• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #include "src/gpu/d3d/GrD3DPipelineState.h"
9 
10 #include "include/private/SkTemplates.h"
11 #include "src/gpu/GrProgramInfo.h"
12 #include "src/gpu/GrStencilSettings.h"
13 #include "src/gpu/d3d/GrD3DBuffer.h"
14 #include "src/gpu/d3d/GrD3DGpu.h"
15 #include "src/gpu/d3d/GrD3DPipeline.h"
16 #include "src/gpu/d3d/GrD3DRootSignature.h"
17 #include "src/gpu/d3d/GrD3DTexture.h"
18 #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
19 #include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
20 #include "src/gpu/glsl/GrGLSLXferProcessor.h"
21 
GrD3DPipelineState(sk_sp<GrD3DPipeline> pipeline,sk_sp<GrD3DRootSignature> rootSignature,const GrGLSLBuiltinUniformHandles & builtinUniformHandles,const UniformInfoArray & uniforms,uint32_t uniformSize,uint32_t numSamplers,std::unique_ptr<GrGLSLGeometryProcessor> geometryProcessor,std::unique_ptr<GrGLSLXferProcessor> xferProcessor,std::vector<std::unique_ptr<GrGLSLFragmentProcessor>> fpImpls,size_t vertexStride,size_t instanceStride)22 GrD3DPipelineState::GrD3DPipelineState(
23         sk_sp<GrD3DPipeline> pipeline,
24         sk_sp<GrD3DRootSignature> rootSignature,
25         const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
26         const UniformInfoArray& uniforms, uint32_t uniformSize,
27         uint32_t numSamplers,
28         std::unique_ptr<GrGLSLGeometryProcessor> geometryProcessor,
29         std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
30         std::vector<std::unique_ptr<GrGLSLFragmentProcessor>> fpImpls,
31         size_t vertexStride,
32         size_t instanceStride)
33     : fPipeline(std::move(pipeline))
34     , fRootSignature(std::move(rootSignature))
35     , fBuiltinUniformHandles(builtinUniformHandles)
36     , fGeometryProcessor(std::move(geometryProcessor))
37     , fXferProcessor(std::move(xferProcessor))
38     , fFPImpls(std::move(fpImpls))
39     , fDataManager(uniforms, uniformSize)
40     , fNumSamplers(numSamplers)
41     , fVertexStride(vertexStride)
42     , fInstanceStride(instanceStride) {}
43 
setAndBindConstants(GrD3DGpu * gpu,const GrRenderTarget * renderTarget,const GrProgramInfo & programInfo)44 void GrD3DPipelineState::setAndBindConstants(GrD3DGpu* gpu,
45                                              const GrRenderTarget* renderTarget,
46                                              const GrProgramInfo& programInfo) {
47     this->setRenderTargetState(renderTarget, programInfo.origin());
48 
49     fGeometryProcessor->setData(fDataManager, *gpu->caps()->shaderCaps(), programInfo.geomProc());
50     for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) {
51         auto& fp = programInfo.pipeline().getFragmentProcessor(i);
52         for (auto [fp, impl] : GrGLSLFragmentProcessor::ParallelRange(fp, *fFPImpls[i])) {
53             impl.setData(fDataManager, fp);
54         }
55     }
56 
57     {
58         SkIPoint offset;
59         GrTexture* dstTexture = programInfo.pipeline().peekDstTexture(&offset);
60 
61         fXferProcessor->setData(fDataManager, programInfo.pipeline().getXferProcessor(),
62                                 dstTexture, offset);
63     }
64 
65     D3D12_GPU_VIRTUAL_ADDRESS constantsAddress = fDataManager.uploadConstants(gpu);
66     gpu->currentCommandList()->setGraphicsRootConstantBufferView(
67         (unsigned int)(GrD3DRootSignature::ParamIndex::kConstantBufferView),
68         constantsAddress);
69 }
70 
setRenderTargetState(const GrRenderTarget * rt,GrSurfaceOrigin origin)71 void GrD3DPipelineState::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) {
72     // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
73     if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
74         fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
75         fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
76     }
77 
78     // set RT adjustment
79     SkISize dimensions = rt->dimensions();
80     SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
81     if (fRenderTargetState.fRenderTargetOrigin != origin ||
82         fRenderTargetState.fRenderTargetSize != dimensions) {
83         fRenderTargetState.fRenderTargetSize = dimensions;
84         fRenderTargetState.fRenderTargetOrigin = origin;
85 
86         float rtAdjustmentVec[4];
87         fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
88         fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
89     }
90 }
91 
setAndBindTextures(GrD3DGpu * gpu,const GrGeometryProcessor & geomProc,const GrSurfaceProxy * const geomProcTextures[],const GrPipeline & pipeline)92 void GrD3DPipelineState::setAndBindTextures(GrD3DGpu* gpu,
93                                             const GrGeometryProcessor& geomProc,
94                                             const GrSurfaceProxy* const geomProcTextures[],
95                                             const GrPipeline& pipeline) {
96     SkASSERT(geomProcTextures || !geomProc.numTextureSamplers());
97 
98     std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> shaderResourceViews(fNumSamplers);
99     std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> samplers(fNumSamplers);
100     unsigned int currTextureBinding = 0;
101 
102     for (int i = 0; i < geomProc.numTextureSamplers(); ++i) {
103         SkASSERT(geomProcTextures[i]->asTextureProxy());
104         const auto& sampler = geomProc.textureSampler(i);
105         auto texture = static_cast<GrD3DTexture*>(geomProcTextures[i]->peekTexture());
106         shaderResourceViews[currTextureBinding] = texture->shaderResourceView();
107         samplers[currTextureBinding++] =
108                 gpu->resourceProvider().findOrCreateCompatibleSampler(sampler.samplerState());
109         gpu->currentCommandList()->addSampledTextureRef(texture);
110     }
111 
112     pipeline.visitTextureEffects([&](const GrTextureEffect& te) {
113         GrSamplerState samplerState = te.samplerState();
114         auto* texture = static_cast<GrD3DTexture*>(te.texture());
115         shaderResourceViews[currTextureBinding] = texture->shaderResourceView();
116         samplers[currTextureBinding++] =
117                 gpu->resourceProvider().findOrCreateCompatibleSampler(samplerState);
118         gpu->currentCommandList()->addSampledTextureRef(texture);
119     });
120 
121     if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
122         auto texture = static_cast<GrD3DTexture*>(dstTexture);
123         shaderResourceViews[currTextureBinding] = texture->shaderResourceView();
124         samplers[currTextureBinding++] = gpu->resourceProvider().findOrCreateCompatibleSampler(
125                                                GrSamplerState::Filter::kNearest);
126         gpu->currentCommandList()->addSampledTextureRef(texture);
127     }
128 
129     SkASSERT(fNumSamplers == currTextureBinding);
130 
131     // fill in descriptor tables and bind to root signature
132     if (fNumSamplers > 0) {
133         // set up and bind shader resource view table
134         sk_sp<GrD3DDescriptorTable> srvTable =
135                 gpu->resourceProvider().findOrCreateShaderViewTable(shaderResourceViews);
136         gpu->currentCommandList()->setGraphicsRootDescriptorTable(
137                 (unsigned int)GrD3DRootSignature::ParamIndex::kShaderViewDescriptorTable,
138                 srvTable->baseGpuDescriptor());
139 
140         // set up and bind sampler table
141         sk_sp<GrD3DDescriptorTable> samplerTable =
142                 gpu->resourceProvider().findOrCreateSamplerTable(samplers);
143         gpu->currentCommandList()->setGraphicsRootDescriptorTable(
144                 (unsigned int)GrD3DRootSignature::ParamIndex::kSamplerDescriptorTable,
145                 samplerTable->baseGpuDescriptor());
146     }
147 }
148 
bindBuffers(GrD3DGpu * gpu,sk_sp<const GrBuffer> indexBuffer,sk_sp<const GrBuffer> instanceBuffer,sk_sp<const GrBuffer> vertexBuffer,GrD3DDirectCommandList * commandList)149 void GrD3DPipelineState::bindBuffers(GrD3DGpu* gpu, sk_sp<const GrBuffer> indexBuffer,
150                                      sk_sp<const GrBuffer> instanceBuffer,
151                                      sk_sp<const GrBuffer> vertexBuffer,
152                                      GrD3DDirectCommandList* commandList) {
153     // Here our vertex and instance inputs need to match the same 0-based bindings they were
154     // assigned in the PipelineState. That is, vertex first (if any) followed by instance.
155     if (vertexBuffer) {
156         auto* d3dVertexBuffer = static_cast<const GrD3DBuffer*>(vertexBuffer.get());
157         SkASSERT(!d3dVertexBuffer->isCpuBuffer());
158         SkASSERT(!d3dVertexBuffer->isMapped());
159         const_cast<GrD3DBuffer*>(d3dVertexBuffer)->setResourceState(
160                 gpu, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
161     }
162     if (instanceBuffer) {
163         auto* d3dInstanceBuffer = static_cast<const GrD3DBuffer*>(instanceBuffer.get());
164         SkASSERT(!d3dInstanceBuffer->isCpuBuffer());
165         SkASSERT(!d3dInstanceBuffer->isMapped());
166         const_cast<GrD3DBuffer*>(d3dInstanceBuffer)->setResourceState(
167                 gpu, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
168     }
169     commandList->setVertexBuffers(0, std::move(vertexBuffer), fVertexStride,
170                                   std::move(instanceBuffer), fInstanceStride);
171 
172     if (auto* d3dIndexBuffer = static_cast<const GrD3DBuffer*>(indexBuffer.get())) {
173         SkASSERT(!d3dIndexBuffer->isCpuBuffer());
174         SkASSERT(!d3dIndexBuffer->isMapped());
175         const_cast<GrD3DBuffer*>(d3dIndexBuffer)->setResourceState(
176                 gpu, D3D12_RESOURCE_STATE_INDEX_BUFFER);
177         commandList->setIndexBuffer(std::move(indexBuffer));
178     }
179 }
180