1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2020 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker //#include <d3dcompiler.h>
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/d3d/GrD3DPipelineStateBuilder.h"
11*c8dee2aaSAndroid Build Coastguard Worker
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/d3d/GrD3DTypes.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkReadBuffer.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkTraceEvent.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/SkSLToBackend.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrAutoLocaleSetter.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrPersistentCacheUtils.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrShaderCaps.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrStencilSettings.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/d3d/GrD3DGpu.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/d3d/GrD3DPipeline.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/d3d/GrD3DRenderTarget.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/d3d/GrD3DRootSignature.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/d3d/GrD3DUtil.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLCompiler.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLProgramKind.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLProgramSettings.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "src/utils/SkShaderUtils.h"
31*c8dee2aaSAndroid Build Coastguard Worker
32*c8dee2aaSAndroid Build Coastguard Worker #include <d3dcompiler.h>
33*c8dee2aaSAndroid Build Coastguard Worker
34*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
35*c8dee2aaSAndroid Build Coastguard Worker
MakePipelineState(GrD3DGpu * gpu,GrD3DRenderTarget * renderTarget,const GrProgramDesc & desc,const GrProgramInfo & programInfo)36*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrD3DPipelineState> GrD3DPipelineStateBuilder::MakePipelineState(
37*c8dee2aaSAndroid Build Coastguard Worker GrD3DGpu* gpu,
38*c8dee2aaSAndroid Build Coastguard Worker GrD3DRenderTarget* renderTarget,
39*c8dee2aaSAndroid Build Coastguard Worker const GrProgramDesc& desc,
40*c8dee2aaSAndroid Build Coastguard Worker const GrProgramInfo& programInfo) {
41*c8dee2aaSAndroid Build Coastguard Worker // ensure that we use "." as a decimal separator when creating SkSL code
42*c8dee2aaSAndroid Build Coastguard Worker GrAutoLocaleSetter als("C");
43*c8dee2aaSAndroid Build Coastguard Worker
44*c8dee2aaSAndroid Build Coastguard Worker // create a builder. This will be handed off to effects so they can use it to add
45*c8dee2aaSAndroid Build Coastguard Worker // uniforms, varyings, textures, etc
46*c8dee2aaSAndroid Build Coastguard Worker GrD3DPipelineStateBuilder builder(gpu, renderTarget, desc, programInfo);
47*c8dee2aaSAndroid Build Coastguard Worker
48*c8dee2aaSAndroid Build Coastguard Worker if (!builder.emitAndInstallProcs()) {
49*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
50*c8dee2aaSAndroid Build Coastguard Worker }
51*c8dee2aaSAndroid Build Coastguard Worker
52*c8dee2aaSAndroid Build Coastguard Worker return builder.finalize();
53*c8dee2aaSAndroid Build Coastguard Worker }
54*c8dee2aaSAndroid Build Coastguard Worker
GrD3DPipelineStateBuilder(GrD3DGpu * gpu,GrD3DRenderTarget * renderTarget,const GrProgramDesc & desc,const GrProgramInfo & programInfo)55*c8dee2aaSAndroid Build Coastguard Worker GrD3DPipelineStateBuilder::GrD3DPipelineStateBuilder(GrD3DGpu* gpu,
56*c8dee2aaSAndroid Build Coastguard Worker GrD3DRenderTarget* renderTarget,
57*c8dee2aaSAndroid Build Coastguard Worker const GrProgramDesc& desc,
58*c8dee2aaSAndroid Build Coastguard Worker const GrProgramInfo& programInfo)
59*c8dee2aaSAndroid Build Coastguard Worker : INHERITED(desc, programInfo)
60*c8dee2aaSAndroid Build Coastguard Worker , fGpu(gpu)
61*c8dee2aaSAndroid Build Coastguard Worker , fVaryingHandler(this)
62*c8dee2aaSAndroid Build Coastguard Worker , fUniformHandler(this)
63*c8dee2aaSAndroid Build Coastguard Worker , fRenderTarget(renderTarget) {}
64*c8dee2aaSAndroid Build Coastguard Worker
caps() const65*c8dee2aaSAndroid Build Coastguard Worker const GrCaps* GrD3DPipelineStateBuilder::caps() const {
66*c8dee2aaSAndroid Build Coastguard Worker return fGpu->caps();
67*c8dee2aaSAndroid Build Coastguard Worker }
68*c8dee2aaSAndroid Build Coastguard Worker
finalizeFragmentSecondaryColor(GrShaderVar & outputColor)69*c8dee2aaSAndroid Build Coastguard Worker void GrD3DPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
70*c8dee2aaSAndroid Build Coastguard Worker outputColor.addLayoutQualifier("location = 0, index = 1");
71*c8dee2aaSAndroid Build Coastguard Worker }
72*c8dee2aaSAndroid Build Coastguard Worker
GrCompileHLSLShader(GrD3DGpu * gpu,const std::string & hlsl,SkSL::ProgramKind kind)73*c8dee2aaSAndroid Build Coastguard Worker static gr_cp<ID3DBlob> GrCompileHLSLShader(GrD3DGpu* gpu,
74*c8dee2aaSAndroid Build Coastguard Worker const std::string& hlsl,
75*c8dee2aaSAndroid Build Coastguard Worker SkSL::ProgramKind kind) {
76*c8dee2aaSAndroid Build Coastguard Worker TRACE_EVENT0("skia.shaders", "driver_compile_shader");
77*c8dee2aaSAndroid Build Coastguard Worker const char* compileTarget = nullptr;
78*c8dee2aaSAndroid Build Coastguard Worker switch (kind) {
79*c8dee2aaSAndroid Build Coastguard Worker case SkSL::ProgramKind::kVertex:
80*c8dee2aaSAndroid Build Coastguard Worker compileTarget = "vs_5_1";
81*c8dee2aaSAndroid Build Coastguard Worker break;
82*c8dee2aaSAndroid Build Coastguard Worker case SkSL::ProgramKind::kFragment:
83*c8dee2aaSAndroid Build Coastguard Worker compileTarget = "ps_5_1";
84*c8dee2aaSAndroid Build Coastguard Worker break;
85*c8dee2aaSAndroid Build Coastguard Worker default:
86*c8dee2aaSAndroid Build Coastguard Worker SkUNREACHABLE;
87*c8dee2aaSAndroid Build Coastguard Worker }
88*c8dee2aaSAndroid Build Coastguard Worker
89*c8dee2aaSAndroid Build Coastguard Worker uint32_t compileFlags = 0;
90*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
91*c8dee2aaSAndroid Build Coastguard Worker // Enable better shader debugging with the graphics debugging tools.
92*c8dee2aaSAndroid Build Coastguard Worker compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
93*c8dee2aaSAndroid Build Coastguard Worker #endif
94*c8dee2aaSAndroid Build Coastguard Worker // SPRIV-cross does matrix multiplication expecting row major matrices
95*c8dee2aaSAndroid Build Coastguard Worker compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
96*c8dee2aaSAndroid Build Coastguard Worker
97*c8dee2aaSAndroid Build Coastguard Worker gr_cp<ID3DBlob> shader;
98*c8dee2aaSAndroid Build Coastguard Worker gr_cp<ID3DBlob> errors;
99*c8dee2aaSAndroid Build Coastguard Worker HRESULT hr = D3DCompile(hlsl.c_str(), hlsl.length(), nullptr, nullptr, nullptr, "main",
100*c8dee2aaSAndroid Build Coastguard Worker compileTarget, compileFlags, 0, &shader, &errors);
101*c8dee2aaSAndroid Build Coastguard Worker if (!SUCCEEDED(hr)) {
102*c8dee2aaSAndroid Build Coastguard Worker gpu->getContext()->priv().getShaderErrorHandler()->compileError(
103*c8dee2aaSAndroid Build Coastguard Worker hlsl.c_str(), reinterpret_cast<char*>(errors->GetBufferPointer()));
104*c8dee2aaSAndroid Build Coastguard Worker }
105*c8dee2aaSAndroid Build Coastguard Worker return shader;
106*c8dee2aaSAndroid Build Coastguard Worker }
107*c8dee2aaSAndroid Build Coastguard Worker
loadHLSLFromCache(SkReadBuffer * reader,gr_cp<ID3DBlob> shaders[])108*c8dee2aaSAndroid Build Coastguard Worker bool GrD3DPipelineStateBuilder::loadHLSLFromCache(SkReadBuffer* reader, gr_cp<ID3DBlob> shaders[]) {
109*c8dee2aaSAndroid Build Coastguard Worker
110*c8dee2aaSAndroid Build Coastguard Worker std::string hlsl[kGrShaderTypeCount];
111*c8dee2aaSAndroid Build Coastguard Worker SkSL::Program::Interface intfs[kGrShaderTypeCount];
112*c8dee2aaSAndroid Build Coastguard Worker
113*c8dee2aaSAndroid Build Coastguard Worker if (!GrPersistentCacheUtils::UnpackCachedShaders(reader, hlsl, intfs, kGrShaderTypeCount)) {
114*c8dee2aaSAndroid Build Coastguard Worker return false;
115*c8dee2aaSAndroid Build Coastguard Worker }
116*c8dee2aaSAndroid Build Coastguard Worker
117*c8dee2aaSAndroid Build Coastguard Worker auto compile = [&](SkSL::ProgramKind kind, GrShaderType shaderType) {
118*c8dee2aaSAndroid Build Coastguard Worker if (intfs[shaderType].fRTFlipUniform != SkSL::Program::Interface::kRTFlip_None) {
119*c8dee2aaSAndroid Build Coastguard Worker this->addRTFlipUniform(SKSL_RTFLIP_NAME);
120*c8dee2aaSAndroid Build Coastguard Worker }
121*c8dee2aaSAndroid Build Coastguard Worker shaders[shaderType] = GrCompileHLSLShader(fGpu, hlsl[shaderType], kind);
122*c8dee2aaSAndroid Build Coastguard Worker return shaders[shaderType].get();
123*c8dee2aaSAndroid Build Coastguard Worker };
124*c8dee2aaSAndroid Build Coastguard Worker
125*c8dee2aaSAndroid Build Coastguard Worker return compile(SkSL::ProgramKind::kVertex, kVertex_GrShaderType) &&
126*c8dee2aaSAndroid Build Coastguard Worker compile(SkSL::ProgramKind::kFragment, kFragment_GrShaderType);
127*c8dee2aaSAndroid Build Coastguard Worker }
128*c8dee2aaSAndroid Build Coastguard Worker
compileD3DProgram(SkSL::ProgramKind kind,const std::string & sksl,const SkSL::ProgramSettings & settings,SkSL::Program::Interface * outInterface,std::string * outHLSL)129*c8dee2aaSAndroid Build Coastguard Worker gr_cp<ID3DBlob> GrD3DPipelineStateBuilder::compileD3DProgram(SkSL::ProgramKind kind,
130*c8dee2aaSAndroid Build Coastguard Worker const std::string& sksl,
131*c8dee2aaSAndroid Build Coastguard Worker const SkSL::ProgramSettings& settings,
132*c8dee2aaSAndroid Build Coastguard Worker SkSL::Program::Interface* outInterface,
133*c8dee2aaSAndroid Build Coastguard Worker std::string* outHLSL) {
134*c8dee2aaSAndroid Build Coastguard Worker if (!skgpu::SkSLToHLSL(this->caps()->shaderCaps(),
135*c8dee2aaSAndroid Build Coastguard Worker sksl,
136*c8dee2aaSAndroid Build Coastguard Worker kind,
137*c8dee2aaSAndroid Build Coastguard Worker settings,
138*c8dee2aaSAndroid Build Coastguard Worker outHLSL,
139*c8dee2aaSAndroid Build Coastguard Worker outInterface,
140*c8dee2aaSAndroid Build Coastguard Worker fGpu->getContext()->priv().getShaderErrorHandler())) {
141*c8dee2aaSAndroid Build Coastguard Worker return gr_cp<ID3DBlob>();
142*c8dee2aaSAndroid Build Coastguard Worker }
143*c8dee2aaSAndroid Build Coastguard Worker
144*c8dee2aaSAndroid Build Coastguard Worker if (outInterface->fRTFlipUniform != SkSL::Program::Interface::kRTFlip_None) {
145*c8dee2aaSAndroid Build Coastguard Worker this->addRTFlipUniform(SKSL_RTFLIP_NAME);
146*c8dee2aaSAndroid Build Coastguard Worker }
147*c8dee2aaSAndroid Build Coastguard Worker
148*c8dee2aaSAndroid Build Coastguard Worker return GrCompileHLSLShader(fGpu, *outHLSL, kind);
149*c8dee2aaSAndroid Build Coastguard Worker }
150*c8dee2aaSAndroid Build Coastguard Worker
attrib_type_to_format(GrVertexAttribType type)151*c8dee2aaSAndroid Build Coastguard Worker static DXGI_FORMAT attrib_type_to_format(GrVertexAttribType type) {
152*c8dee2aaSAndroid Build Coastguard Worker switch (type) {
153*c8dee2aaSAndroid Build Coastguard Worker case kFloat_GrVertexAttribType:
154*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R32_FLOAT;
155*c8dee2aaSAndroid Build Coastguard Worker case kFloat2_GrVertexAttribType:
156*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R32G32_FLOAT;
157*c8dee2aaSAndroid Build Coastguard Worker case kFloat3_GrVertexAttribType:
158*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R32G32B32_FLOAT;
159*c8dee2aaSAndroid Build Coastguard Worker case kFloat4_GrVertexAttribType:
160*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R32G32B32A32_FLOAT;
161*c8dee2aaSAndroid Build Coastguard Worker case kHalf_GrVertexAttribType:
162*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R16_FLOAT;
163*c8dee2aaSAndroid Build Coastguard Worker case kHalf2_GrVertexAttribType:
164*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R16G16_FLOAT;
165*c8dee2aaSAndroid Build Coastguard Worker case kHalf4_GrVertexAttribType:
166*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R16G16B16A16_FLOAT;
167*c8dee2aaSAndroid Build Coastguard Worker case kInt2_GrVertexAttribType:
168*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R32G32_SINT;
169*c8dee2aaSAndroid Build Coastguard Worker case kInt3_GrVertexAttribType:
170*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R32G32B32_SINT;
171*c8dee2aaSAndroid Build Coastguard Worker case kInt4_GrVertexAttribType:
172*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R32G32B32A32_SINT;
173*c8dee2aaSAndroid Build Coastguard Worker case kByte_GrVertexAttribType:
174*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R8_SINT;
175*c8dee2aaSAndroid Build Coastguard Worker case kByte2_GrVertexAttribType:
176*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R8G8_SINT;
177*c8dee2aaSAndroid Build Coastguard Worker case kByte4_GrVertexAttribType:
178*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R8G8B8A8_SINT;
179*c8dee2aaSAndroid Build Coastguard Worker case kUByte_GrVertexAttribType:
180*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R8_UINT;
181*c8dee2aaSAndroid Build Coastguard Worker case kUByte2_GrVertexAttribType:
182*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R8G8_UINT;
183*c8dee2aaSAndroid Build Coastguard Worker case kUByte4_GrVertexAttribType:
184*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R8G8B8A8_UINT;
185*c8dee2aaSAndroid Build Coastguard Worker case kUByte_norm_GrVertexAttribType:
186*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R8_UNORM;
187*c8dee2aaSAndroid Build Coastguard Worker case kUByte4_norm_GrVertexAttribType:
188*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R8G8B8A8_UNORM;
189*c8dee2aaSAndroid Build Coastguard Worker case kShort2_GrVertexAttribType:
190*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R16G16_SINT;
191*c8dee2aaSAndroid Build Coastguard Worker case kShort4_GrVertexAttribType:
192*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R16G16B16A16_SINT;
193*c8dee2aaSAndroid Build Coastguard Worker case kUShort2_GrVertexAttribType:
194*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R16G16_UINT;
195*c8dee2aaSAndroid Build Coastguard Worker case kUShort2_norm_GrVertexAttribType:
196*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R16G16_UNORM;
197*c8dee2aaSAndroid Build Coastguard Worker case kInt_GrVertexAttribType:
198*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R32_SINT;
199*c8dee2aaSAndroid Build Coastguard Worker case kUInt_GrVertexAttribType:
200*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R32_UINT;
201*c8dee2aaSAndroid Build Coastguard Worker case kUShort_norm_GrVertexAttribType:
202*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R16_UNORM;
203*c8dee2aaSAndroid Build Coastguard Worker case kUShort4_norm_GrVertexAttribType:
204*c8dee2aaSAndroid Build Coastguard Worker return DXGI_FORMAT_R16G16B16A16_UNORM;
205*c8dee2aaSAndroid Build Coastguard Worker }
206*c8dee2aaSAndroid Build Coastguard Worker SK_ABORT("Unknown vertex attrib type");
207*c8dee2aaSAndroid Build Coastguard Worker }
208*c8dee2aaSAndroid Build Coastguard Worker
setup_vertex_input_layout(const GrGeometryProcessor & geomProc,D3D12_INPUT_ELEMENT_DESC * inputElements)209*c8dee2aaSAndroid Build Coastguard Worker static void setup_vertex_input_layout(const GrGeometryProcessor& geomProc,
210*c8dee2aaSAndroid Build Coastguard Worker D3D12_INPUT_ELEMENT_DESC* inputElements) {
211*c8dee2aaSAndroid Build Coastguard Worker unsigned int slotNumber = 0;
212*c8dee2aaSAndroid Build Coastguard Worker unsigned int vertexSlot = 0;
213*c8dee2aaSAndroid Build Coastguard Worker unsigned int instanceSlot = 0;
214*c8dee2aaSAndroid Build Coastguard Worker if (geomProc.hasVertexAttributes()) {
215*c8dee2aaSAndroid Build Coastguard Worker vertexSlot = slotNumber++;
216*c8dee2aaSAndroid Build Coastguard Worker }
217*c8dee2aaSAndroid Build Coastguard Worker if (geomProc.hasInstanceAttributes()) {
218*c8dee2aaSAndroid Build Coastguard Worker instanceSlot = slotNumber++;
219*c8dee2aaSAndroid Build Coastguard Worker }
220*c8dee2aaSAndroid Build Coastguard Worker
221*c8dee2aaSAndroid Build Coastguard Worker unsigned int currentAttrib = 0;
222*c8dee2aaSAndroid Build Coastguard Worker
223*c8dee2aaSAndroid Build Coastguard Worker for (auto attrib : geomProc.vertexAttributes()) {
224*c8dee2aaSAndroid Build Coastguard Worker // When using SPIRV-Cross it converts the location modifier in SPIRV to be
225*c8dee2aaSAndroid Build Coastguard Worker // TEXCOORD<N> where N is the location value for eveery vertext attribute
226*c8dee2aaSAndroid Build Coastguard Worker inputElements[currentAttrib] = { "TEXCOORD", currentAttrib,
227*c8dee2aaSAndroid Build Coastguard Worker attrib_type_to_format(attrib.cpuType()),
228*c8dee2aaSAndroid Build Coastguard Worker vertexSlot, SkToU32(*attrib.offset()),
229*c8dee2aaSAndroid Build Coastguard Worker D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 };
230*c8dee2aaSAndroid Build Coastguard Worker currentAttrib++;
231*c8dee2aaSAndroid Build Coastguard Worker }
232*c8dee2aaSAndroid Build Coastguard Worker
233*c8dee2aaSAndroid Build Coastguard Worker for (auto attrib : geomProc.instanceAttributes()) {
234*c8dee2aaSAndroid Build Coastguard Worker // When using SPIRV-Cross it converts the location modifier in SPIRV to be
235*c8dee2aaSAndroid Build Coastguard Worker // TEXCOORD<N> where N is the location value for eveery vertext attribute
236*c8dee2aaSAndroid Build Coastguard Worker inputElements[currentAttrib] = { "TEXCOORD", currentAttrib,
237*c8dee2aaSAndroid Build Coastguard Worker attrib_type_to_format(attrib.cpuType()),
238*c8dee2aaSAndroid Build Coastguard Worker instanceSlot, SkToU32(*attrib.offset()),
239*c8dee2aaSAndroid Build Coastguard Worker D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1 };
240*c8dee2aaSAndroid Build Coastguard Worker currentAttrib++;
241*c8dee2aaSAndroid Build Coastguard Worker }
242*c8dee2aaSAndroid Build Coastguard Worker }
243*c8dee2aaSAndroid Build Coastguard Worker
blend_coeff_to_d3d_blend(skgpu::BlendCoeff coeff)244*c8dee2aaSAndroid Build Coastguard Worker static D3D12_BLEND blend_coeff_to_d3d_blend(skgpu::BlendCoeff coeff) {
245*c8dee2aaSAndroid Build Coastguard Worker switch (coeff) {
246*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kZero:
247*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_ZERO;
248*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kOne:
249*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_ONE;
250*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kSC:
251*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_SRC_COLOR;
252*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kISC:
253*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_INV_SRC_COLOR;
254*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kDC:
255*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_DEST_COLOR;
256*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kIDC:
257*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_INV_DEST_COLOR;
258*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kSA:
259*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_SRC_ALPHA;
260*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kISA:
261*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_INV_SRC_ALPHA;
262*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kDA:
263*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_DEST_ALPHA;
264*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kIDA:
265*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_INV_DEST_ALPHA;
266*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kConstC:
267*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_BLEND_FACTOR;
268*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kIConstC:
269*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_INV_BLEND_FACTOR;
270*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kS2C:
271*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_SRC1_COLOR;
272*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kIS2C:
273*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_INV_SRC1_COLOR;
274*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kS2A:
275*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_SRC1_ALPHA;
276*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kIS2A:
277*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_INV_SRC1_ALPHA;
278*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kIllegal:
279*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_ZERO;
280*c8dee2aaSAndroid Build Coastguard Worker }
281*c8dee2aaSAndroid Build Coastguard Worker SkUNREACHABLE;
282*c8dee2aaSAndroid Build Coastguard Worker }
283*c8dee2aaSAndroid Build Coastguard Worker
blend_coeff_to_d3d_blend_for_alpha(skgpu::BlendCoeff coeff)284*c8dee2aaSAndroid Build Coastguard Worker static D3D12_BLEND blend_coeff_to_d3d_blend_for_alpha(skgpu::BlendCoeff coeff) {
285*c8dee2aaSAndroid Build Coastguard Worker switch (coeff) {
286*c8dee2aaSAndroid Build Coastguard Worker // Force all srcColor used in alpha slot to alpha version.
287*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kSC:
288*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_SRC_ALPHA;
289*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kISC:
290*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_INV_SRC_ALPHA;
291*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kDC:
292*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_DEST_ALPHA;
293*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kIDC:
294*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_INV_DEST_ALPHA;
295*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kS2C:
296*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_SRC1_ALPHA;
297*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendCoeff::kIS2C:
298*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_INV_SRC1_ALPHA;
299*c8dee2aaSAndroid Build Coastguard Worker
300*c8dee2aaSAndroid Build Coastguard Worker default:
301*c8dee2aaSAndroid Build Coastguard Worker return blend_coeff_to_d3d_blend(coeff);
302*c8dee2aaSAndroid Build Coastguard Worker }
303*c8dee2aaSAndroid Build Coastguard Worker }
304*c8dee2aaSAndroid Build Coastguard Worker
305*c8dee2aaSAndroid Build Coastguard Worker
blend_equation_to_d3d_op(skgpu::BlendEquation equation)306*c8dee2aaSAndroid Build Coastguard Worker static D3D12_BLEND_OP blend_equation_to_d3d_op(skgpu::BlendEquation equation) {
307*c8dee2aaSAndroid Build Coastguard Worker switch (equation) {
308*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendEquation::kAdd:
309*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_OP_ADD;
310*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendEquation::kSubtract:
311*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_OP_SUBTRACT;
312*c8dee2aaSAndroid Build Coastguard Worker case skgpu::BlendEquation::kReverseSubtract:
313*c8dee2aaSAndroid Build Coastguard Worker return D3D12_BLEND_OP_REV_SUBTRACT;
314*c8dee2aaSAndroid Build Coastguard Worker default:
315*c8dee2aaSAndroid Build Coastguard Worker SkUNREACHABLE;
316*c8dee2aaSAndroid Build Coastguard Worker }
317*c8dee2aaSAndroid Build Coastguard Worker }
318*c8dee2aaSAndroid Build Coastguard Worker
fill_in_blend_state(const GrPipeline & pipeline,D3D12_BLEND_DESC * blendDesc)319*c8dee2aaSAndroid Build Coastguard Worker static void fill_in_blend_state(const GrPipeline& pipeline, D3D12_BLEND_DESC* blendDesc) {
320*c8dee2aaSAndroid Build Coastguard Worker blendDesc->AlphaToCoverageEnable = false;
321*c8dee2aaSAndroid Build Coastguard Worker blendDesc->IndependentBlendEnable = false;
322*c8dee2aaSAndroid Build Coastguard Worker
323*c8dee2aaSAndroid Build Coastguard Worker const skgpu::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
324*c8dee2aaSAndroid Build Coastguard Worker
325*c8dee2aaSAndroid Build Coastguard Worker skgpu::BlendEquation equation = blendInfo.fEquation;
326*c8dee2aaSAndroid Build Coastguard Worker skgpu::BlendCoeff srcCoeff = blendInfo.fSrcBlend;
327*c8dee2aaSAndroid Build Coastguard Worker skgpu::BlendCoeff dstCoeff = blendInfo.fDstBlend;
328*c8dee2aaSAndroid Build Coastguard Worker bool blendOff = skgpu::BlendShouldDisable(equation, srcCoeff, dstCoeff);
329*c8dee2aaSAndroid Build Coastguard Worker
330*c8dee2aaSAndroid Build Coastguard Worker auto& rtBlend = blendDesc->RenderTarget[0];
331*c8dee2aaSAndroid Build Coastguard Worker rtBlend.BlendEnable = !blendOff;
332*c8dee2aaSAndroid Build Coastguard Worker if (!blendOff) {
333*c8dee2aaSAndroid Build Coastguard Worker rtBlend.SrcBlend = blend_coeff_to_d3d_blend(srcCoeff);
334*c8dee2aaSAndroid Build Coastguard Worker rtBlend.DestBlend = blend_coeff_to_d3d_blend(dstCoeff);
335*c8dee2aaSAndroid Build Coastguard Worker rtBlend.BlendOp = blend_equation_to_d3d_op(equation);
336*c8dee2aaSAndroid Build Coastguard Worker rtBlend.SrcBlendAlpha = blend_coeff_to_d3d_blend_for_alpha(srcCoeff);
337*c8dee2aaSAndroid Build Coastguard Worker rtBlend.DestBlendAlpha = blend_coeff_to_d3d_blend_for_alpha(dstCoeff);
338*c8dee2aaSAndroid Build Coastguard Worker rtBlend.BlendOpAlpha = blend_equation_to_d3d_op(equation);
339*c8dee2aaSAndroid Build Coastguard Worker }
340*c8dee2aaSAndroid Build Coastguard Worker
341*c8dee2aaSAndroid Build Coastguard Worker if (!blendInfo.fWritesColor) {
342*c8dee2aaSAndroid Build Coastguard Worker rtBlend.RenderTargetWriteMask = 0;
343*c8dee2aaSAndroid Build Coastguard Worker } else {
344*c8dee2aaSAndroid Build Coastguard Worker rtBlend.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
345*c8dee2aaSAndroid Build Coastguard Worker }
346*c8dee2aaSAndroid Build Coastguard Worker }
347*c8dee2aaSAndroid Build Coastguard Worker
fill_in_rasterizer_state(const GrPipeline & pipeline,bool multisampleEnable,const GrCaps * caps,D3D12_RASTERIZER_DESC * rasterizer)348*c8dee2aaSAndroid Build Coastguard Worker static void fill_in_rasterizer_state(const GrPipeline& pipeline,
349*c8dee2aaSAndroid Build Coastguard Worker bool multisampleEnable,
350*c8dee2aaSAndroid Build Coastguard Worker const GrCaps* caps,
351*c8dee2aaSAndroid Build Coastguard Worker D3D12_RASTERIZER_DESC* rasterizer) {
352*c8dee2aaSAndroid Build Coastguard Worker rasterizer->FillMode = (caps->wireframeMode() || pipeline.isWireframe()) ?
353*c8dee2aaSAndroid Build Coastguard Worker D3D12_FILL_MODE_WIREFRAME : D3D12_FILL_MODE_SOLID;
354*c8dee2aaSAndroid Build Coastguard Worker rasterizer->CullMode = D3D12_CULL_MODE_NONE;
355*c8dee2aaSAndroid Build Coastguard Worker rasterizer->FrontCounterClockwise = true;
356*c8dee2aaSAndroid Build Coastguard Worker rasterizer->DepthBias = 0;
357*c8dee2aaSAndroid Build Coastguard Worker rasterizer->DepthBiasClamp = 0.0f;
358*c8dee2aaSAndroid Build Coastguard Worker rasterizer->SlopeScaledDepthBias = 0.0f;
359*c8dee2aaSAndroid Build Coastguard Worker rasterizer->DepthClipEnable = false;
360*c8dee2aaSAndroid Build Coastguard Worker rasterizer->MultisampleEnable = multisampleEnable;
361*c8dee2aaSAndroid Build Coastguard Worker rasterizer->AntialiasedLineEnable = false;
362*c8dee2aaSAndroid Build Coastguard Worker rasterizer->ForcedSampleCount = 0;
363*c8dee2aaSAndroid Build Coastguard Worker rasterizer->ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
364*c8dee2aaSAndroid Build Coastguard Worker }
365*c8dee2aaSAndroid Build Coastguard Worker
stencil_op_to_d3d_op(GrStencilOp op)366*c8dee2aaSAndroid Build Coastguard Worker static D3D12_STENCIL_OP stencil_op_to_d3d_op(GrStencilOp op) {
367*c8dee2aaSAndroid Build Coastguard Worker switch (op) {
368*c8dee2aaSAndroid Build Coastguard Worker case GrStencilOp::kKeep:
369*c8dee2aaSAndroid Build Coastguard Worker return D3D12_STENCIL_OP_KEEP;
370*c8dee2aaSAndroid Build Coastguard Worker case GrStencilOp::kZero:
371*c8dee2aaSAndroid Build Coastguard Worker return D3D12_STENCIL_OP_ZERO;
372*c8dee2aaSAndroid Build Coastguard Worker case GrStencilOp::kReplace:
373*c8dee2aaSAndroid Build Coastguard Worker return D3D12_STENCIL_OP_REPLACE;
374*c8dee2aaSAndroid Build Coastguard Worker case GrStencilOp::kInvert:
375*c8dee2aaSAndroid Build Coastguard Worker return D3D12_STENCIL_OP_INVERT;
376*c8dee2aaSAndroid Build Coastguard Worker case GrStencilOp::kIncWrap:
377*c8dee2aaSAndroid Build Coastguard Worker return D3D12_STENCIL_OP_INCR;
378*c8dee2aaSAndroid Build Coastguard Worker case GrStencilOp::kDecWrap:
379*c8dee2aaSAndroid Build Coastguard Worker return D3D12_STENCIL_OP_DECR;
380*c8dee2aaSAndroid Build Coastguard Worker case GrStencilOp::kIncClamp:
381*c8dee2aaSAndroid Build Coastguard Worker return D3D12_STENCIL_OP_INCR_SAT;
382*c8dee2aaSAndroid Build Coastguard Worker case GrStencilOp::kDecClamp:
383*c8dee2aaSAndroid Build Coastguard Worker return D3D12_STENCIL_OP_DECR_SAT;
384*c8dee2aaSAndroid Build Coastguard Worker }
385*c8dee2aaSAndroid Build Coastguard Worker SkUNREACHABLE;
386*c8dee2aaSAndroid Build Coastguard Worker }
387*c8dee2aaSAndroid Build Coastguard Worker
stencil_test_to_d3d_func(GrStencilTest test)388*c8dee2aaSAndroid Build Coastguard Worker static D3D12_COMPARISON_FUNC stencil_test_to_d3d_func(GrStencilTest test) {
389*c8dee2aaSAndroid Build Coastguard Worker switch (test) {
390*c8dee2aaSAndroid Build Coastguard Worker case GrStencilTest::kAlways:
391*c8dee2aaSAndroid Build Coastguard Worker return D3D12_COMPARISON_FUNC_ALWAYS;
392*c8dee2aaSAndroid Build Coastguard Worker case GrStencilTest::kNever:
393*c8dee2aaSAndroid Build Coastguard Worker return D3D12_COMPARISON_FUNC_NEVER;
394*c8dee2aaSAndroid Build Coastguard Worker case GrStencilTest::kGreater:
395*c8dee2aaSAndroid Build Coastguard Worker return D3D12_COMPARISON_FUNC_GREATER;
396*c8dee2aaSAndroid Build Coastguard Worker case GrStencilTest::kGEqual:
397*c8dee2aaSAndroid Build Coastguard Worker return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
398*c8dee2aaSAndroid Build Coastguard Worker case GrStencilTest::kLess:
399*c8dee2aaSAndroid Build Coastguard Worker return D3D12_COMPARISON_FUNC_LESS;
400*c8dee2aaSAndroid Build Coastguard Worker case GrStencilTest::kLEqual:
401*c8dee2aaSAndroid Build Coastguard Worker return D3D12_COMPARISON_FUNC_LESS_EQUAL;
402*c8dee2aaSAndroid Build Coastguard Worker case GrStencilTest::kEqual:
403*c8dee2aaSAndroid Build Coastguard Worker return D3D12_COMPARISON_FUNC_EQUAL;
404*c8dee2aaSAndroid Build Coastguard Worker case GrStencilTest::kNotEqual:
405*c8dee2aaSAndroid Build Coastguard Worker return D3D12_COMPARISON_FUNC_NOT_EQUAL;
406*c8dee2aaSAndroid Build Coastguard Worker }
407*c8dee2aaSAndroid Build Coastguard Worker SkUNREACHABLE;
408*c8dee2aaSAndroid Build Coastguard Worker }
409*c8dee2aaSAndroid Build Coastguard Worker
setup_stencilop_desc(D3D12_DEPTH_STENCILOP_DESC * desc,const GrStencilSettings::Face & stencilFace)410*c8dee2aaSAndroid Build Coastguard Worker static void setup_stencilop_desc(D3D12_DEPTH_STENCILOP_DESC* desc,
411*c8dee2aaSAndroid Build Coastguard Worker const GrStencilSettings::Face& stencilFace) {
412*c8dee2aaSAndroid Build Coastguard Worker desc->StencilFailOp = stencil_op_to_d3d_op(stencilFace.fFailOp);
413*c8dee2aaSAndroid Build Coastguard Worker desc->StencilDepthFailOp = desc->StencilFailOp;
414*c8dee2aaSAndroid Build Coastguard Worker desc->StencilPassOp = stencil_op_to_d3d_op(stencilFace.fPassOp);
415*c8dee2aaSAndroid Build Coastguard Worker desc->StencilFunc = stencil_test_to_d3d_func(stencilFace.fTest);
416*c8dee2aaSAndroid Build Coastguard Worker }
417*c8dee2aaSAndroid Build Coastguard Worker
fill_in_depth_stencil_state(const GrProgramInfo & programInfo,D3D12_DEPTH_STENCIL_DESC * dsDesc)418*c8dee2aaSAndroid Build Coastguard Worker static void fill_in_depth_stencil_state(const GrProgramInfo& programInfo,
419*c8dee2aaSAndroid Build Coastguard Worker D3D12_DEPTH_STENCIL_DESC* dsDesc) {
420*c8dee2aaSAndroid Build Coastguard Worker GrStencilSettings stencilSettings = programInfo.nonGLStencilSettings();
421*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceOrigin origin = programInfo.origin();
422*c8dee2aaSAndroid Build Coastguard Worker
423*c8dee2aaSAndroid Build Coastguard Worker dsDesc->DepthEnable = false;
424*c8dee2aaSAndroid Build Coastguard Worker dsDesc->DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
425*c8dee2aaSAndroid Build Coastguard Worker dsDesc->DepthFunc = D3D12_COMPARISON_FUNC_NEVER;
426*c8dee2aaSAndroid Build Coastguard Worker dsDesc->StencilEnable = !stencilSettings.isDisabled();
427*c8dee2aaSAndroid Build Coastguard Worker if (!stencilSettings.isDisabled()) {
428*c8dee2aaSAndroid Build Coastguard Worker if (stencilSettings.isTwoSided()) {
429*c8dee2aaSAndroid Build Coastguard Worker const auto& frontFace = stencilSettings.postOriginCCWFace(origin);
430*c8dee2aaSAndroid Build Coastguard Worker const auto& backFace = stencilSettings.postOriginCWFace(origin);
431*c8dee2aaSAndroid Build Coastguard Worker
432*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(frontFace.fTestMask == backFace.fTestMask);
433*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(frontFace.fWriteMask == backFace.fWriteMask);
434*c8dee2aaSAndroid Build Coastguard Worker dsDesc->StencilReadMask = frontFace.fTestMask;
435*c8dee2aaSAndroid Build Coastguard Worker dsDesc->StencilWriteMask = frontFace.fWriteMask;
436*c8dee2aaSAndroid Build Coastguard Worker
437*c8dee2aaSAndroid Build Coastguard Worker setup_stencilop_desc(&dsDesc->FrontFace, frontFace);
438*c8dee2aaSAndroid Build Coastguard Worker setup_stencilop_desc(&dsDesc->BackFace, backFace);
439*c8dee2aaSAndroid Build Coastguard Worker } else {
440*c8dee2aaSAndroid Build Coastguard Worker dsDesc->StencilReadMask = stencilSettings.singleSidedFace().fTestMask;
441*c8dee2aaSAndroid Build Coastguard Worker dsDesc->StencilWriteMask = stencilSettings.singleSidedFace().fWriteMask;
442*c8dee2aaSAndroid Build Coastguard Worker setup_stencilop_desc(&dsDesc->FrontFace, stencilSettings.singleSidedFace());
443*c8dee2aaSAndroid Build Coastguard Worker dsDesc->BackFace = dsDesc->FrontFace;
444*c8dee2aaSAndroid Build Coastguard Worker }
445*c8dee2aaSAndroid Build Coastguard Worker }
446*c8dee2aaSAndroid Build Coastguard Worker }
447*c8dee2aaSAndroid Build Coastguard Worker
gr_primitive_type_to_d3d(GrPrimitiveType primitiveType)448*c8dee2aaSAndroid Build Coastguard Worker static D3D12_PRIMITIVE_TOPOLOGY_TYPE gr_primitive_type_to_d3d(GrPrimitiveType primitiveType) {
449*c8dee2aaSAndroid Build Coastguard Worker switch (primitiveType) {
450*c8dee2aaSAndroid Build Coastguard Worker case GrPrimitiveType::kTriangles:
451*c8dee2aaSAndroid Build Coastguard Worker case GrPrimitiveType::kTriangleStrip: //fall through
452*c8dee2aaSAndroid Build Coastguard Worker return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
453*c8dee2aaSAndroid Build Coastguard Worker case GrPrimitiveType::kPoints:
454*c8dee2aaSAndroid Build Coastguard Worker return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
455*c8dee2aaSAndroid Build Coastguard Worker case GrPrimitiveType::kLines: // fall through
456*c8dee2aaSAndroid Build Coastguard Worker case GrPrimitiveType::kLineStrip:
457*c8dee2aaSAndroid Build Coastguard Worker return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
458*c8dee2aaSAndroid Build Coastguard Worker default:
459*c8dee2aaSAndroid Build Coastguard Worker SkUNREACHABLE;
460*c8dee2aaSAndroid Build Coastguard Worker }
461*c8dee2aaSAndroid Build Coastguard Worker }
462*c8dee2aaSAndroid Build Coastguard Worker
create_pipeline_state(GrD3DGpu * gpu,const GrProgramInfo & programInfo,const sk_sp<GrD3DRootSignature> & rootSig,gr_cp<ID3DBlob> vertexShader,gr_cp<ID3DBlob> pixelShader,DXGI_FORMAT renderTargetFormat,DXGI_FORMAT depthStencilFormat,unsigned int sampleQualityPattern)463*c8dee2aaSAndroid Build Coastguard Worker gr_cp<ID3D12PipelineState> create_pipeline_state(
464*c8dee2aaSAndroid Build Coastguard Worker GrD3DGpu* gpu, const GrProgramInfo& programInfo, const sk_sp<GrD3DRootSignature>& rootSig,
465*c8dee2aaSAndroid Build Coastguard Worker gr_cp<ID3DBlob> vertexShader, gr_cp<ID3DBlob> pixelShader,
466*c8dee2aaSAndroid Build Coastguard Worker DXGI_FORMAT renderTargetFormat, DXGI_FORMAT depthStencilFormat,
467*c8dee2aaSAndroid Build Coastguard Worker unsigned int sampleQualityPattern) {
468*c8dee2aaSAndroid Build Coastguard Worker D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
469*c8dee2aaSAndroid Build Coastguard Worker
470*c8dee2aaSAndroid Build Coastguard Worker psoDesc.pRootSignature = rootSig->rootSignature();
471*c8dee2aaSAndroid Build Coastguard Worker
472*c8dee2aaSAndroid Build Coastguard Worker psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()),
473*c8dee2aaSAndroid Build Coastguard Worker vertexShader->GetBufferSize() };
474*c8dee2aaSAndroid Build Coastguard Worker psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()),
475*c8dee2aaSAndroid Build Coastguard Worker pixelShader->GetBufferSize() };
476*c8dee2aaSAndroid Build Coastguard Worker
477*c8dee2aaSAndroid Build Coastguard Worker psoDesc.StreamOutput = { nullptr, 0, nullptr, 0, 0 };
478*c8dee2aaSAndroid Build Coastguard Worker
479*c8dee2aaSAndroid Build Coastguard Worker fill_in_blend_state(programInfo.pipeline(), &psoDesc.BlendState);
480*c8dee2aaSAndroid Build Coastguard Worker psoDesc.SampleMask = UINT_MAX;
481*c8dee2aaSAndroid Build Coastguard Worker
482*c8dee2aaSAndroid Build Coastguard Worker fill_in_rasterizer_state(programInfo.pipeline(), programInfo.numSamples() > 1, gpu->caps(),
483*c8dee2aaSAndroid Build Coastguard Worker &psoDesc.RasterizerState);
484*c8dee2aaSAndroid Build Coastguard Worker
485*c8dee2aaSAndroid Build Coastguard Worker fill_in_depth_stencil_state(programInfo, &psoDesc.DepthStencilState);
486*c8dee2aaSAndroid Build Coastguard Worker
487*c8dee2aaSAndroid Build Coastguard Worker unsigned int totalAttributeCnt = programInfo.geomProc().numVertexAttributes() +
488*c8dee2aaSAndroid Build Coastguard Worker programInfo.geomProc().numInstanceAttributes();
489*c8dee2aaSAndroid Build Coastguard Worker AutoSTArray<4, D3D12_INPUT_ELEMENT_DESC> inputElements(totalAttributeCnt);
490*c8dee2aaSAndroid Build Coastguard Worker setup_vertex_input_layout(programInfo.geomProc(), inputElements.get());
491*c8dee2aaSAndroid Build Coastguard Worker
492*c8dee2aaSAndroid Build Coastguard Worker psoDesc.InputLayout = { inputElements.get(), totalAttributeCnt };
493*c8dee2aaSAndroid Build Coastguard Worker
494*c8dee2aaSAndroid Build Coastguard Worker psoDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
495*c8dee2aaSAndroid Build Coastguard Worker
496*c8dee2aaSAndroid Build Coastguard Worker // This is for geometry or hull shader primitives
497*c8dee2aaSAndroid Build Coastguard Worker psoDesc.PrimitiveTopologyType = gr_primitive_type_to_d3d(programInfo.primitiveType());
498*c8dee2aaSAndroid Build Coastguard Worker
499*c8dee2aaSAndroid Build Coastguard Worker psoDesc.NumRenderTargets = 1;
500*c8dee2aaSAndroid Build Coastguard Worker
501*c8dee2aaSAndroid Build Coastguard Worker psoDesc.RTVFormats[0] = renderTargetFormat;
502*c8dee2aaSAndroid Build Coastguard Worker
503*c8dee2aaSAndroid Build Coastguard Worker psoDesc.DSVFormat = depthStencilFormat;
504*c8dee2aaSAndroid Build Coastguard Worker
505*c8dee2aaSAndroid Build Coastguard Worker unsigned int numSamples = programInfo.numSamples();
506*c8dee2aaSAndroid Build Coastguard Worker psoDesc.SampleDesc = { numSamples, sampleQualityPattern };
507*c8dee2aaSAndroid Build Coastguard Worker
508*c8dee2aaSAndroid Build Coastguard Worker // Only used for multi-adapter systems.
509*c8dee2aaSAndroid Build Coastguard Worker psoDesc.NodeMask = 0;
510*c8dee2aaSAndroid Build Coastguard Worker
511*c8dee2aaSAndroid Build Coastguard Worker psoDesc.CachedPSO = { nullptr, 0 };
512*c8dee2aaSAndroid Build Coastguard Worker psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
513*c8dee2aaSAndroid Build Coastguard Worker
514*c8dee2aaSAndroid Build Coastguard Worker gr_cp<ID3D12PipelineState> pipelineState;
515*c8dee2aaSAndroid Build Coastguard Worker {
516*c8dee2aaSAndroid Build Coastguard Worker TRACE_EVENT0("skia.shaders", "CreateGraphicsPipelineState");
517*c8dee2aaSAndroid Build Coastguard Worker GR_D3D_CALL_ERRCHECK(
518*c8dee2aaSAndroid Build Coastguard Worker gpu->device()->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState)));
519*c8dee2aaSAndroid Build Coastguard Worker }
520*c8dee2aaSAndroid Build Coastguard Worker
521*c8dee2aaSAndroid Build Coastguard Worker return pipelineState;
522*c8dee2aaSAndroid Build Coastguard Worker }
523*c8dee2aaSAndroid Build Coastguard Worker
524*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkFourByteTag kHLSL_Tag = SkSetFourByteTag('H', 'L', 'S', 'L');
525*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
526*c8dee2aaSAndroid Build Coastguard Worker
finalize()527*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrD3DPipelineState> GrD3DPipelineStateBuilder::finalize() {
528*c8dee2aaSAndroid Build Coastguard Worker TRACE_EVENT0("skia.shaders", TRACE_FUNC);
529*c8dee2aaSAndroid Build Coastguard Worker
530*c8dee2aaSAndroid Build Coastguard Worker this->finalizeShaders();
531*c8dee2aaSAndroid Build Coastguard Worker
532*c8dee2aaSAndroid Build Coastguard Worker SkSL::ProgramSettings settings;
533*c8dee2aaSAndroid Build Coastguard Worker settings.fSharpenTextures =
534*c8dee2aaSAndroid Build Coastguard Worker this->gpu()->getContext()->priv().options().fSharpenMipmappedTextures;
535*c8dee2aaSAndroid Build Coastguard Worker settings.fRTFlipOffset = fUniformHandler.getRTFlipOffset();
536*c8dee2aaSAndroid Build Coastguard Worker settings.fRTFlipBinding = 0;
537*c8dee2aaSAndroid Build Coastguard Worker settings.fRTFlipSet = 0;
538*c8dee2aaSAndroid Build Coastguard Worker
539*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> cached;
540*c8dee2aaSAndroid Build Coastguard Worker SkReadBuffer reader;
541*c8dee2aaSAndroid Build Coastguard Worker SkFourByteTag shaderType = 0;
542*c8dee2aaSAndroid Build Coastguard Worker auto persistentCache = fGpu->getContext()->priv().getPersistentCache();
543*c8dee2aaSAndroid Build Coastguard Worker if (persistentCache) {
544*c8dee2aaSAndroid Build Coastguard Worker // Shear off the D3D-specific portion of the Desc to get the persistent key. We only cache
545*c8dee2aaSAndroid Build Coastguard Worker // shader code, not entire pipelines.
546*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> key =
547*c8dee2aaSAndroid Build Coastguard Worker SkData::MakeWithoutCopy(this->desc().asKey(), this->desc().initialKeyLength());
548*c8dee2aaSAndroid Build Coastguard Worker cached = persistentCache->load(*key);
549*c8dee2aaSAndroid Build Coastguard Worker if (cached) {
550*c8dee2aaSAndroid Build Coastguard Worker reader.setMemory(cached->data(), cached->size());
551*c8dee2aaSAndroid Build Coastguard Worker shaderType = GrPersistentCacheUtils::GetType(&reader);
552*c8dee2aaSAndroid Build Coastguard Worker }
553*c8dee2aaSAndroid Build Coastguard Worker }
554*c8dee2aaSAndroid Build Coastguard Worker
555*c8dee2aaSAndroid Build Coastguard Worker const GrGeometryProcessor& geomProc = this->geometryProcessor();
556*c8dee2aaSAndroid Build Coastguard Worker gr_cp<ID3DBlob> shaders[kGrShaderTypeCount];
557*c8dee2aaSAndroid Build Coastguard Worker
558*c8dee2aaSAndroid Build Coastguard Worker if (kHLSL_Tag == shaderType && this->loadHLSLFromCache(&reader, shaders)) {
559*c8dee2aaSAndroid Build Coastguard Worker // We successfully loaded and compiled HLSL
560*c8dee2aaSAndroid Build Coastguard Worker } else {
561*c8dee2aaSAndroid Build Coastguard Worker SkSL::Program::Interface intfs[kGrShaderTypeCount];
562*c8dee2aaSAndroid Build Coastguard Worker std::string* sksl[kGrShaderTypeCount] = {
563*c8dee2aaSAndroid Build Coastguard Worker &fVS.fCompilerString,
564*c8dee2aaSAndroid Build Coastguard Worker &fFS.fCompilerString,
565*c8dee2aaSAndroid Build Coastguard Worker };
566*c8dee2aaSAndroid Build Coastguard Worker std::string cached_sksl[kGrShaderTypeCount];
567*c8dee2aaSAndroid Build Coastguard Worker std::string hlsl[kGrShaderTypeCount];
568*c8dee2aaSAndroid Build Coastguard Worker
569*c8dee2aaSAndroid Build Coastguard Worker if (kSKSL_Tag == shaderType) {
570*c8dee2aaSAndroid Build Coastguard Worker if (GrPersistentCacheUtils::UnpackCachedShaders(&reader, cached_sksl, intfs,
571*c8dee2aaSAndroid Build Coastguard Worker kGrShaderTypeCount)) {
572*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kGrShaderTypeCount; ++i) {
573*c8dee2aaSAndroid Build Coastguard Worker sksl[i] = &cached_sksl[i];
574*c8dee2aaSAndroid Build Coastguard Worker }
575*c8dee2aaSAndroid Build Coastguard Worker }
576*c8dee2aaSAndroid Build Coastguard Worker }
577*c8dee2aaSAndroid Build Coastguard Worker
578*c8dee2aaSAndroid Build Coastguard Worker auto compile = [&](SkSL::ProgramKind kind, GrShaderType shaderType) {
579*c8dee2aaSAndroid Build Coastguard Worker shaders[shaderType] = this->compileD3DProgram(
580*c8dee2aaSAndroid Build Coastguard Worker kind, *sksl[shaderType], settings, &intfs[shaderType], &hlsl[shaderType]);
581*c8dee2aaSAndroid Build Coastguard Worker return shaders[shaderType].get();
582*c8dee2aaSAndroid Build Coastguard Worker };
583*c8dee2aaSAndroid Build Coastguard Worker
584*c8dee2aaSAndroid Build Coastguard Worker if (!compile(SkSL::ProgramKind::kVertex, kVertex_GrShaderType) ||
585*c8dee2aaSAndroid Build Coastguard Worker !compile(SkSL::ProgramKind::kFragment, kFragment_GrShaderType)) {
586*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
587*c8dee2aaSAndroid Build Coastguard Worker }
588*c8dee2aaSAndroid Build Coastguard Worker
589*c8dee2aaSAndroid Build Coastguard Worker if (persistentCache && !cached) {
590*c8dee2aaSAndroid Build Coastguard Worker const bool cacheSkSL = fGpu->getContext()->priv().options().fShaderCacheStrategy ==
591*c8dee2aaSAndroid Build Coastguard Worker GrContextOptions::ShaderCacheStrategy::kSkSL;
592*c8dee2aaSAndroid Build Coastguard Worker if (cacheSkSL) {
593*c8dee2aaSAndroid Build Coastguard Worker // Replace the HLSL with formatted SkSL to be cached. This looks odd, but this is
594*c8dee2aaSAndroid Build Coastguard Worker // the last time we're going to use these strings, so it's safe.
595*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kGrShaderTypeCount; ++i) {
596*c8dee2aaSAndroid Build Coastguard Worker hlsl[i] = SkShaderUtils::PrettyPrint(*sksl[i]);
597*c8dee2aaSAndroid Build Coastguard Worker }
598*c8dee2aaSAndroid Build Coastguard Worker }
599*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> key =
600*c8dee2aaSAndroid Build Coastguard Worker SkData::MakeWithoutCopy(this->desc().asKey(), this->desc().initialKeyLength());
601*c8dee2aaSAndroid Build Coastguard Worker SkString description = GrProgramDesc::Describe(fProgramInfo, *this->caps());
602*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> data = GrPersistentCacheUtils::PackCachedShaders(
603*c8dee2aaSAndroid Build Coastguard Worker cacheSkSL ? kSKSL_Tag : kHLSL_Tag, hlsl, intfs, kGrShaderTypeCount);
604*c8dee2aaSAndroid Build Coastguard Worker persistentCache->store(*key, *data, description);
605*c8dee2aaSAndroid Build Coastguard Worker }
606*c8dee2aaSAndroid Build Coastguard Worker }
607*c8dee2aaSAndroid Build Coastguard Worker
608*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrD3DRootSignature> rootSig =
609*c8dee2aaSAndroid Build Coastguard Worker fGpu->resourceProvider().findOrCreateRootSignature(fUniformHandler.fSamplers.count());
610*c8dee2aaSAndroid Build Coastguard Worker if (!rootSig) {
611*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
612*c8dee2aaSAndroid Build Coastguard Worker }
613*c8dee2aaSAndroid Build Coastguard Worker
614*c8dee2aaSAndroid Build Coastguard Worker const GrD3DRenderTarget* rt = static_cast<const GrD3DRenderTarget*>(fRenderTarget);
615*c8dee2aaSAndroid Build Coastguard Worker gr_cp<ID3D12PipelineState> pipelineState = create_pipeline_state(
616*c8dee2aaSAndroid Build Coastguard Worker fGpu, fProgramInfo, rootSig, std::move(shaders[kVertex_GrShaderType]),
617*c8dee2aaSAndroid Build Coastguard Worker std::move(shaders[kFragment_GrShaderType]),
618*c8dee2aaSAndroid Build Coastguard Worker rt->dxgiFormat(), rt->stencilDxgiFormat(), rt->sampleQualityPattern());
619*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrD3DPipeline> pipeline = GrD3DPipeline::Make(std::move(pipelineState));
620*c8dee2aaSAndroid Build Coastguard Worker if (!pipeline) {
621*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
622*c8dee2aaSAndroid Build Coastguard Worker }
623*c8dee2aaSAndroid Build Coastguard Worker
624*c8dee2aaSAndroid Build Coastguard Worker return std::unique_ptr<GrD3DPipelineState>(
625*c8dee2aaSAndroid Build Coastguard Worker new GrD3DPipelineState(std::move(pipeline),
626*c8dee2aaSAndroid Build Coastguard Worker std::move(rootSig),
627*c8dee2aaSAndroid Build Coastguard Worker fUniformHandles,
628*c8dee2aaSAndroid Build Coastguard Worker fUniformHandler.fUniforms,
629*c8dee2aaSAndroid Build Coastguard Worker fUniformHandler.fCurrentUBOOffset,
630*c8dee2aaSAndroid Build Coastguard Worker fUniformHandler.fSamplers.count(),
631*c8dee2aaSAndroid Build Coastguard Worker std::move(fGPImpl),
632*c8dee2aaSAndroid Build Coastguard Worker std::move(fXPImpl),
633*c8dee2aaSAndroid Build Coastguard Worker std::move(fFPImpls),
634*c8dee2aaSAndroid Build Coastguard Worker geomProc.vertexStride(),
635*c8dee2aaSAndroid Build Coastguard Worker geomProc.instanceStride()));
636*c8dee2aaSAndroid Build Coastguard Worker }
637*c8dee2aaSAndroid Build Coastguard Worker
638*c8dee2aaSAndroid Build Coastguard Worker
MakeComputePipeline(GrD3DGpu * gpu,GrD3DRootSignature * rootSig,const char * shader)639*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrD3DPipeline> GrD3DPipelineStateBuilder::MakeComputePipeline(GrD3DGpu* gpu,
640*c8dee2aaSAndroid Build Coastguard Worker GrD3DRootSignature* rootSig,
641*c8dee2aaSAndroid Build Coastguard Worker const char* shader) {
642*c8dee2aaSAndroid Build Coastguard Worker D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {};
643*c8dee2aaSAndroid Build Coastguard Worker psoDesc.pRootSignature = rootSig->rootSignature();
644*c8dee2aaSAndroid Build Coastguard Worker
645*c8dee2aaSAndroid Build Coastguard Worker // compile shader
646*c8dee2aaSAndroid Build Coastguard Worker gr_cp<ID3DBlob> shaderBlob;
647*c8dee2aaSAndroid Build Coastguard Worker {
648*c8dee2aaSAndroid Build Coastguard Worker TRACE_EVENT0("skia.shaders", "driver_compile_shader");
649*c8dee2aaSAndroid Build Coastguard Worker uint32_t compileFlags = 0;
650*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
651*c8dee2aaSAndroid Build Coastguard Worker // Enable better shader debugging with the graphics debugging tools.
652*c8dee2aaSAndroid Build Coastguard Worker compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
653*c8dee2aaSAndroid Build Coastguard Worker #endif
654*c8dee2aaSAndroid Build Coastguard Worker
655*c8dee2aaSAndroid Build Coastguard Worker gr_cp<ID3DBlob> errors;
656*c8dee2aaSAndroid Build Coastguard Worker HRESULT hr = D3DCompile(shader, strlen(shader), nullptr, nullptr, nullptr, "main",
657*c8dee2aaSAndroid Build Coastguard Worker "cs_5_1", compileFlags, 0, &shaderBlob, &errors);
658*c8dee2aaSAndroid Build Coastguard Worker if (!SUCCEEDED(hr)) {
659*c8dee2aaSAndroid Build Coastguard Worker gpu->getContext()->priv().getShaderErrorHandler()->compileError(
660*c8dee2aaSAndroid Build Coastguard Worker shader, reinterpret_cast<char*>(errors->GetBufferPointer()));
661*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
662*c8dee2aaSAndroid Build Coastguard Worker }
663*c8dee2aaSAndroid Build Coastguard Worker psoDesc.CS = { reinterpret_cast<UINT8*>(shaderBlob->GetBufferPointer()),
664*c8dee2aaSAndroid Build Coastguard Worker shaderBlob->GetBufferSize() };
665*c8dee2aaSAndroid Build Coastguard Worker }
666*c8dee2aaSAndroid Build Coastguard Worker
667*c8dee2aaSAndroid Build Coastguard Worker // Only used for multi-adapter systems.
668*c8dee2aaSAndroid Build Coastguard Worker psoDesc.NodeMask = 0;
669*c8dee2aaSAndroid Build Coastguard Worker
670*c8dee2aaSAndroid Build Coastguard Worker psoDesc.CachedPSO = { nullptr, 0 };
671*c8dee2aaSAndroid Build Coastguard Worker psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
672*c8dee2aaSAndroid Build Coastguard Worker
673*c8dee2aaSAndroid Build Coastguard Worker gr_cp<ID3D12PipelineState> pipelineState;
674*c8dee2aaSAndroid Build Coastguard Worker {
675*c8dee2aaSAndroid Build Coastguard Worker TRACE_EVENT0("skia.shaders", "CreateComputePipelineState");
676*c8dee2aaSAndroid Build Coastguard Worker GR_D3D_CALL_ERRCHECK(
677*c8dee2aaSAndroid Build Coastguard Worker gpu->device()->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState)));
678*c8dee2aaSAndroid Build Coastguard Worker }
679*c8dee2aaSAndroid Build Coastguard Worker
680*c8dee2aaSAndroid Build Coastguard Worker return GrD3DPipeline::Make(std::move(pipelineState));
681*c8dee2aaSAndroid Build Coastguard Worker }
682