Add Metal support for dynamic texture state

Bug: skia:9604
Change-Id: I16f487137c79e37493cd24b63ee29ac2e22d6cec
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/254981
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2019-11-18 11:58:25 -05:00 committed by Skia Commit-Bot
parent 5d07c5279b
commit 9042d46ff4
4 changed files with 42 additions and 20 deletions

View File

@ -293,6 +293,8 @@ void GrMtlCaps::initGrCaps(const id<MTLDevice> device) {
fCrossContextTextureSupport = false;
fHalfFloatVertexAttributeSupport = true;
fDynamicStateArrayGeometryProcessorTextureSupport = true;
}
static bool format_is_srgb(MTLPixelFormat format) {

View File

@ -89,6 +89,7 @@ void GrMtlOpsRenderPass::onDraw(const GrProgramInfo& programInfo,
programInfo.pipeline().getXferProcessor());
bool hasDynamicScissors = programInfo.hasDynamicScissors();
bool hasDynamicTextures = programInfo.hasDynamicPrimProcTextures();
if (!programInfo.pipeline().isScissorEnabled()) {
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder,
@ -103,6 +104,10 @@ void GrMtlOpsRenderPass::onDraw(const GrProgramInfo& programInfo,
programInfo.fixedScissor());
}
if (!hasDynamicTextures) {
pipelineState->bindTextures(fActiveRenderCmdEncoder);
}
for (int i = 0; i < meshCount; ++i) {
const GrMesh& mesh = meshes[i];
SkASSERT(nil != fActiveRenderCmdEncoder);
@ -113,6 +118,11 @@ void GrMtlOpsRenderPass::onDraw(const GrProgramInfo& programInfo,
fOrigin,
programInfo.dynamicScissor(i));
}
if (hasDynamicTextures) {
auto meshProxies = programInfo.dynamicPrimProcTextures(i);
pipelineState->setTextures(programInfo, meshProxies);
pipelineState->bindTextures(fActiveRenderCmdEncoder);
}
mesh.sendToGpu(this);
}

View File

@ -48,6 +48,10 @@ public:
void setData(const GrRenderTarget*, const GrProgramInfo&);
void setTextures(const GrProgramInfo& programInfo,
const GrTextureProxy* const primProcTextures[]);
void bindTextures(id<MTLRenderCommandEncoder> renderCmdEncoder);
void setDrawState(id<MTLRenderCommandEncoder>, const GrSwizzle& outputSwizzle,
const GrXferProcessor&);
@ -97,7 +101,7 @@ private:
void setRenderTargetState(const GrRenderTarget*, GrSurfaceOrigin);
void bind(id<MTLRenderCommandEncoder>);
void bindUniforms(id<MTLRenderCommandEncoder>);
void setBlendConstants(id<MTLRenderCommandEncoder>, const GrSwizzle&, const GrXferProcessor&);

View File

@ -58,19 +58,33 @@ GrMtlPipelineState::GrMtlPipelineState(
void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
const GrProgramInfo& programInfo) {
// Note: the Metal backend currently only supports fixed primProc textures
SkASSERT(!programInfo.hasDynamicPrimProcTextures());
auto proxies = programInfo.hasFixedPrimProcTextures() ? programInfo.fixedPrimProcTextures()
: nullptr;
this->setRenderTargetState(renderTarget, programInfo.origin());
fGeometryProcessor->setData(fDataManager, programInfo.primProc(),
GrFragmentProcessor::CoordTransformIter(programInfo.pipeline()));
if (!programInfo.hasDynamicPrimProcTextures()) {
auto proxies = programInfo.hasFixedPrimProcTextures() ? programInfo.fixedPrimProcTextures()
: nullptr;
this->setTextures(programInfo, proxies);
}
fDataManager.resetDirtyBits();
#ifdef SK_DEBUG
if (programInfo.pipeline().isStencilEnabled()) {
SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
SkASSERT(renderTarget->renderTargetPriv().numStencilBits() == 8);
}
#endif
fStencil = programInfo.nonGLStencilSettings();
}
void GrMtlPipelineState::setTextures(const GrProgramInfo& programInfo,
const GrTextureProxy* const primProcTextures[]) {
fSamplerBindings.reset();
for (int i = 0; i < programInfo.primProc().numTextureSamplers(); ++i) {
const auto& sampler = programInfo.primProc().textureSampler(i);
auto texture = static_cast<GrMtlTexture*>(proxies[i]->peekTexture());
auto texture = static_cast<GrMtlTexture*>(primProcTextures[i]->peekTexture());
fSamplerBindings.emplace_back(sampler.samplerState(), texture, fGpu);
}
@ -104,31 +118,23 @@ void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
}
SkASSERT(fNumSamplers == fSamplerBindings.count());
fDataManager.resetDirtyBits();
#ifdef SK_DEBUG
if (programInfo.pipeline().isStencilEnabled()) {
SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
SkASSERT(renderTarget->renderTargetPriv().numStencilBits() == 8);
}
#endif
fStencil = programInfo.nonGLStencilSettings();
}
void GrMtlPipelineState::setDrawState(id<MTLRenderCommandEncoder> renderCmdEncoder,
const GrSwizzle& outputSwizzle,
const GrXferProcessor& xferProcessor) {
[renderCmdEncoder pushDebugGroup:@"setDrawState"];
this->bind(renderCmdEncoder);
this->bindUniforms(renderCmdEncoder);
this->setBlendConstants(renderCmdEncoder, outputSwizzle, xferProcessor);
this->setDepthStencilState(renderCmdEncoder);
[renderCmdEncoder popDebugGroup];
}
void GrMtlPipelineState::bind(id<MTLRenderCommandEncoder> renderCmdEncoder) {
void GrMtlPipelineState::bindUniforms(id<MTLRenderCommandEncoder> renderCmdEncoder) {
fDataManager.uploadAndBindUniformBuffers(fGpu, renderCmdEncoder);
}
void GrMtlPipelineState::bindTextures(id<MTLRenderCommandEncoder> renderCmdEncoder) {
SkASSERT(fNumSamplers == fSamplerBindings.count());
for (int index = 0; index < fNumSamplers; ++index) {
[renderCmdEncoder setFragmentTexture: fSamplerBindings[index].fTexture