void set_dynamic_scissor_state(GrVkGpu* gpu, GrVkCommandBuffer* cmdBuffer, const GrPipeline& pipeline, const GrRenderTarget& target) { // We always use one scissor and if it is disabled we just make it the size of the RT const GrScissorState& scissorState = pipeline.getScissorState(); VkRect2D scissor; if (scissorState.enabled() && !scissorState.rect().contains(0, 0, target.width(), target.height())) { // This all assumes the scissorState has previously been clipped to the device space render // target. scissor.offset.x = scissorState.rect().fLeft; scissor.extent.width = scissorState.rect().width(); if (kTopLeft_GrSurfaceOrigin == target.origin()) { scissor.offset.y = scissorState.rect().fTop; } else { SkASSERT(kBottomLeft_GrSurfaceOrigin == target.origin()); scissor.offset.y = target.height() - scissorState.rect().fBottom; } scissor.extent.height = scissorState.rect().height(); SkASSERT(scissor.offset.x >= 0); SkASSERT(scissor.offset.x + scissor.extent.width <= (uint32_t)target.width()); SkASSERT(scissor.offset.y >= 0); SkASSERT(scissor.offset.y + scissor.extent.height <= (uint32_t)target.height()); } else { scissor.extent.width = target.width(); scissor.extent.height = target.height(); scissor.offset.x = 0; scissor.offset.y = 0; } cmdBuffer->setScissor(gpu, 0, 1, &scissor); }
bool GrVkProgramDescBuilder::Build(GrProgramDesc* desc, const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, const GrGLSLCaps& glslCaps) { // The descriptor is used as a cache key. Thus when a field of the // descriptor will not affect program generation (because of the attribute // bindings in use or other descriptor field settings) it should be set // to a canonical value to avoid duplicate programs with different keys. GrVkProgramDesc* vkDesc = (GrVkProgramDesc*)desc; GR_STATIC_ASSERT(0 == kProcessorKeysOffset % sizeof(uint32_t)); // Make room for everything up to the effect keys. vkDesc->key().reset(); vkDesc->key().push_back_n(kProcessorKeysOffset); GrProcessorKeyBuilder b(&vkDesc->key()); primProc.getGLSLProcessorKey(glslCaps, &b); if (!gen_meta_key(primProc, glslCaps, 0, &b)) { vkDesc->key().reset(); return false; } GrProcessor::RequiredFeatures requiredFeatures = primProc.requiredFeatures(); for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) { const GrFragmentProcessor& fp = pipeline.getFragmentProcessor(i); if (!gen_frag_proc_and_meta_keys(primProc, fp, glslCaps, &b)) { vkDesc->key().reset(); return false; } requiredFeatures |= fp.requiredFeatures(); } const GrXferProcessor& xp = pipeline.getXferProcessor(); xp.getGLSLProcessorKey(glslCaps, &b); if (!gen_meta_key(xp, glslCaps, 0, &b)) { vkDesc->key().reset(); return false; } requiredFeatures |= xp.requiredFeatures(); // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------------------------- // Because header is a pointer into the dynamic array, we can't push any new data into the key // below here. KeyHeader* header = vkDesc->atOffset<KeyHeader, kHeaderOffset>(); // make sure any padding in the header is zeroed. memset(header, 0, kHeaderSize); GrRenderTarget* rt = pipeline.getRenderTarget(); if (requiredFeatures & (GrProcessor::kFragmentPosition_RequiredFeature | GrProcessor::kSampleLocations_RequiredFeature)) { header->fSurfaceOriginKey = GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(rt->origin()); } else { header->fSurfaceOriginKey = 0; } if (requiredFeatures & GrProcessor::kSampleLocations_RequiredFeature) { SkASSERT(pipeline.isHWAntialiasState()); header->fSamplePatternKey = rt->renderTargetPriv().getMultisampleSpecs(pipeline.getStencil()).fUniqueID; } else { header->fSamplePatternKey = 0; } header->fOutputSwizzle = glslCaps.configOutputSwizzle(rt->config()).asKey(); if (pipeline.ignoresCoverage()) { header->fIgnoresCoverage = 1; } else { header->fIgnoresCoverage = 0; } header->fSnapVerticesToPixelCenters = pipeline.snapVerticesToPixelCenters(); header->fColorEffectCnt = pipeline.numColorFragmentProcessors(); header->fCoverageEffectCnt = pipeline.numCoverageFragmentProcessors(); vkDesc->finalize(); return true; }