Remove GrStencilSettings from GrPipeline
Updates the GrPipeline to have user stencil settings instead of actual settings. This allows us to further defer creating and attaching a stencil buffer. This change is a partial step. The ultimate goal is to attach the stencil buffer and create the stencil settings during render target flush, but for the sake of keeping this CL smaller, we create the stencil settings right before use for now. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2468653002 Review-Url: https://codereview.chromium.org/2468653002
This commit is contained in:
parent
7bb9301b16
commit
c633abbb34
@ -19,6 +19,7 @@
|
||||
#include "GrResourceProvider.h"
|
||||
#include "GrRenderTargetPriv.h"
|
||||
#include "GrStencilAttachment.h"
|
||||
#include "GrStencilSettings.h"
|
||||
#include "GrSurfacePriv.h"
|
||||
#include "GrTexturePriv.h"
|
||||
#include "SkMathPriv.h"
|
||||
@ -442,10 +443,18 @@ void GrGpu::didWriteToSurface(GrSurface* surface, const SkIRect* bounds, uint32_
|
||||
}
|
||||
}
|
||||
|
||||
const GrGpu::MultisampleSpecs& GrGpu::queryMultisampleSpecs(GrRenderTarget* rt,
|
||||
const GrStencilSettings& stencil) {
|
||||
const GrGpu::MultisampleSpecs& GrGpu::queryMultisampleSpecs(const GrPipeline& pipeline) {
|
||||
GrRenderTarget* rt = pipeline.getRenderTarget();
|
||||
SkASSERT(rt->desc().fSampleCnt > 1);
|
||||
|
||||
GrStencilSettings stencil;
|
||||
if (pipeline.isStencilEnabled()) {
|
||||
// TODO: attach stencil and create settings during render target flush.
|
||||
SkASSERT(rt->renderTargetPriv().getStencilAttachment());
|
||||
stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
|
||||
rt->renderTargetPriv().numStencilBits());
|
||||
}
|
||||
|
||||
int effectiveSampleCnt;
|
||||
SkSTArray<16, SkPoint, true> pattern;
|
||||
this->onQueryMultisampleSpecs(rt, stencil, &effectiveSampleCnt, &pattern);
|
||||
|
@ -355,10 +355,10 @@ public:
|
||||
const SkPoint* fSampleLocations;
|
||||
};
|
||||
|
||||
// Finds a render target's multisample specs. The stencil settings are only needed in case we
|
||||
// need to flush the draw state prior to querying multisample info. They are not expected to
|
||||
// Finds a render target's multisample specs. The pipeline is only needed in case we need to
|
||||
// flush the draw state prior to querying multisample info. The pipeline is not expected to
|
||||
// affect the multisample information itself.
|
||||
const MultisampleSpecs& queryMultisampleSpecs(GrRenderTarget*, const GrStencilSettings&);
|
||||
const MultisampleSpecs& queryMultisampleSpecs(const GrPipeline&);
|
||||
|
||||
// Finds the multisample specs with a given unique id.
|
||||
const MultisampleSpecs& getMultisampleSpecs(uint8_t uniqueID) {
|
||||
|
@ -21,19 +21,15 @@
|
||||
GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
||||
GrXPOverridesForBatch* overrides) {
|
||||
const GrPipelineBuilder& builder = *args.fPipelineBuilder;
|
||||
const GrUserStencilSettings* userStencil = builder.getUserStencil();
|
||||
GrRenderTarget* rt = args.fRenderTargetContext->accessRenderTarget();
|
||||
|
||||
GrPipeline* pipeline = new (memory) GrPipeline;
|
||||
GrRenderTarget* rt = args.fRenderTargetContext->accessRenderTarget();
|
||||
pipeline->fRenderTarget.reset(rt);
|
||||
SkASSERT(pipeline->fRenderTarget);
|
||||
pipeline->fScissorState = *args.fScissor;
|
||||
pipeline->fWindowRectsState = *args.fWindowRectsState;
|
||||
if (builder.hasUserStencilSettings() || args.fHasStencilClip) {
|
||||
const GrRenderTargetPriv& rtPriv = rt->renderTargetPriv();
|
||||
pipeline->fStencilSettings.reset(*builder.getUserStencil(), args.fHasStencilClip,
|
||||
rtPriv.numStencilBits());
|
||||
SkASSERT(!pipeline->fStencilSettings.usesWrapOp() || args.fCaps->stencilWrapOpsSupport());
|
||||
}
|
||||
pipeline->fUserStencilSettings = userStencil;
|
||||
pipeline->fDrawFace = builder.getDrawFace();
|
||||
|
||||
pipeline->fFlags = 0;
|
||||
@ -55,10 +51,13 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
||||
if (args.fHasStencilClip) {
|
||||
pipeline->fFlags |= kHasStencilClip_Flag;
|
||||
}
|
||||
if (!userStencil->isDisabled(args.fHasStencilClip)) {
|
||||
pipeline->fFlags |= kStencilEnabled_Flag;
|
||||
}
|
||||
|
||||
// Create XferProcessor from DS's XPFactory
|
||||
bool hasMixedSamples = args.fRenderTargetContext->hasMixedSamples() &&
|
||||
(builder.isHWAntialias() || !pipeline->fStencilSettings.isDisabled());
|
||||
(builder.isHWAntialias() || pipeline->isStencilEnabled());
|
||||
const GrXPFactory* xpFactory = builder.getXPFactory();
|
||||
SkAutoTUnref<GrXferProcessor> xferProcessor;
|
||||
if (xpFactory) {
|
||||
@ -88,7 +87,7 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
||||
const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() :
|
||||
&GrPorterDuffXPFactory::SimpleSrcOverXP();
|
||||
optFlags = xpForOpts->getOptimizations(args.fOpts,
|
||||
pipeline->fStencilSettings.doesWrite(),
|
||||
userStencil->doesWrite(args.fHasStencilClip),
|
||||
&overrideColor,
|
||||
*args.fCaps);
|
||||
|
||||
@ -226,7 +225,7 @@ bool GrPipeline::AreEqual(const GrPipeline& a, const GrPipeline& b) {
|
||||
a.fScissorState != b.fScissorState ||
|
||||
!a.fWindowRectsState.cheapEqualTo(b.fWindowRectsState) ||
|
||||
a.fFlags != b.fFlags ||
|
||||
a.fStencilSettings != b.fStencilSettings ||
|
||||
a.fUserStencilSettings != b.fUserStencilSettings ||
|
||||
a.fDrawFace != b.fDrawFace ||
|
||||
a.fIgnoresCoverage != b.fIgnoresCoverage) {
|
||||
return false;
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "GrProcOptInfo.h"
|
||||
#include "GrProgramDesc.h"
|
||||
#include "GrScissorState.h"
|
||||
#include "GrStencilSettings.h"
|
||||
#include "GrUserStencilSettings.h"
|
||||
#include "GrWindowRectsState.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkRefCnt.h"
|
||||
@ -148,7 +148,7 @@ public:
|
||||
*/
|
||||
GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
|
||||
|
||||
const GrStencilSettings& getStencil() const { return fStencilSettings; }
|
||||
const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
|
||||
|
||||
const GrScissorState& getScissorState() const { return fScissorState; }
|
||||
|
||||
@ -168,6 +168,9 @@ public:
|
||||
bool hasStencilClip() const {
|
||||
return SkToBool(fFlags & kHasStencilClip_Flag);
|
||||
}
|
||||
bool isStencilEnabled() const {
|
||||
return SkToBool(fFlags & kStencilEnabled_Flag);
|
||||
}
|
||||
|
||||
GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
|
||||
return this->getXferProcessor().xferBarrierType(fRenderTarget.get(), caps);
|
||||
@ -213,6 +216,7 @@ private:
|
||||
kAllowSRGBInputs_Flag = 0x8,
|
||||
kUsesDistanceVectorField_Flag = 0x10,
|
||||
kHasStencilClip_Flag = 0x20,
|
||||
kStencilEnabled_Flag = 0x40,
|
||||
};
|
||||
|
||||
typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
|
||||
@ -222,7 +226,7 @@ private:
|
||||
RenderTarget fRenderTarget;
|
||||
GrScissorState fScissorState;
|
||||
GrWindowRectsState fWindowRectsState;
|
||||
GrStencilSettings fStencilSettings;
|
||||
const GrUserStencilSettings* fUserStencilSettings;
|
||||
GrDrawFace fDrawFace;
|
||||
uint32_t fFlags;
|
||||
ProgramXferProcessor fXferProcessor;
|
||||
|
@ -165,7 +165,7 @@ bool GrProgramDesc::Build(GrProgramDesc* desc,
|
||||
if (requiredFeatures & GrProcessor::kSampleLocations_RequiredFeature) {
|
||||
SkASSERT(pipeline.isHWAntialiasState());
|
||||
header->fSamplePatternKey =
|
||||
rt->renderTargetPriv().getMultisampleSpecs(pipeline.getStencil()).fUniqueID;
|
||||
rt->renderTargetPriv().getMultisampleSpecs(pipeline).fUniqueID;
|
||||
} else {
|
||||
header->fSamplePatternKey = 0;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "GrDrawingManager.h"
|
||||
#include "GrFixedClip.h"
|
||||
#include "GrPathRenderer.h"
|
||||
#include "GrStencilSettings.h"
|
||||
#include "GrStyle.h"
|
||||
#include "GrUserStencilSettings.h"
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "GrRenderTargetOpList.h"
|
||||
#include "GrRenderTargetPriv.h"
|
||||
#include "GrStencilAttachment.h"
|
||||
#include "GrStencilSettings.h"
|
||||
|
||||
GrRenderTarget::GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc, Flags flags,
|
||||
GrStencilAttachment* stencil)
|
||||
@ -100,17 +101,19 @@ bool GrRenderTargetPriv::attachStencilAttachment(GrStencilAttachment* stencil) {
|
||||
}
|
||||
|
||||
int GrRenderTargetPriv::numStencilBits() const {
|
||||
return fRenderTarget->fStencilAttachment ? fRenderTarget->fStencilAttachment->bits() : 0;
|
||||
SkASSERT(this->getStencilAttachment());
|
||||
return this->getStencilAttachment()->bits();
|
||||
}
|
||||
|
||||
const GrGpu::MultisampleSpecs&
|
||||
GrRenderTargetPriv::getMultisampleSpecs(const GrStencilSettings& stencil) const {
|
||||
GrRenderTargetPriv::getMultisampleSpecs(const GrPipeline& pipeline) const {
|
||||
SkASSERT(fRenderTarget == pipeline.getRenderTarget()); // TODO: remove RT from pipeline.
|
||||
GrGpu* gpu = fRenderTarget->getGpu();
|
||||
if (auto id = fRenderTarget->fMultisampleSpecsID) {
|
||||
SkASSERT(gpu->queryMultisampleSpecs(fRenderTarget, stencil).fUniqueID == id);
|
||||
SkASSERT(gpu->queryMultisampleSpecs(pipeline).fUniqueID == id);
|
||||
return gpu->getMultisampleSpecs(id);
|
||||
}
|
||||
const GrGpu::MultisampleSpecs& specs = gpu->queryMultisampleSpecs(fRenderTarget, stencil);
|
||||
const GrGpu::MultisampleSpecs& specs = gpu->queryMultisampleSpecs(pipeline);
|
||||
fRenderTarget->fMultisampleSpecsID = specs.fUniqueID;
|
||||
return specs;
|
||||
}
|
||||
|
@ -32,10 +32,10 @@ public:
|
||||
|
||||
int numStencilBits() const;
|
||||
|
||||
// Finds a render target's multisample specs. The stencil settings are only needed in case the
|
||||
// info isn't cached and we need to flush the draw state in order to query it. They are not
|
||||
// expected to affect the multisample information itself.
|
||||
const GrGpu::MultisampleSpecs& getMultisampleSpecs(const GrStencilSettings& stencil) const;
|
||||
// Finds a render target's multisample specs. The pipeline is only needed in case the info isn't
|
||||
// cached and we need to flush the draw state in order to query it. The pipeline is not expected
|
||||
// to affect the multisample information itself.
|
||||
const GrGpu::MultisampleSpecs& getMultisampleSpecs(const GrPipeline&) const;
|
||||
|
||||
typedef GrRenderTarget::Flags Flags;
|
||||
|
||||
|
@ -28,6 +28,7 @@ void GrStencilSettings::reset(const GrUserStencilSettings& user, bool hasStencil
|
||||
int numStencilBits) {
|
||||
uint16_t frontFlags = user.fFrontFlags[hasStencilClip];
|
||||
if (frontFlags & kSingleSided_StencilFlag) {
|
||||
SkASSERT(frontFlags == user.fBackFlags[hasStencilClip]);
|
||||
fFlags = frontFlags;
|
||||
if (!this->isDisabled()) {
|
||||
fFront.reset(user.fFront, hasStencilClip, numStencilBits);
|
||||
|
@ -182,6 +182,22 @@ struct GrUserStencilSettings {
|
||||
GrUserStencilSettings() = delete;
|
||||
GrUserStencilSettings(const GrUserStencilSettings&) = delete;
|
||||
|
||||
uint16_t flags(bool hasStencilClip) const {
|
||||
return fFrontFlags[hasStencilClip] & fBackFlags[hasStencilClip];
|
||||
}
|
||||
bool isDisabled(bool hasStencilClip) const {
|
||||
return this->flags(hasStencilClip) & kDisabled_StencilFlag;
|
||||
}
|
||||
bool doesWrite(bool hasStencilClip) const {
|
||||
return !(this->flags(hasStencilClip) & kNoModifyStencil_StencilFlag);
|
||||
}
|
||||
bool isTwoSided(bool hasStencilClip) const {
|
||||
return !(this->flags(hasStencilClip) & kSingleSided_StencilFlag);
|
||||
}
|
||||
bool usesWrapOp(bool hasStencilClip) const {
|
||||
return !(this->flags(hasStencilClip) & kNoWrapOps_StencilFlag);
|
||||
}
|
||||
|
||||
const uint16_t fFrontFlags[2]; // frontFlagsForDraw = fFrontFlags[hasStencilClip].
|
||||
const Face fFront;
|
||||
const uint16_t fBackFlags[2]; // backFlagsForDraw = fBackFlags[hasStencilClip].
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "GrPath.h"
|
||||
#include "GrPathRendering.h"
|
||||
#include "GrPathProcessor.h"
|
||||
#include "GrStencilSettings.h"
|
||||
|
||||
#include "SkTLList.h"
|
||||
|
||||
|
@ -2052,10 +2052,17 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso
|
||||
program->setData(primProc, pipeline);
|
||||
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
|
||||
this->flushStencil(pipeline.getStencil());
|
||||
GrStencilSettings stencil;
|
||||
if (pipeline.isStencilEnabled()) {
|
||||
// TODO: attach stencil and create settings during render target flush.
|
||||
SkASSERT(glRT->renderTargetPriv().getStencilAttachment());
|
||||
stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
|
||||
glRT->renderTargetPriv().numStencilBits());
|
||||
}
|
||||
this->flushStencil(stencil);
|
||||
this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->origin());
|
||||
this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT);
|
||||
this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !pipeline.getStencil().isDisabled());
|
||||
this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), stencil.isDisabled());
|
||||
|
||||
// This must come after textures are flushed because a texture may need
|
||||
// to be msaa-resolved (which will modify bound FBO state).
|
||||
|
@ -10,12 +10,12 @@
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "GrPathRendering.h"
|
||||
#include "GrStencilSettings.h"
|
||||
#include "gl/GrGLTypes.h"
|
||||
#include "glsl/GrGLSLUtil.h"
|
||||
|
||||
class GrGLNameAllocator;
|
||||
class GrGLGpu;
|
||||
class GrStencilSettings;
|
||||
class GrStyle;
|
||||
|
||||
/**
|
||||
|
@ -357,7 +357,7 @@ void GrGLSLFragmentShaderBuilder::defineSampleOffsetArray(const char* name, cons
|
||||
SkASSERT(fProgramBuilder->caps()->sampleLocationsSupport());
|
||||
const GrPipeline& pipeline = fProgramBuilder->pipeline();
|
||||
const GrRenderTargetPriv& rtp = pipeline.getRenderTarget()->renderTargetPriv();
|
||||
const GrGpu::MultisampleSpecs& specs = rtp.getMultisampleSpecs(pipeline.getStencil());
|
||||
const GrGpu::MultisampleSpecs& specs = rtp.getMultisampleSpecs(pipeline);
|
||||
SkSTArray<16, SkPoint, true> offsets;
|
||||
offsets.push_back_n(specs.fEffectiveSampleCnt);
|
||||
m.mapPoints(offsets.begin(), specs.fSampleLocations, specs.fEffectiveSampleCnt);
|
||||
|
@ -1701,7 +1701,7 @@ GLSLInstanceProcessor::Backend::Create(const GrPipeline& pipeline, BatchInfo bat
|
||||
case AntialiasMode::kMSAA:
|
||||
case AntialiasMode::kMixedSamples: {
|
||||
const GrRenderTargetPriv& rtp = pipeline.getRenderTarget()->renderTargetPriv();
|
||||
const GrGpu::MultisampleSpecs& specs = rtp.getMultisampleSpecs(pipeline.getStencil());
|
||||
const GrGpu::MultisampleSpecs& specs = rtp.getMultisampleSpecs(pipeline);
|
||||
return new BackendMultisample(batchInfo, inputs, specs.fEffectiveSampleCnt);
|
||||
}
|
||||
}
|
||||
|
@ -397,6 +397,7 @@ static void setup_dynamic_state(VkPipelineDynamicStateCreateInfo* dynamicInfo,
|
||||
}
|
||||
|
||||
GrVkPipeline* GrVkPipeline::Create(GrVkGpu* gpu, const GrPipeline& pipeline,
|
||||
const GrStencilSettings& stencil,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
VkPipelineShaderStageCreateInfo* shaderStageInfo,
|
||||
int shaderStageCount,
|
||||
@ -415,7 +416,7 @@ GrVkPipeline* GrVkPipeline::Create(GrVkGpu* gpu, const GrPipeline& pipeline,
|
||||
setup_input_assembly_state(primitiveType, &inputAssemblyInfo);
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilInfo;
|
||||
setup_depth_stencil_state(pipeline.getStencil(), &depthStencilInfo);
|
||||
setup_depth_stencil_state(stencil, &depthStencilInfo);
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportInfo;
|
||||
setup_viewport_scissor_state(&viewportInfo);
|
||||
|
@ -17,6 +17,7 @@
|
||||
class GrNonInstancedVertices;
|
||||
class GrPipeline;
|
||||
class GrPrimitiveProcessor;
|
||||
class GrStencilSettings;
|
||||
class GrVkCommandBuffer;
|
||||
class GrVkGpu;
|
||||
class GrVkRenderPass;
|
||||
@ -25,6 +26,7 @@ class GrVkPipeline : public GrVkResource {
|
||||
public:
|
||||
static GrVkPipeline* Create(GrVkGpu* gpu,
|
||||
const GrPipeline& pipeline,
|
||||
const GrStencilSettings&,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
VkPipelineShaderStageCreateInfo* shaderStageInfo,
|
||||
int shaderStageCount,
|
||||
|
@ -492,6 +492,7 @@ uint32_t get_blend_info_key(const GrPipeline& pipeline) {
|
||||
bool GrVkPipelineState::Desc::Build(Desc* desc,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrStencilSettings& stencil,
|
||||
GrPrimitiveType primitiveType,
|
||||
const GrGLSLCaps& caps) {
|
||||
if (!INHERITED::Build(desc, primProc, primitiveType == kPoints_GrPrimitiveType, pipeline,
|
||||
@ -503,7 +504,7 @@ bool GrVkPipelineState::Desc::Build(Desc* desc,
|
||||
GrVkRenderTarget* vkRT = (GrVkRenderTarget*)pipeline.getRenderTarget();
|
||||
vkRT->simpleRenderPass()->genKey(&b);
|
||||
|
||||
pipeline.getStencil().genKey(&b);
|
||||
stencil.genKey(&b);
|
||||
|
||||
SkASSERT(sizeof(GrDrawFace) <= sizeof(uint32_t));
|
||||
b.add32((int32_t)pipeline.getDrawFace());
|
||||
|
@ -74,6 +74,7 @@ public:
|
||||
static bool Build(Desc*,
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrPipeline&,
|
||||
const GrStencilSettings&,
|
||||
GrPrimitiveType primitiveType,
|
||||
const GrGLSLCaps&);
|
||||
private:
|
||||
|
@ -14,6 +14,7 @@
|
||||
GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
|
||||
GrVkGpu* gpu,
|
||||
const GrPipeline& pipeline,
|
||||
const GrStencilSettings& stencil,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
GrPrimitiveType primitiveType,
|
||||
const GrVkPipelineState::Desc& desc,
|
||||
@ -30,7 +31,7 @@ GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return builder.finalize(primitiveType, renderPass, desc);
|
||||
return builder.finalize(stencil, primitiveType, renderPass, desc);
|
||||
}
|
||||
|
||||
GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
|
||||
@ -73,7 +74,8 @@ bool GrVkPipelineStateBuilder::CreateVkShaderModule(const GrVkGpu* gpu,
|
||||
return GrCompileVkShaderModule(gpu, shaderString.c_str(), stage, shaderModule, stageInfo);
|
||||
}
|
||||
|
||||
GrVkPipelineState* GrVkPipelineStateBuilder::finalize(GrPrimitiveType primitiveType,
|
||||
GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& stencil,
|
||||
GrPrimitiveType primitiveType,
|
||||
const GrVkRenderPass& renderPass,
|
||||
const GrVkPipelineState::Desc& desc) {
|
||||
VkDescriptorSetLayout dsLayout[2];
|
||||
@ -129,6 +131,7 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(GrPrimitiveType primitiveT
|
||||
&shaderStageInfo[1]));
|
||||
|
||||
GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
|
||||
stencil,
|
||||
fPrimProc,
|
||||
shaderStageInfo,
|
||||
2,
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
*/
|
||||
static GrVkPipelineState* CreatePipelineState(GrVkGpu*,
|
||||
const GrPipeline&,
|
||||
const GrStencilSettings&,
|
||||
const GrPrimitiveProcessor&,
|
||||
GrPrimitiveType,
|
||||
const GrVkPipelineState::Desc&,
|
||||
@ -50,7 +51,8 @@ private:
|
||||
const GrPrimitiveProcessor&,
|
||||
const GrProgramDesc&);
|
||||
|
||||
GrVkPipelineState* finalize(GrPrimitiveType primitiveType,
|
||||
GrVkPipelineState* finalize(const GrStencilSettings&,
|
||||
GrPrimitiveType primitiveType,
|
||||
const GrVkRenderPass& renderPass,
|
||||
const GrVkPipelineState::Desc&);
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "GrVkGpu.h"
|
||||
#include "GrProcessor.h"
|
||||
#include "GrRenderTargetPriv.h" // TODO: remove once refPipelineState gets passed stencil settings.
|
||||
#include "GrVkPipelineState.h"
|
||||
#include "GrVkPipelineStateBuilder.h"
|
||||
#include "SkOpts.h"
|
||||
@ -97,10 +98,19 @@ sk_sp<GrVkPipelineState> GrVkResourceProvider::PipelineStateCache::refPipelineSt
|
||||
#ifdef GR_PIPELINE_STATE_CACHE_STATS
|
||||
++fTotalRequests;
|
||||
#endif
|
||||
GrStencilSettings stencil;
|
||||
if (pipeline.isStencilEnabled()) {
|
||||
GrRenderTarget* rt = pipeline.getRenderTarget();
|
||||
// TODO: attach stencil and create settings during render target flush.
|
||||
SkASSERT(rt->renderTargetPriv().getStencilAttachment());
|
||||
stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
|
||||
rt->renderTargetPriv().numStencilBits());
|
||||
}
|
||||
|
||||
// Get GrVkProgramDesc
|
||||
GrVkPipelineState::Desc desc;
|
||||
if (!GrVkPipelineState::Desc::Build(&desc, primProc, pipeline, primitiveType,
|
||||
*fGpu->vkCaps().glslCaps())) {
|
||||
if (!GrVkPipelineState::Desc::Build(&desc, primProc, pipeline, stencil,
|
||||
primitiveType, *fGpu->vkCaps().glslCaps())) {
|
||||
GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n");
|
||||
return nullptr;
|
||||
}
|
||||
@ -118,6 +128,7 @@ sk_sp<GrVkPipelineState> GrVkResourceProvider::PipelineStateCache::refPipelineSt
|
||||
sk_sp<GrVkPipelineState> pipelineState(
|
||||
GrVkPipelineStateBuilder::CreatePipelineState(fGpu,
|
||||
pipeline,
|
||||
stencil,
|
||||
primProc,
|
||||
primitiveType,
|
||||
desc,
|
||||
|
@ -57,6 +57,7 @@ void GrVkResourceProvider::init() {
|
||||
}
|
||||
|
||||
GrVkPipeline* GrVkResourceProvider::createPipeline(const GrPipeline& pipeline,
|
||||
const GrStencilSettings& stencil,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
VkPipelineShaderStageCreateInfo* shaderStageInfo,
|
||||
int shaderStageCount,
|
||||
@ -64,8 +65,9 @@ GrVkPipeline* GrVkResourceProvider::createPipeline(const GrPipeline& pipeline,
|
||||
const GrVkRenderPass& renderPass,
|
||||
VkPipelineLayout layout) {
|
||||
|
||||
return GrVkPipeline::Create(fGpu, pipeline, primProc, shaderStageInfo, shaderStageCount,
|
||||
primitiveType, renderPass, layout, fPipelineCache);
|
||||
return GrVkPipeline::Create(fGpu, pipeline, stencil, primProc, shaderStageInfo,
|
||||
shaderStageCount, primitiveType, renderPass, layout,
|
||||
fPipelineCache);
|
||||
}
|
||||
|
||||
GrVkCopyPipeline* GrVkResourceProvider::findOrCreateCopyPipeline(
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
void init();
|
||||
|
||||
GrVkPipeline* createPipeline(const GrPipeline& pipeline,
|
||||
const GrStencilSettings& stencil,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
VkPipelineShaderStageCreateInfo* shaderStageInfo,
|
||||
int shaderStageCount,
|
||||
|
@ -12,7 +12,9 @@
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
|
||||
#include "GrRenderTargetContext.h"
|
||||
#include "GrRenderTargetPriv.h"
|
||||
#include "GrPipelineBuilder.h"
|
||||
#include "gl/GrGLGpu.h"
|
||||
#include "gl/debug/DebugGLTestContext.h"
|
||||
|
||||
@ -87,23 +89,31 @@ public:
|
||||
virtual ~TestSampleLocationsInterface() {}
|
||||
};
|
||||
|
||||
GrRenderTarget* SK_WARN_UNUSED_RESULT create_render_target(GrContext* ctx, GrSurfaceOrigin origin,
|
||||
int numSamples) {
|
||||
GrSurfaceDesc desc;
|
||||
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||
desc.fOrigin = origin;
|
||||
desc.fWidth = 100;
|
||||
desc.fHeight = 100;
|
||||
desc.fConfig = kBGRA_8888_GrPixelConfig;
|
||||
desc.fSampleCnt = numSamples;
|
||||
return ctx->textureProvider()->createTexture(desc, SkBudgeted::kNo, 0, 0)->asRenderTarget();
|
||||
static GrPipeline* construct_dummy_pipeline(GrRenderTargetContext* dc, void* storage) {
|
||||
GrPipelineBuilder dummyBuilder;
|
||||
GrScissorState dummyScissor;
|
||||
GrWindowRectsState dummyWindows;
|
||||
GrXPOverridesForBatch dummyOverrides;
|
||||
|
||||
GrPipeline::CreateArgs args;
|
||||
args.fPipelineBuilder = &dummyBuilder;
|
||||
args.fRenderTargetContext = dc;
|
||||
args.fCaps = dc->caps();
|
||||
args.fOpts = GrPipelineOptimizations();
|
||||
args.fScissor = &dummyScissor;
|
||||
args.fWindowRectsState = &dummyWindows;
|
||||
args.fHasStencilClip = false;
|
||||
args.fDstTexture = GrXferProcessor::DstTexture();
|
||||
|
||||
GrPipeline::CreateAt(storage, args, &dummyOverrides);
|
||||
return reinterpret_cast<GrPipeline*>(storage);
|
||||
}
|
||||
|
||||
void assert_equal(skiatest::Reporter* reporter, const SamplePattern& pattern,
|
||||
const GrGpu::MultisampleSpecs& specs, bool flipY) {
|
||||
GrAlwaysAssert(specs.fSampleLocations);
|
||||
if ((int)pattern.size() != specs.fEffectiveSampleCnt) {
|
||||
REPORTER_ASSERT_MESSAGE(reporter, false, "Sample pattern has wrong number of samples.");
|
||||
REPORT_FAILURE(reporter, "", SkString("Sample pattern has wrong number of samples."));
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < specs.fEffectiveSampleCnt; ++i) {
|
||||
@ -112,7 +122,7 @@ void assert_equal(skiatest::Reporter* reporter, const SamplePattern& pattern,
|
||||
expectedLocation.fY = 1 - expectedLocation.fY;
|
||||
}
|
||||
if (pattern[i] != expectedLocation) {
|
||||
REPORTER_ASSERT_MESSAGE(reporter, false, "Sample pattern has wrong sample location.");
|
||||
REPORT_FAILURE(reporter, "", SkString("Sample pattern has wrong sample location."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -121,28 +131,37 @@ void assert_equal(skiatest::Reporter* reporter, const SamplePattern& pattern,
|
||||
void test_sampleLocations(skiatest::Reporter* reporter, TestSampleLocationsInterface* testInterface,
|
||||
GrContext* ctx) {
|
||||
SkRandom rand;
|
||||
SkAutoTUnref<GrRenderTarget> bottomUps[numTestPatterns];
|
||||
SkAutoTUnref<GrRenderTarget> topDowns[numTestPatterns];
|
||||
sk_sp<GrRenderTargetContext> bottomUps[numTestPatterns];
|
||||
sk_sp<GrRenderTargetContext> topDowns[numTestPatterns];
|
||||
for (int i = 0; i < numTestPatterns; ++i) {
|
||||
int numSamples = (int)kTestPatterns[i].size();
|
||||
GrAlwaysAssert(numSamples > 1 && SkIsPow2(numSamples));
|
||||
bottomUps[i].reset(create_render_target(ctx, kBottomLeft_GrSurfaceOrigin,
|
||||
rand.nextRangeU(1 + numSamples / 2, numSamples)));
|
||||
topDowns[i].reset(create_render_target(ctx, kTopLeft_GrSurfaceOrigin,
|
||||
rand.nextRangeU(1 + numSamples / 2, numSamples)));
|
||||
bottomUps[i] = ctx->makeRenderTargetContextWithFallback(
|
||||
SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr,
|
||||
rand.nextRangeU(1 + numSamples / 2, numSamples),
|
||||
kBottomLeft_GrSurfaceOrigin);
|
||||
topDowns[i] = ctx->makeRenderTargetContextWithFallback(
|
||||
SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr,
|
||||
rand.nextRangeU(1 + numSamples / 2, numSamples),
|
||||
kTopLeft_GrSurfaceOrigin);
|
||||
}
|
||||
|
||||
// Ensure all sample locations get queried and/or cached properly.
|
||||
GrStencilSettings dummyStencil;
|
||||
SkAlignedSTStorage<1, GrPipeline> pipelineStorage;
|
||||
for (int repeat = 0; repeat < 2; ++repeat) {
|
||||
for (int i = 0; i < numTestPatterns; ++i) {
|
||||
testInterface->overrideSamplePattern(kTestPatterns[i]);
|
||||
assert_equal(reporter, kTestPatterns[i],
|
||||
topDowns[i]->renderTargetPriv().getMultisampleSpecs(dummyStencil), false);
|
||||
assert_equal(reporter, kTestPatterns[i],
|
||||
bottomUps[i]->renderTargetPriv().getMultisampleSpecs(dummyStencil), true);
|
||||
for (GrRenderTargetContext* dc : {bottomUps[i].get(), topDowns[i].get()}) {
|
||||
GrPipeline* dummyPipe = construct_dummy_pipeline(dc, pipelineStorage.get());
|
||||
GrRenderTarget* rt = dc->accessRenderTarget();
|
||||
assert_equal(reporter, kTestPatterns[i],
|
||||
rt->renderTargetPriv().getMultisampleSpecs(*dummyPipe),
|
||||
kBottomLeft_GrSurfaceOrigin == rt->origin());
|
||||
dummyPipe->~GrPipeline();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user