1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2020 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DOpsRenderPass.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "src/gpu/GrBackendUtils.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrOpFlushState.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrProgramDesc.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrRenderTarget.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrStencilSettings.h" 15cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DBuffer.h" 16cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DCommandSignature.h" 17cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DGpu.h" 18cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DPipelineState.h" 19cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DPipelineStateBuilder.h" 20cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DRenderTarget.h" 21cb93a386Sopenharmony_ci#include "src/gpu/d3d/GrD3DTexture.h" 22cb93a386Sopenharmony_ci#include "src/gpu/effects/GrTextureEffect.h" 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci#ifdef SK_DEBUG 25cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 26cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 27cb93a386Sopenharmony_ci#endif 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ciGrD3DOpsRenderPass::GrD3DOpsRenderPass(GrD3DGpu* gpu) : fGpu(gpu) {} 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_cibool GrD3DOpsRenderPass::set(GrRenderTarget* rt, GrSurfaceOrigin origin, const SkIRect& bounds, 32cb93a386Sopenharmony_ci const GrOpsRenderPass::LoadAndStoreInfo& colorInfo, 33cb93a386Sopenharmony_ci const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo, 34cb93a386Sopenharmony_ci const SkTArray<GrSurfaceProxy*, true>& sampledProxies) { 35cb93a386Sopenharmony_ci SkASSERT(!fRenderTarget); 36cb93a386Sopenharmony_ci SkASSERT(fGpu == rt->getContext()->priv().getGpu()); 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ci this->INHERITED::set(rt, origin); 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci fBounds = bounds; 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci fColorLoadOp = colorInfo.fLoadOp; 43cb93a386Sopenharmony_ci fClearColor = colorInfo.fClearColor; 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci // TODO 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci return true; 48cb93a386Sopenharmony_ci} 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ciGrD3DOpsRenderPass::~GrD3DOpsRenderPass() {} 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ciGrGpu* GrD3DOpsRenderPass::gpu() { return fGpu; } 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_civoid GrD3DOpsRenderPass::onBegin() { 55cb93a386Sopenharmony_ci GrD3DRenderTarget* d3dRT = static_cast<GrD3DRenderTarget*>(fRenderTarget); 56cb93a386Sopenharmony_ci if (d3dRT->numSamples() > 1) { 57cb93a386Sopenharmony_ci d3dRT->msaaTextureResource()->setResourceState(fGpu, D3D12_RESOURCE_STATE_RENDER_TARGET); 58cb93a386Sopenharmony_ci } else { 59cb93a386Sopenharmony_ci d3dRT->setResourceState(fGpu, D3D12_RESOURCE_STATE_RENDER_TARGET); 60cb93a386Sopenharmony_ci } 61cb93a386Sopenharmony_ci fGpu->currentCommandList()->setRenderTarget(d3dRT); 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci if (GrLoadOp::kClear == fColorLoadOp) { 64cb93a386Sopenharmony_ci // Passing in nullptr for the rect clears the entire d3d RT. Is this correct? Does the load 65cb93a386Sopenharmony_ci // op respect the logical bounds of a RT? 66cb93a386Sopenharmony_ci fGpu->currentCommandList()->clearRenderTargetView(d3dRT, fClearColor, nullptr); 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci if (auto stencil = d3dRT->getStencilAttachment()) { 70cb93a386Sopenharmony_ci GrD3DAttachment* d3dStencil = static_cast<GrD3DAttachment*>(stencil); 71cb93a386Sopenharmony_ci d3dStencil->setResourceState(fGpu, D3D12_RESOURCE_STATE_DEPTH_WRITE); 72cb93a386Sopenharmony_ci if (fStencilLoadOp == GrLoadOp::kClear) { 73cb93a386Sopenharmony_ci fGpu->currentCommandList()->clearDepthStencilView(d3dStencil, 0, nullptr); 74cb93a386Sopenharmony_ci } 75cb93a386Sopenharmony_ci } 76cb93a386Sopenharmony_ci} 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_civoid set_stencil_ref(GrD3DGpu* gpu, const GrProgramInfo& info) { 79cb93a386Sopenharmony_ci GrStencilSettings stencilSettings = info.nonGLStencilSettings(); 80cb93a386Sopenharmony_ci if (!stencilSettings.isDisabled()) { 81cb93a386Sopenharmony_ci unsigned int stencilRef = 0; 82cb93a386Sopenharmony_ci if (stencilSettings.isTwoSided()) { 83cb93a386Sopenharmony_ci SkASSERT(stencilSettings.postOriginCCWFace(info.origin()).fRef == 84cb93a386Sopenharmony_ci stencilSettings.postOriginCWFace(info.origin()).fRef); 85cb93a386Sopenharmony_ci stencilRef = stencilSettings.postOriginCCWFace(info.origin()).fRef; 86cb93a386Sopenharmony_ci } else { 87cb93a386Sopenharmony_ci stencilRef = stencilSettings.singleSidedFace().fRef; 88cb93a386Sopenharmony_ci } 89cb93a386Sopenharmony_ci gpu->currentCommandList()->setStencilRef(stencilRef); 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci} 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_civoid set_blend_factor(GrD3DGpu* gpu, const GrProgramInfo& info) { 94cb93a386Sopenharmony_ci const GrXferProcessor& xferProcessor = info.pipeline().getXferProcessor(); 95cb93a386Sopenharmony_ci const GrSwizzle& swizzle = info.pipeline().writeSwizzle(); 96cb93a386Sopenharmony_ci const GrXferProcessor::BlendInfo& blendInfo = xferProcessor.getBlendInfo(); 97cb93a386Sopenharmony_ci GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; 98cb93a386Sopenharmony_ci GrBlendCoeff dstCoeff = blendInfo.fDstBlend; 99cb93a386Sopenharmony_ci float floatColors[4]; 100cb93a386Sopenharmony_ci if (GrBlendCoeffRefsConstant(srcCoeff) || GrBlendCoeffRefsConstant(dstCoeff)) { 101cb93a386Sopenharmony_ci // Swizzle the blend to match what the shader will output. 102cb93a386Sopenharmony_ci SkPMColor4f blendConst = swizzle.applyTo(blendInfo.fBlendConstant); 103cb93a386Sopenharmony_ci floatColors[0] = blendConst.fR; 104cb93a386Sopenharmony_ci floatColors[1] = blendConst.fG; 105cb93a386Sopenharmony_ci floatColors[2] = blendConst.fB; 106cb93a386Sopenharmony_ci floatColors[3] = blendConst.fA; 107cb93a386Sopenharmony_ci } else { 108cb93a386Sopenharmony_ci memset(floatColors, 0, 4 * sizeof(float)); 109cb93a386Sopenharmony_ci } 110cb93a386Sopenharmony_ci gpu->currentCommandList()->setBlendFactor(floatColors); 111cb93a386Sopenharmony_ci} 112cb93a386Sopenharmony_ci 113cb93a386Sopenharmony_civoid set_primitive_topology(GrD3DGpu* gpu, const GrProgramInfo& info) { 114cb93a386Sopenharmony_ci D3D12_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; 115cb93a386Sopenharmony_ci switch (info.primitiveType()) { 116cb93a386Sopenharmony_ci case GrPrimitiveType::kTriangles: 117cb93a386Sopenharmony_ci topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; 118cb93a386Sopenharmony_ci break; 119cb93a386Sopenharmony_ci case GrPrimitiveType::kTriangleStrip: 120cb93a386Sopenharmony_ci topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; 121cb93a386Sopenharmony_ci break; 122cb93a386Sopenharmony_ci case GrPrimitiveType::kPoints: 123cb93a386Sopenharmony_ci topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; 124cb93a386Sopenharmony_ci break; 125cb93a386Sopenharmony_ci case GrPrimitiveType::kLines: 126cb93a386Sopenharmony_ci topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; 127cb93a386Sopenharmony_ci break; 128cb93a386Sopenharmony_ci case GrPrimitiveType::kLineStrip: 129cb93a386Sopenharmony_ci topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; 130cb93a386Sopenharmony_ci break; 131cb93a386Sopenharmony_ci case GrPrimitiveType::kPatches: // Unsupported 132cb93a386Sopenharmony_ci case GrPrimitiveType::kPath: // Unsupported 133cb93a386Sopenharmony_ci default: 134cb93a386Sopenharmony_ci SkUNREACHABLE; 135cb93a386Sopenharmony_ci } 136cb93a386Sopenharmony_ci gpu->currentCommandList()->setPrimitiveTopology(topology); 137cb93a386Sopenharmony_ci} 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_civoid set_scissor_rects(GrD3DGpu* gpu, const GrRenderTarget* renderTarget, GrSurfaceOrigin rtOrigin, 140cb93a386Sopenharmony_ci const SkIRect& scissorRect) { 141cb93a386Sopenharmony_ci SkASSERT(scissorRect.isEmpty() || 142cb93a386Sopenharmony_ci SkIRect::MakeWH(renderTarget->width(), renderTarget->height()).contains(scissorRect)); 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci D3D12_RECT scissor; 145cb93a386Sopenharmony_ci scissor.left = scissorRect.fLeft; 146cb93a386Sopenharmony_ci scissor.right = scissorRect.fRight; 147cb93a386Sopenharmony_ci if (kTopLeft_GrSurfaceOrigin == rtOrigin) { 148cb93a386Sopenharmony_ci scissor.top = scissorRect.fTop; 149cb93a386Sopenharmony_ci } else { 150cb93a386Sopenharmony_ci SkASSERT(kBottomLeft_GrSurfaceOrigin == rtOrigin); 151cb93a386Sopenharmony_ci scissor.top = renderTarget->height() - scissorRect.fBottom; 152cb93a386Sopenharmony_ci } 153cb93a386Sopenharmony_ci scissor.bottom = scissor.top + scissorRect.height(); 154cb93a386Sopenharmony_ci 155cb93a386Sopenharmony_ci SkASSERT(scissor.left >= 0); 156cb93a386Sopenharmony_ci SkASSERT(scissor.top >= 0); 157cb93a386Sopenharmony_ci gpu->currentCommandList()->setScissorRects(1, &scissor); 158cb93a386Sopenharmony_ci} 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_civoid set_viewport(GrD3DGpu* gpu, const GrRenderTarget* renderTarget) { 161cb93a386Sopenharmony_ci D3D12_VIEWPORT viewport; 162cb93a386Sopenharmony_ci viewport.TopLeftX = 0.0f; 163cb93a386Sopenharmony_ci viewport.TopLeftY = 0.0f; 164cb93a386Sopenharmony_ci viewport.Width = SkIntToScalar(renderTarget->width()); 165cb93a386Sopenharmony_ci viewport.Height = SkIntToScalar(renderTarget->height()); 166cb93a386Sopenharmony_ci viewport.MinDepth = 0.0f; 167cb93a386Sopenharmony_ci viewport.MaxDepth = 1.0f; 168cb93a386Sopenharmony_ci gpu->currentCommandList()->setViewports(1, &viewport); 169cb93a386Sopenharmony_ci} 170cb93a386Sopenharmony_ci 171cb93a386Sopenharmony_cibool GrD3DOpsRenderPass::onBindPipeline(const GrProgramInfo& info, const SkRect& drawBounds) { 172cb93a386Sopenharmony_ci SkRect rtRect = SkRect::Make(fBounds); 173cb93a386Sopenharmony_ci if (rtRect.intersect(drawBounds)) { 174cb93a386Sopenharmony_ci rtRect.roundOut(&fCurrentPipelineBounds); 175cb93a386Sopenharmony_ci } else { 176cb93a386Sopenharmony_ci fCurrentPipelineBounds.setEmpty(); 177cb93a386Sopenharmony_ci } 178cb93a386Sopenharmony_ci 179cb93a386Sopenharmony_ci GrD3DRenderTarget* d3dRT = static_cast<GrD3DRenderTarget*>(fRenderTarget); 180cb93a386Sopenharmony_ci fCurrentPipelineState = 181cb93a386Sopenharmony_ci fGpu->resourceProvider().findOrCreateCompatiblePipelineState(d3dRT, info); 182cb93a386Sopenharmony_ci if (!fCurrentPipelineState) { 183cb93a386Sopenharmony_ci return false; 184cb93a386Sopenharmony_ci } 185cb93a386Sopenharmony_ci 186cb93a386Sopenharmony_ci fGpu->currentCommandList()->setGraphicsRootSignature(fCurrentPipelineState->rootSignature()); 187cb93a386Sopenharmony_ci fGpu->currentCommandList()->setPipelineState(fCurrentPipelineState->pipeline()); 188cb93a386Sopenharmony_ci fCurrentPipelineState->setAndBindConstants(fGpu, fRenderTarget, info); 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_ci set_stencil_ref(fGpu, info); 191cb93a386Sopenharmony_ci set_blend_factor(fGpu, info); 192cb93a386Sopenharmony_ci set_primitive_topology(fGpu, info); 193cb93a386Sopenharmony_ci if (!info.pipeline().isScissorTestEnabled()) { 194cb93a386Sopenharmony_ci // "Disable" scissor by setting it to the full pipeline bounds. 195cb93a386Sopenharmony_ci set_scissor_rects(fGpu, fRenderTarget, fOrigin, fCurrentPipelineBounds); 196cb93a386Sopenharmony_ci } 197cb93a386Sopenharmony_ci set_viewport(fGpu, fRenderTarget); 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_ci return true; 200cb93a386Sopenharmony_ci} 201cb93a386Sopenharmony_ci 202cb93a386Sopenharmony_civoid GrD3DOpsRenderPass::onSetScissorRect(const SkIRect& scissor) { 203cb93a386Sopenharmony_ci SkIRect combinedScissorRect; 204cb93a386Sopenharmony_ci if (!combinedScissorRect.intersect(fCurrentPipelineBounds, scissor)) { 205cb93a386Sopenharmony_ci combinedScissorRect = SkIRect::MakeEmpty(); 206cb93a386Sopenharmony_ci } 207cb93a386Sopenharmony_ci 208cb93a386Sopenharmony_ci set_scissor_rects(fGpu, fRenderTarget, fOrigin, combinedScissorRect); 209cb93a386Sopenharmony_ci} 210cb93a386Sopenharmony_ci 211cb93a386Sopenharmony_civoid update_resource_state(GrTexture* tex, GrRenderTarget* rt, GrD3DGpu* gpu) { 212cb93a386Sopenharmony_ci SkASSERT(!tex->isProtected() || (rt->isProtected() && gpu->protectedContext())); 213cb93a386Sopenharmony_ci GrD3DTexture* d3dTex = static_cast<GrD3DTexture*>(tex); 214cb93a386Sopenharmony_ci SkASSERT(d3dTex); 215cb93a386Sopenharmony_ci d3dTex->setResourceState(gpu, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); 216cb93a386Sopenharmony_ci} 217cb93a386Sopenharmony_ci 218cb93a386Sopenharmony_cibool GrD3DOpsRenderPass::onBindTextures(const GrGeometryProcessor& geomProc, 219cb93a386Sopenharmony_ci const GrSurfaceProxy* const geomProcTextures[], 220cb93a386Sopenharmony_ci const GrPipeline& pipeline) { 221cb93a386Sopenharmony_ci SkASSERT(fCurrentPipelineState); 222cb93a386Sopenharmony_ci 223cb93a386Sopenharmony_ci // update textures to sampled resource state 224cb93a386Sopenharmony_ci for (int i = 0; i < geomProc.numTextureSamplers(); ++i) { 225cb93a386Sopenharmony_ci update_resource_state(geomProcTextures[i]->peekTexture(), fRenderTarget, fGpu); 226cb93a386Sopenharmony_ci } 227cb93a386Sopenharmony_ci 228cb93a386Sopenharmony_ci pipeline.visitTextureEffects([&](const GrTextureEffect& te) { 229cb93a386Sopenharmony_ci update_resource_state(te.texture(), fRenderTarget, fGpu); 230cb93a386Sopenharmony_ci }); 231cb93a386Sopenharmony_ci 232cb93a386Sopenharmony_ci if (GrTexture* dstTexture = pipeline.peekDstTexture()) { 233cb93a386Sopenharmony_ci update_resource_state(dstTexture, fRenderTarget, fGpu); 234cb93a386Sopenharmony_ci } 235cb93a386Sopenharmony_ci 236cb93a386Sopenharmony_ci // TODO: possibly check for success once we start binding properly 237cb93a386Sopenharmony_ci fCurrentPipelineState->setAndBindTextures(fGpu, geomProc, geomProcTextures, pipeline); 238cb93a386Sopenharmony_ci 239cb93a386Sopenharmony_ci return true; 240cb93a386Sopenharmony_ci} 241cb93a386Sopenharmony_ci 242cb93a386Sopenharmony_civoid GrD3DOpsRenderPass::onBindBuffers(sk_sp<const GrBuffer> indexBuffer, 243cb93a386Sopenharmony_ci sk_sp<const GrBuffer> instanceBuffer, 244cb93a386Sopenharmony_ci sk_sp<const GrBuffer> vertexBuffer, 245cb93a386Sopenharmony_ci GrPrimitiveRestart primRestart) { 246cb93a386Sopenharmony_ci SkASSERT(GrPrimitiveRestart::kNo == primRestart); 247cb93a386Sopenharmony_ci SkASSERT(fCurrentPipelineState); 248cb93a386Sopenharmony_ci SkASSERT(!fGpu->caps()->usePrimitiveRestart()); // Ignore primitiveRestart parameter. 249cb93a386Sopenharmony_ci 250cb93a386Sopenharmony_ci GrD3DDirectCommandList* currCmdList = fGpu->currentCommandList(); 251cb93a386Sopenharmony_ci SkASSERT(currCmdList); 252cb93a386Sopenharmony_ci 253cb93a386Sopenharmony_ci fCurrentPipelineState->bindBuffers(fGpu, std::move(indexBuffer), std::move(instanceBuffer), 254cb93a386Sopenharmony_ci std::move(vertexBuffer), currCmdList); 255cb93a386Sopenharmony_ci} 256cb93a386Sopenharmony_ci 257cb93a386Sopenharmony_civoid GrD3DOpsRenderPass::onDrawInstanced(int instanceCount, int baseInstance, int vertexCount, 258cb93a386Sopenharmony_ci int baseVertex) { 259cb93a386Sopenharmony_ci SkASSERT(fCurrentPipelineState); 260cb93a386Sopenharmony_ci fGpu->currentCommandList()->drawInstanced(vertexCount, instanceCount, baseVertex, baseInstance); 261cb93a386Sopenharmony_ci fGpu->stats()->incNumDraws(); 262cb93a386Sopenharmony_ci} 263cb93a386Sopenharmony_ci 264cb93a386Sopenharmony_civoid GrD3DOpsRenderPass::onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, 265cb93a386Sopenharmony_ci int baseInstance, int baseVertex) { 266cb93a386Sopenharmony_ci SkASSERT(fCurrentPipelineState); 267cb93a386Sopenharmony_ci fGpu->currentCommandList()->drawIndexedInstanced(indexCount, instanceCount, baseIndex, 268cb93a386Sopenharmony_ci baseVertex, baseInstance); 269cb93a386Sopenharmony_ci fGpu->stats()->incNumDraws(); 270cb93a386Sopenharmony_ci} 271cb93a386Sopenharmony_ci 272cb93a386Sopenharmony_civoid GrD3DOpsRenderPass::onDrawIndirect(const GrBuffer* buffer, size_t offset, int drawCount) { 273cb93a386Sopenharmony_ci constexpr unsigned int kSlot = 0; 274cb93a386Sopenharmony_ci sk_sp<GrD3DCommandSignature> cmdSig = fGpu->resourceProvider().findOrCreateCommandSignature( 275cb93a386Sopenharmony_ci GrD3DCommandSignature::ForIndexed::kNo, kSlot); 276cb93a386Sopenharmony_ci fGpu->currentCommandList()->executeIndirect(cmdSig, drawCount, 277cb93a386Sopenharmony_ci static_cast<const GrD3DBuffer*>(buffer), offset); 278cb93a386Sopenharmony_ci fGpu->stats()->incNumDraws(); 279cb93a386Sopenharmony_ci} 280cb93a386Sopenharmony_ci 281cb93a386Sopenharmony_civoid GrD3DOpsRenderPass::onDrawIndexedIndirect(const GrBuffer* buffer, size_t offset, 282cb93a386Sopenharmony_ci int drawCount) { 283cb93a386Sopenharmony_ci constexpr unsigned int kSlot = 0; 284cb93a386Sopenharmony_ci sk_sp<GrD3DCommandSignature> cmdSig = fGpu->resourceProvider().findOrCreateCommandSignature( 285cb93a386Sopenharmony_ci GrD3DCommandSignature::ForIndexed::kYes, kSlot); 286cb93a386Sopenharmony_ci fGpu->currentCommandList()->executeIndirect(cmdSig, drawCount, 287cb93a386Sopenharmony_ci static_cast<const GrD3DBuffer*>(buffer), offset); 288cb93a386Sopenharmony_ci fGpu->stats()->incNumDraws(); 289cb93a386Sopenharmony_ci} 290cb93a386Sopenharmony_ci 291cb93a386Sopenharmony_ci 292cb93a386Sopenharmony_cistatic D3D12_RECT scissor_to_d3d_clear_rect(const GrScissorState& scissor, 293cb93a386Sopenharmony_ci const GrSurface* surface, 294cb93a386Sopenharmony_ci GrSurfaceOrigin origin) { 295cb93a386Sopenharmony_ci D3D12_RECT clearRect; 296cb93a386Sopenharmony_ci // Flip rect if necessary 297cb93a386Sopenharmony_ci SkIRect d3dRect; 298cb93a386Sopenharmony_ci if (!scissor.enabled()) { 299cb93a386Sopenharmony_ci d3dRect.setXYWH(0, 0, surface->width(), surface->height()); 300cb93a386Sopenharmony_ci } else if (kBottomLeft_GrSurfaceOrigin != origin) { 301cb93a386Sopenharmony_ci d3dRect = scissor.rect(); 302cb93a386Sopenharmony_ci } else { 303cb93a386Sopenharmony_ci d3dRect.setLTRB(scissor.rect().fLeft, surface->height() - scissor.rect().fBottom, 304cb93a386Sopenharmony_ci scissor.rect().fRight, surface->height() - scissor.rect().fTop); 305cb93a386Sopenharmony_ci } 306cb93a386Sopenharmony_ci clearRect.left = d3dRect.fLeft; 307cb93a386Sopenharmony_ci clearRect.right = d3dRect.fRight; 308cb93a386Sopenharmony_ci clearRect.top = d3dRect.fTop; 309cb93a386Sopenharmony_ci clearRect.bottom = d3dRect.fBottom; 310cb93a386Sopenharmony_ci return clearRect; 311cb93a386Sopenharmony_ci} 312cb93a386Sopenharmony_ci 313cb93a386Sopenharmony_civoid GrD3DOpsRenderPass::onClear(const GrScissorState& scissor, std::array<float, 4> color) { 314cb93a386Sopenharmony_ci D3D12_RECT clearRect = scissor_to_d3d_clear_rect(scissor, fRenderTarget, fOrigin); 315cb93a386Sopenharmony_ci auto d3dRT = static_cast<GrD3DRenderTarget*>(fRenderTarget); 316cb93a386Sopenharmony_ci SkASSERT(d3dRT->grD3DResourceState()->getResourceState() == D3D12_RESOURCE_STATE_RENDER_TARGET); 317cb93a386Sopenharmony_ci fGpu->currentCommandList()->clearRenderTargetView(d3dRT, color, &clearRect); 318cb93a386Sopenharmony_ci} 319cb93a386Sopenharmony_ci 320cb93a386Sopenharmony_civoid GrD3DOpsRenderPass::onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) { 321cb93a386Sopenharmony_ci GrAttachment* sb = fRenderTarget->getStencilAttachment(); 322cb93a386Sopenharmony_ci // this should only be called internally when we know we have a 323cb93a386Sopenharmony_ci // stencil buffer. 324cb93a386Sopenharmony_ci SkASSERT(sb); 325cb93a386Sopenharmony_ci int stencilBitCount = GrBackendFormatStencilBits(sb->backendFormat()); 326cb93a386Sopenharmony_ci 327cb93a386Sopenharmony_ci // The contract with the callers does not guarantee that we preserve all bits in the stencil 328cb93a386Sopenharmony_ci // during this clear. Thus we will clear the entire stencil to the desired value. 329cb93a386Sopenharmony_ci 330cb93a386Sopenharmony_ci uint8_t stencilColor = 0; 331cb93a386Sopenharmony_ci if (insideStencilMask) { 332cb93a386Sopenharmony_ci stencilColor = (1 << (stencilBitCount - 1)); 333cb93a386Sopenharmony_ci } 334cb93a386Sopenharmony_ci 335cb93a386Sopenharmony_ci D3D12_RECT clearRect = scissor_to_d3d_clear_rect(scissor, fRenderTarget, fOrigin); 336cb93a386Sopenharmony_ci 337cb93a386Sopenharmony_ci auto d3dStencil = static_cast<GrD3DAttachment*>(sb); 338cb93a386Sopenharmony_ci fGpu->currentCommandList()->clearDepthStencilView(d3dStencil, stencilColor, &clearRect); 339cb93a386Sopenharmony_ci} 340cb93a386Sopenharmony_ci 341cb93a386Sopenharmony_civoid GrD3DOpsRenderPass::inlineUpload(GrOpFlushState* state, GrDeferredTextureUploadFn& upload) { 342cb93a386Sopenharmony_ci // If we ever start using copy command lists for doing uploads, then we'll need to make sure 343cb93a386Sopenharmony_ci // we submit our main command list before doing the copy here and then start a new main command 344cb93a386Sopenharmony_ci // list. 345cb93a386Sopenharmony_ci 346cb93a386Sopenharmony_ci fGpu->endRenderPass(fRenderTarget, fOrigin, fBounds); 347cb93a386Sopenharmony_ci 348cb93a386Sopenharmony_ci // We pass in true here to signal that after the upload we need to set the upload texture's 349cb93a386Sopenharmony_ci // resource state back to D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE. 350cb93a386Sopenharmony_ci state->doUpload(upload, true); 351cb93a386Sopenharmony_ci} 352cb93a386Sopenharmony_ci 353cb93a386Sopenharmony_civoid GrD3DOpsRenderPass::submit() { 354cb93a386Sopenharmony_ci if (!fRenderTarget) { 355cb93a386Sopenharmony_ci return; 356cb93a386Sopenharmony_ci } 357cb93a386Sopenharmony_ci 358cb93a386Sopenharmony_ci // We don't use render passes in d3d, so there is nothing to submit here as all commands have 359cb93a386Sopenharmony_ci // already been recorded on the main command list. If in the future we start to use render 360cb93a386Sopenharmony_ci // passes on d3d12 devices that support them (most likely ARM devices), then we 361cb93a386Sopenharmony_ci // will submit them here. 362cb93a386Sopenharmony_ci fGpu->endRenderPass(fRenderTarget, fOrigin, fBounds); 363cb93a386Sopenharmony_ci} 364