diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h index f99405e27f..a41caf6ff7 100644 --- a/include/gpu/GrCaps.h +++ b/include/gpu/GrCaps.h @@ -43,7 +43,6 @@ public: * Is there support for enabling/disabling sRGB writes for sRGB-capable color buffers? */ bool srgbWriteControl() const { return fSRGBWriteControl; } - bool twoSidedStencilSupport() const { return fTwoSidedStencilSupport; } bool stencilWrapOpsSupport() const { return fStencilWrapOpsSupport; } bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; } bool gpuTracingSupport() const { return fGpuTracingSupport; } @@ -208,7 +207,6 @@ protected: bool fMipMapSupport : 1; bool fSRGBSupport : 1; bool fSRGBWriteControl : 1; - bool fTwoSidedStencilSupport : 1; bool fStencilWrapOpsSupport : 1; bool fDiscardRenderTargetSupport : 1; bool fReuseScratchTextures : 1; diff --git a/include/gpu/GrTypesPriv.h b/include/gpu/GrTypesPriv.h index cbff7d8a3b..8f828e67d6 100644 --- a/include/gpu/GrTypesPriv.h +++ b/include/gpu/GrTypesPriv.h @@ -98,14 +98,6 @@ enum GrShaderFlags { }; GR_MAKE_BITFIELD_OPS(GrShaderFlags); -enum class GrDrawFace { - kInvalid = -1, - - kBoth, - kCCW, - kCW, -}; - /** * Precisions of shader language variables. Not all shading languages support precisions or actually * vary the internal precision based on the qualifiers. These currently only apply to float types ( diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp index e9a1893169..78bb6795e9 100644 --- a/src/gpu/GrCaps.cpp +++ b/src/gpu/GrCaps.cpp @@ -36,7 +36,6 @@ GrCaps::GrCaps(const GrContextOptions& options) { fNPOTTextureTileSupport = false; fSRGBSupport = false; fSRGBWriteControl = false; - fTwoSidedStencilSupport = false; fStencilWrapOpsSupport = false; fDiscardRenderTargetSupport = false; fReuseScratchTextures = true; @@ -126,7 +125,6 @@ SkString GrCaps::dump() const { r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]); r.appendf("sRGB Support : %s\n", gNY[fSRGBSupport]); r.appendf("sRGB Write Control : %s\n", gNY[fSRGBWriteControl]); - r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]); r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]); r.appendf("Discard Render Target Support : %s\n", gNY[fDiscardRenderTargetSupport]); r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]); diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp index 55c4a305dc..8d06a5e7cf 100644 --- a/src/gpu/GrPathRendererChain.cpp +++ b/src/gpu/GrPathRendererChain.cpp @@ -60,8 +60,7 @@ GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& opti fChain.push_back(sk_make_sp()); } if (options.fGpuPathRenderers & GpuPathRenderers::kDefault) { - fChain.push_back(sk_make_sp(caps.twoSidedStencilSupport(), - caps.stencilWrapOpsSupport())); + fChain.push_back(sk_make_sp(caps.stencilWrapOpsSupport())); } } diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp index 78fb759154..489a4a91e3 100644 --- a/src/gpu/GrPipeline.cpp +++ b/src/gpu/GrPipeline.cpp @@ -42,8 +42,6 @@ void GrPipeline::init(const InitArgs& args) { fUserStencilSettings = args.fUserStencil; - fDrawFace = static_cast(args.fDrawFace); - fXferProcessor = args.fProcessors->refXferProcessor(); if (args.fDstTexture.texture()) { @@ -118,7 +116,6 @@ GrPipeline::GrPipeline(GrRenderTarget* rt, SkBlendMode blendmode) , fScissorState() , fWindowRectsState() , fUserStencilSettings(&GrUserStencilSettings::kUnused) - , fDrawFace(static_cast(GrDrawFace::kBoth)) , fFlags() , fXferProcessor(GrPorterDuffXPFactory::MakeNoCoverageXP(blendmode)) , fFragmentProcessors() diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h index e0c85d3f4d..3483d2bed4 100644 --- a/src/gpu/GrPipeline.h +++ b/src/gpu/GrPipeline.h @@ -70,7 +70,6 @@ public: struct InitArgs { uint32_t fFlags = 0; - GrDrawFace fDrawFace = GrDrawFace::kBoth; const GrProcessorSet* fProcessors = nullptr; // Must be finalized const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused; const GrAppliedClip* fAppliedClip = nullptr; @@ -222,13 +221,6 @@ public: return this->getXferProcessor().xferBarrierType(caps); } - /** - * Gets whether the target is drawing clockwise, counterclockwise, - * or both faces. - * @return the current draw face(s). - */ - GrDrawFace getDrawFace() const { return static_cast(fDrawFace); } - private: void markAsBad() { fFlags |= kIsBad_Flag; } diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index ef84f5b40c..9bb2c49c17 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -30,7 +30,6 @@ public: */ GrPipelineBuilder(GrPaint&& paint, GrAAType aaType) : fFlags(GrPipeline::SRGBFlagsFromPaint(paint)) - , fDrawFace(GrDrawFace::kBoth) , fUserStencilSettings(&GrUserStencilSettings::kUnused) , fProcessors(std::move(paint)) { if (GrAATypeIsHW(aaType)) { @@ -107,31 +106,14 @@ public: /// @} - /////////////////////////////////////////////////////////////////////////// - /// @name Face Culling - //// - - /** - * Controls whether clockwise, counterclockwise, or both faces are drawn. - * @param face the face(s) to draw. - */ - void setDrawFace(GrDrawFace face) { - SkASSERT(GrDrawFace::kInvalid != face); - fDrawFace = face; - } - - /// @} - void getPipelineInitArgs(GrPipeline::InitArgs* args) const { args->fFlags = fFlags; args->fUserStencil = fUserStencilSettings; - args->fDrawFace = fDrawFace; args->fProcessors = &fProcessors; } private: uint32_t fFlags; - GrDrawFace fDrawFace; const GrUserStencilSettings* fUserStencilSettings; GrProcessorSet fProcessors; }; diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index bc894c30d1..ad0b6bc9b3 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -379,16 +379,11 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, this->initStencilFormats(ctxInfo); if (kGL_GrGLStandard == standard) { - // we could also look for GL_ATI_separate_stencil extension or - // GL_EXT_stencil_two_side but they use different function signatures - // than GL2.0+ (and than each other). - fTwoSidedStencilSupport = (ctxInfo.version() >= GR_GL_VER(2,0)); // supported on GL 1.4 and higher or by extension fStencilWrapOpsSupport = (ctxInfo.version() >= GR_GL_VER(1,4)) || ctxInfo.hasExtension("GL_EXT_stencil_wrap"); } else { - // ES 2 has two sided stencil and stencil wrap - fTwoSidedStencilSupport = true; + // ES 2 has stencil wrap fStencilWrapOpsSupport = true; } diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 3f200bba6f..99db511911 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -372,17 +372,22 @@ void GrGLGpu::disconnect(DisconnectType type) { /////////////////////////////////////////////////////////////////////////////// void GrGLGpu::onResetContext(uint32_t resetBits) { - // we don't use the zb at all if (resetBits & kMisc_GrGLBackendState) { + // we don't use the zb at all GL_CALL(Disable(GR_GL_DEPTH_TEST)); GL_CALL(DepthMask(GR_GL_FALSE)); + // We don't use face culling. + GL_CALL(Disable(GR_GL_CULL_FACE)); + // We do use separate stencil. Our algorithms don't care which face is front vs. back so + // just set this to the default for self-consistency. + GL_CALL(FrontFace(GR_GL_CCW)); + fHWBufferState[kTexel_GrBufferType].invalidate(); fHWBufferState[kDrawIndirect_GrBufferType].invalidate(); fHWBufferState[kXferCpuToGpu_GrBufferType].invalidate(); fHWBufferState[kXferGpuToCpu_GrBufferType].invalidate(); - fHWDrawFace = GrDrawFace::kInvalid; if (kGL_GrGLStandard == this->glStandard()) { #ifndef USE_NSIGHT // Desktop-only state that we never change @@ -1948,7 +1953,6 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso pipeline.getXferProcessor().getBlendInfo(&blendInfo); this->flushColorWrite(blendInfo.fWriteColor); - this->flushDrawFace(pipeline.getDrawFace()); this->flushMinSampleShading(primProc.getSampleShading()); GrGLuint programID = program->programID(); @@ -2819,7 +2823,6 @@ void GrGLGpu::flushStencil(const GrStencilSettings& stencilSettings) { fHWStencilTestEnabled = kYes_TriState; } if (stencilSettings.isTwoSided()) { - SkASSERT(this->caps()->twoSidedStencilSupport()); set_gl_stencil(this->glInterface(), stencilSettings.front(), GR_GL_FRONT); @@ -3282,27 +3285,6 @@ void GrGLGpu::flushColorWrite(bool writeColor) { } } -void GrGLGpu::flushDrawFace(GrDrawFace face) { - if (fHWDrawFace != face) { - switch (face) { - case GrDrawFace::kCCW: - GL_CALL(Enable(GR_GL_CULL_FACE)); - GL_CALL(CullFace(GR_GL_BACK)); - break; - case GrDrawFace::kCW: - GL_CALL(Enable(GR_GL_CULL_FACE)); - GL_CALL(CullFace(GR_GL_FRONT)); - break; - case GrDrawFace::kBoth: - GL_CALL(Disable(GR_GL_CULL_FACE)); - break; - default: - SkFAIL("Unknown draw face."); - } - fHWDrawFace = face; - } -} - void GrGLGpu::setTextureUnit(int unit) { SkASSERT(unit >= 0 && unit < fHWBoundTextureUniqueIDs.count()); if (unit != fHWActiveTextureUnitIdx) { @@ -3951,7 +3933,6 @@ void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor blendInfo.reset(); this->flushBlend(blendInfo, GrSwizzle::RGBA()); this->flushColorWrite(true); - this->flushDrawFace(GrDrawFace::kBoth); this->flushHWAAState(glRT, false, false); this->disableScissor(); this->disableWindowRectangles(); @@ -4035,7 +4016,6 @@ bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, blendInfo.reset(); this->flushBlend(blendInfo, GrSwizzle::RGBA()); this->flushColorWrite(true); - this->flushDrawFace(GrDrawFace::kBoth); this->flushHWAAState(nullptr, false, false); this->disableScissor(); this->disableWindowRectangles(); @@ -4244,7 +4224,6 @@ bool GrGLGpu::generateMipmap(GrGLTexture* texture, bool gammaCorrect) { blendInfo.reset(); this->flushBlend(blendInfo, GrSwizzle::RGBA()); this->flushColorWrite(true); - this->flushDrawFace(GrDrawFace::kBoth); this->flushHWAAState(nullptr, false, false); this->disableScissor(); this->disableWindowRectangles(); diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index f192c2b5ba..04929f89fa 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -314,7 +314,6 @@ private: }; void flushColorWrite(bool writeColor); - void flushDrawFace(GrDrawFace face); // flushes the scissor. see the note on flushBoundTextureAndParams about // flushing the scissor after that function is called. @@ -566,7 +565,6 @@ private: TriState fHWStencilTestEnabled; - GrDrawFace fHWDrawFace; TriState fHWWriteToColor; GrGpuResource::UniqueID fHWBoundRenderTargetUniqueID; TriState fHWSRGBFramebuffer; diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp index c196b4bb97..5bb4b5f6f8 100644 --- a/src/gpu/gl/GrGLInterface.cpp +++ b/src/gpu/gl/GrGLInterface.cpp @@ -117,8 +117,11 @@ bool GrGLInterface::validate() const { nullptr == fFunctions.fScissor || nullptr == fFunctions.fShaderSource || nullptr == fFunctions.fStencilFunc || + nullptr == fFunctions.fStencilFuncSeparate || nullptr == fFunctions.fStencilMask || + nullptr == fFunctions.fStencilMaskSeparate || nullptr == fFunctions.fStencilOp || + nullptr == fFunctions.fStencilOpSeparate || nullptr == fFunctions.fTexImage2D || nullptr == fFunctions.fTexParameteri || nullptr == fFunctions.fTexParameteriv || @@ -178,19 +181,9 @@ bool GrGLInterface::validate() const { // these functions are part of ES2, we assume they are available // On the desktop we assume they are available if the extension // is present or GL version is high enough. - if (kGLES_GrGLStandard == fStandard) { - if (nullptr == fFunctions.fStencilFuncSeparate || - nullptr == fFunctions.fStencilMaskSeparate || - nullptr == fFunctions.fStencilOpSeparate) { - RETURN_FALSE_INTERFACE - } - } else if (kGL_GrGLStandard == fStandard) { - + if (kGL_GrGLStandard == fStandard) { if (glVer >= GR_GL_VER(2,0)) { - if (nullptr == fFunctions.fStencilFuncSeparate || - nullptr == fFunctions.fStencilMaskSeparate || - nullptr == fFunctions.fStencilOpSeparate || - nullptr == fFunctions.fPolygonMode) { + if (nullptr == fFunctions.fPolygonMode) { RETURN_FALSE_INTERFACE } } diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp index cbf2041255..6341aa897c 100644 --- a/src/gpu/gl/GrGLPathRendering.cpp +++ b/src/gpu/gl/GrGLPathRendering.cpp @@ -119,7 +119,6 @@ void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath* GrGLGpu* gpu = this->gpu(); SkASSERT(gpu->caps()->shaderCaps()->pathRenderingSupport()); gpu->flushColorWrite(false); - gpu->flushDrawFace(GrDrawFace::kBoth); GrGLRenderTarget* rt = static_cast(args.fRenderTarget); SkISize size = SkISize::Make(rt->width(), rt->height()); diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp index b2baf2eaff..faa8daa93c 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.cpp +++ b/src/gpu/ops/GrDefaultPathRenderer.cpp @@ -24,10 +24,8 @@ #include "ops/GrMeshDrawOp.h" #include "ops/GrRectOpFactory.h" -GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport, - bool stencilWrapOpsSupport) - : fSeparateStencil(separateStencilSupport) - , fStencilWrapOps(stencilWrapOpsSupport) { +GrDefaultPathRenderer::GrDefaultPathRenderer(bool stencilWrapOpsSupport) + : fStencilWrapOps(stencilWrapOpsSupport) { } //////////////////////////////////////////////////////////////////////////////// @@ -431,8 +429,7 @@ bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTarget } int passCount = 0; - const GrUserStencilSettings* passes[3]; - GrDrawFace drawFace[3]; + const GrUserStencilSettings* passes[2]; bool reverse = false; bool lastPassIsBounds; @@ -444,7 +441,6 @@ bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTarget passes[0] = &userStencilSettings; } lastPassIsBounds = false; - drawFace[0] = GrDrawFace::kBoth; } else { if (single_pass_shape(shape)) { passCount = 1; @@ -453,7 +449,6 @@ bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTarget } else { passes[0] = &userStencilSettings; } - drawFace[0] = GrDrawFace::kBoth; lastPassIsBounds = false; } else { switch (path.getFillType()) { @@ -474,40 +469,23 @@ bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTarget passes[1] = &gEOColorPass; } } - drawFace[0] = drawFace[1] = GrDrawFace::kBoth; break; case SkPath::kInverseWinding_FillType: reverse = true; // fallthrough case SkPath::kWinding_FillType: - if (fSeparateStencil) { - if (fStencilWrapOps) { - passes[0] = &gWindStencilSeparateWithWrap; - } else { - passes[0] = &gWindStencilSeparateNoWrap; - } - passCount = 2; - drawFace[0] = GrDrawFace::kBoth; + if (fStencilWrapOps) { + passes[0] = &gWindStencilSeparateWithWrap; } else { - if (fStencilWrapOps) { - passes[0] = &gWindSingleStencilWithWrapInc; - passes[1] = &gWindSingleStencilWithWrapDec; - } else { - passes[0] = &gWindSingleStencilNoWrapInc; - passes[1] = &gWindSingleStencilNoWrapDec; - } - // which is cw and which is ccw is arbitrary. - drawFace[0] = GrDrawFace::kCW; - drawFace[1] = GrDrawFace::kCCW; - passCount = 3; + passes[0] = &gWindStencilSeparateNoWrap; } + passCount = 2; if (stencilOnly) { lastPassIsBounds = false; --passCount; } else { lastPassIsBounds = true; - drawFace[passCount-1] = GrDrawFace::kBoth; if (reverse) { passes[passCount-1] = &gInvWindColorPass; } else { @@ -552,10 +530,7 @@ bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTarget viewMatrix; std::unique_ptr op(GrRectOpFactory::MakeNonAAFill( paint.getColor(), viewM, bounds, nullptr, &localMatrix)); - - SkASSERT(GrDrawFace::kBoth == drawFace[p]); GrPipelineBuilder pipelineBuilder(std::move(paint), aaType); - pipelineBuilder.setDrawFace(drawFace[p]); pipelineBuilder.setUserStencil(passes[p]); renderTargetContext->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op)); @@ -569,7 +544,6 @@ bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTarget passPaint.paint().setXPFactory(GrDisableColorXPFactory::Get()); } GrPipelineBuilder pipelineBuilder(std::move(passPaint), aaType); - pipelineBuilder.setDrawFace(drawFace[p]); pipelineBuilder.setUserStencil(passes[p]); renderTargetContext->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op)); diff --git a/src/gpu/ops/GrDefaultPathRenderer.h b/src/gpu/ops/GrDefaultPathRenderer.h index 0a84eb9356..ea2127dbf5 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.h +++ b/src/gpu/ops/GrDefaultPathRenderer.h @@ -18,7 +18,7 @@ */ class SK_API GrDefaultPathRenderer : public GrPathRenderer { public: - GrDefaultPathRenderer(bool separateStencilSupport, bool stencilWrapOpsSupport); + GrDefaultPathRenderer(bool stencilWrapOpsSupport); private: @@ -39,7 +39,6 @@ private: const GrShape&, bool stencilOnly); - bool fSeparateStencil; bool fStencilWrapOps; typedef GrPathRenderer INHERITED; diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index 2644987810..238b954dfc 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -28,7 +28,6 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* fMipMapSupport = true; // always available in Vulkan fSRGBSupport = true; // always available in Vulkan fNPOTTextureTileSupport = true; // always available in Vulkan - fTwoSidedStencilSupport = true; // always available in Vulkan fStencilWrapOpsSupport = true; // always available in Vulkan fDiscardRenderTargetSupport = true; fReuseScratchTextures = true; //TODO: figure this out diff --git a/src/gpu/vk/GrVkPipeline.cpp b/src/gpu/vk/GrVkPipeline.cpp index 8310199b39..809333f7ef 100644 --- a/src/gpu/vk/GrVkPipeline.cpp +++ b/src/gpu/vk/GrVkPipeline.cpp @@ -359,21 +359,6 @@ static void setup_color_blend_state(const GrPipeline& pipeline, // colorBlendInfo->blendConstants is set dynamically } -static VkCullModeFlags draw_face_to_vk_cull_mode(GrDrawFace drawFace) { - // Assumes that we've set the front face to be ccw - static const VkCullModeFlags gTable[] = { - VK_CULL_MODE_NONE, // kBoth_DrawFace - VK_CULL_MODE_BACK_BIT, // kCCW_DrawFace, cull back face - VK_CULL_MODE_FRONT_BIT, // kCW_DrawFace, cull front face - }; - GR_STATIC_ASSERT(0 == (int)GrDrawFace::kBoth); - GR_STATIC_ASSERT(1 == (int)GrDrawFace::kCCW); - GR_STATIC_ASSERT(2 == (int)GrDrawFace::kCW); - SkASSERT(-1 < (int)drawFace && (int)drawFace <= 2); - - return gTable[(int)drawFace]; -} - static void setup_raster_state(const GrPipeline& pipeline, const GrCaps* caps, VkPipelineRasterizationStateCreateInfo* rasterInfo) { @@ -385,7 +370,7 @@ static void setup_raster_state(const GrPipeline& pipeline, rasterInfo->rasterizerDiscardEnable = VK_FALSE; rasterInfo->polygonMode = caps->wireframeMode() ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL; - rasterInfo->cullMode = draw_face_to_vk_cull_mode(pipeline.getDrawFace()); + rasterInfo->cullMode = VK_CULL_MODE_NONE; rasterInfo->frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rasterInfo->depthBiasEnable = VK_FALSE; rasterInfo->depthBiasConstantFactor = 0.0f; diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp index 458a94ee02..ef0a96297e 100644 --- a/src/gpu/vk/GrVkPipelineState.cpp +++ b/src/gpu/vk/GrVkPipelineState.cpp @@ -517,9 +517,6 @@ bool GrVkPipelineState::Desc::Build(Desc* desc, stencil.genKey(&b); - SkASSERT(sizeof(GrDrawFace) <= sizeof(uint32_t)); - b.add32((int32_t)pipeline.getDrawFace()); - b.add32(get_blend_info_key(pipeline)); b.add32(primitiveType);