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