void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline) { this->setRenderTargetState(primProc, pipeline.proxy()); // we set the textures, and uniforms for installed processors in a generic way, but subclasses // of GLProgram determine how to set coord transforms // We must bind to texture units in the same order in which we set the uniforms in // GrGLProgramDataManager. That is first all texture samplers and then texel buffers. // Within each group we will bind them in primProc, fragProcs, XP order. int nextTexSamplerIdx = 0; int nextTexelBufferIdx = fNumTextureSamplers; fGeometryProcessor->setData(fProgramDataManager, primProc, GrFragmentProcessor::CoordTransformIter(pipeline)); this->bindTextures(primProc, pipeline.getAllowSRGBInputs(), &nextTexSamplerIdx, &nextTexelBufferIdx); this->setFragmentData(primProc, pipeline, &nextTexSamplerIdx, &nextTexelBufferIdx); const GrXferProcessor& xp = pipeline.getXferProcessor(); SkIPoint offset; GrTexture* dstTexture = pipeline.peekDstTexture(&offset); fXferProcessor->setData(fProgramDataManager, xp, dstTexture, offset); if (dstTexture) { fGpu->bindTexture(nextTexSamplerIdx++, GrSamplerState::ClampNearest(), true, static_cast<GrGLTexture*>(dstTexture), pipeline.dstTextureProxy()->origin()); } SkASSERT(nextTexSamplerIdx == fNumTextureSamplers); SkASSERT(nextTexelBufferIdx == fNumTextureSamplers + fNumTexelBuffers); }
void GrVkPipelineState::setAndBindUniforms(GrVkGpu* gpu, const GrRenderTarget* renderTarget, GrSurfaceOrigin origin, const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, GrVkCommandBuffer* commandBuffer) { this->setRenderTargetState(renderTarget, origin); fGeometryProcessor->setData(fDataManager, primProc, GrFragmentProcessor::CoordTransformIter(pipeline)); GrFragmentProcessor::Iter iter(pipeline); GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt); const GrFragmentProcessor* fp = iter.next(); GrGLSLFragmentProcessor* glslFP = glslIter.next(); while (fp && glslFP) { glslFP->setData(fDataManager, *fp); fp = iter.next(); glslFP = glslIter.next(); } SkASSERT(!fp && !glslFP); { SkIPoint offset; GrTexture* dstTexture = pipeline.peekDstTexture(&offset); fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset); } // Get new descriptor set if (fGeometryUniformBuffer || fFragmentUniformBuffer) { int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet; if (fDataManager.uploadUniformBuffers( gpu, fGeometryUniformBuffer.get(), fFragmentUniformBuffer.get()) || !fUniformDescriptorSet) { if (fUniformDescriptorSet) { fUniformDescriptorSet->recycle(gpu); } fUniformDescriptorSet = gpu->resourceProvider().getUniformDescriptorSet(); fDescriptorSets[uniformDSIdx] = fUniformDescriptorSet->descriptorSet(); this->writeUniformBuffers(gpu); } commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, uniformDSIdx, 1, &fDescriptorSets[uniformDSIdx], 0, nullptr); if (fUniformDescriptorSet) { commandBuffer->addRecycledResource(fUniformDescriptorSet); } if (fGeometryUniformBuffer) { commandBuffer->addRecycledResource(fGeometryUniformBuffer->resource()); } if (fFragmentUniformBuffer) { commandBuffer->addRecycledResource(fFragmentUniformBuffer->resource()); } } }
void GrVkGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, const GrPipeline::FixedDynamicState* fixedDynamicState, const GrPipeline::DynamicStateArrays* dynamicStateArrays, const GrMesh meshes[], int meshCount, const SkRect& bounds) { if (!meshCount) { return; } CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo]; auto prepareSampledImage = [&](GrTexture* texture, GrSamplerState::Filter filter) { GrVkTexture* vkTexture = static_cast<GrVkTexture*>(texture); // We may need to resolve the texture first if it is also a render target GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget()); if (texRT) { fGpu->resolveRenderTargetNoFlush(texRT); } // Check if we need to regenerate any mip maps if (GrSamplerState::Filter::kMipMap == filter && (vkTexture->width() != 1 || vkTexture->height() != 1)) { SkASSERT(vkTexture->texturePriv().mipMapped() == GrMipMapped::kYes); if (vkTexture->texturePriv().mipMapsAreDirty()) { fGpu->regenerateMipMapLevels(vkTexture); } } cbInfo.fSampledTextures.push_back(vkTexture); }; if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) { for (int m = 0, i = 0; m < meshCount; ++m) { for (int s = 0; s < primProc.numTextureSamplers(); ++s, ++i) { auto texture = dynamicStateArrays->fPrimitiveProcessorTextures[i]->peekTexture(); prepareSampledImage(texture, primProc.textureSampler(s).samplerState().filter()); } } } else { for (int i = 0; i < primProc.numTextureSamplers(); ++i) { auto texture = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture(); prepareSampledImage(texture, primProc.textureSampler(i).samplerState().filter()); } } GrFragmentProcessor::Iter iter(pipeline); while (const GrFragmentProcessor* fp = iter.next()) { for (int i = 0; i < fp->numTextureSamplers(); ++i) { const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i); prepareSampledImage(sampler.peekTexture(), sampler.samplerState().filter()); } } if (GrTexture* dstTexture = pipeline.peekDstTexture()) { cbInfo.fSampledTextures.push_back(sk_ref_sp(static_cast<GrVkTexture*>(dstTexture))); } GrPrimitiveType primitiveType = meshes[0].primitiveType(); GrVkPipelineState* pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState, dynamicStateArrays, primitiveType); if (!pipelineState) { return; } bool dynamicScissor = pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects; bool dynamicTextures = dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures; for (int i = 0; i < meshCount; ++i) { const GrMesh& mesh = meshes[i]; if (mesh.primitiveType() != primitiveType) { SkDEBUGCODE(pipelineState = nullptr); primitiveType = mesh.primitiveType(); pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState, dynamicStateArrays, primitiveType); if (!pipelineState) { return; } } if (dynamicScissor) { GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget, fOrigin, dynamicStateArrays->fScissorRects[i]); } if (dynamicTextures) { GrTextureProxy* const* meshProxies = dynamicStateArrays->fPrimitiveProcessorTextures + primProc.numTextureSamplers() * i; pipelineState->setAndBindTextures(fGpu, primProc, pipeline, meshProxies, cbInfo.currentCmdBuf()); } SkASSERT(pipelineState); mesh.sendToGpu(this); } cbInfo.fBounds.join(bounds); cbInfo.fIsEmpty = false; }