blob: 7960b6e047ce8b10befb66fbc504d7b1270516c0 [file] [log] [blame]
Greg Daniel5fc5c812020-04-23 10:30:23 -04001/*
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 <d3dcompiler.h>
9
10#include "src/gpu/d3d/GrD3DPipelineStateBuilder.h"
11
12#include "include/gpu/GrContext.h"
13#include "include/gpu/d3d/GrD3DTypes.h"
14#include "src/core/SkTraceEvent.h"
15#include "src/gpu/GrAutoLocaleSetter.h"
16#include "src/gpu/GrContextPriv.h"
17#include "src/gpu/GrShaderCaps.h"
18#include "src/gpu/GrShaderUtils.h"
19#include "src/gpu/GrStencilSettings.h"
20#include "src/gpu/d3d/GrD3DGpu.h"
21#include "src/gpu/d3d/GrD3DRenderTarget.h"
Greg Danielc31edc02020-04-23 11:03:02 -040022#include "src/gpu/d3d/GrD3DRootSignature.h"
Greg Daniel5fc5c812020-04-23 10:30:23 -040023#include "src/sksl/SkSLCompiler.h"
24
25#include <d3dcompiler.h>
26
27typedef size_t shader_size;
28
Greg Danielb698ad32020-05-04 10:17:22 -040029sk_sp<GrD3DPipelineState> GrD3DPipelineStateBuilder::MakePipelineState(
Greg Daniel5fc5c812020-04-23 10:30:23 -040030 GrD3DGpu* gpu,
31 GrRenderTarget* renderTarget,
32 const GrProgramDesc& desc,
33 const GrProgramInfo& programInfo) {
34 // ensure that we use "." as a decimal separator when creating SkSL code
35 GrAutoLocaleSetter als("C");
36
37 // create a builder. This will be handed off to effects so they can use it to add
38 // uniforms, varyings, textures, etc
39 GrD3DPipelineStateBuilder builder(gpu, renderTarget, desc, programInfo);
40
41 if (!builder.emitAndInstallProcs()) {
42 return nullptr;
43 }
44
45 return builder.finalize();
46}
47
48GrD3DPipelineStateBuilder::GrD3DPipelineStateBuilder(GrD3DGpu* gpu,
49 GrRenderTarget* renderTarget,
50 const GrProgramDesc& desc,
51 const GrProgramInfo& programInfo)
52 : INHERITED(renderTarget, desc, programInfo)
53 , fGpu(gpu)
54 , fVaryingHandler(this)
55 , fUniformHandler(this) {}
56
57const GrCaps* GrD3DPipelineStateBuilder::caps() const {
58 return fGpu->caps();
59}
60
61void GrD3DPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
62 outputColor.addLayoutQualifier("location = 0, index = 0");
63}
64
65void GrD3DPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
66 outputColor.addLayoutQualifier("location = 0, index = 1");
67}
68
69void GrD3DPipelineStateBuilder::compileD3DProgram(SkSL::Program::Kind kind,
70 const SkSL::String& sksl,
71 const SkSL::Program::Settings& settings,
72 ID3DBlob** shader,
73 SkSL::Program::Inputs* outInputs) {
74 auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler();
75 std::unique_ptr<SkSL::Program> program = fGpu->shaderCompiler()->convertProgram(
76 kind, sksl, settings);
77 if (!program) {
78 errorHandler->compileError(sksl.c_str(),
79 fGpu->shaderCompiler()->errorText().c_str());
80 return;
81 }
82 *outInputs = program->fInputs;
83 SkSL::String outHLSL;
84 if (!fGpu->shaderCompiler()->toHLSL(*program, &outHLSL)) {
85 errorHandler->compileError(sksl.c_str(),
86 fGpu->shaderCompiler()->errorText().c_str());
87 return;
88 }
89
90 const char* compileTarget = nullptr;
91 switch (kind) {
92 case SkSL::Program::kVertex_Kind:
93 compileTarget = "vs_5_1";
94 break;
95 case SkSL::Program::kGeometry_Kind:
96 compileTarget = "gs_5_1";
97 break;
98 case SkSL::Program::kFragment_Kind:
99 compileTarget = "ps_5_1";
100 break;
101 default:
102 SkUNREACHABLE;
103 }
104
105 uint32_t compileFlags = 0;
106#ifdef SK_DEBUG
107 // Enable better shader debugging with the graphics debugging tools.
108 compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
109#endif
110 // SPRIV-cross does matrix multiplication expecting row major matrices
111 compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
112
113 // TODO: D3D Static Function
114 gr_cp<ID3DBlob> errors;
115 HRESULT hr = D3DCompile(outHLSL.c_str(), outHLSL.length(), nullptr, nullptr, nullptr, "main",
116 compileTarget, compileFlags, 0, shader, &errors);
117 if (!SUCCEEDED(hr)) {
118 errorHandler->compileError(outHLSL.c_str(),
119 reinterpret_cast<char*>(errors->GetBufferPointer()));
120 }
121}
122
Jim Van Verthbe259dc2020-05-19 11:40:31 -0400123static DXGI_FORMAT attrib_type_to_format(GrVertexAttribType type) {
124 switch (type) {
125 case kFloat_GrVertexAttribType:
126 return DXGI_FORMAT_R32_FLOAT;
127 case kFloat2_GrVertexAttribType:
128 return DXGI_FORMAT_R32G32_FLOAT;
129 case kFloat3_GrVertexAttribType:
130 return DXGI_FORMAT_R32G32B32_FLOAT;
131 case kFloat4_GrVertexAttribType:
132 return DXGI_FORMAT_R32G32B32A32_FLOAT;
133 case kHalf_GrVertexAttribType:
134 return DXGI_FORMAT_R16_FLOAT;
135 case kHalf2_GrVertexAttribType:
136 return DXGI_FORMAT_R16G16_FLOAT;
137 case kHalf4_GrVertexAttribType:
138 return DXGI_FORMAT_R16G16B16A16_FLOAT;
139 case kInt2_GrVertexAttribType:
140 return DXGI_FORMAT_R32G32_SINT;
141 case kInt3_GrVertexAttribType:
142 return DXGI_FORMAT_R32G32B32_SINT;
143 case kInt4_GrVertexAttribType:
144 return DXGI_FORMAT_R32G32B32A32_SINT;
145 case kByte_GrVertexAttribType:
146 return DXGI_FORMAT_R8_SINT;
147 case kByte2_GrVertexAttribType:
148 return DXGI_FORMAT_R8G8_SINT;
149 case kByte4_GrVertexAttribType:
150 return DXGI_FORMAT_R8G8B8A8_SINT;
151 case kUByte_GrVertexAttribType:
152 return DXGI_FORMAT_R8_UINT;
153 case kUByte2_GrVertexAttribType:
154 return DXGI_FORMAT_R8G8_UINT;
155 case kUByte4_GrVertexAttribType:
156 return DXGI_FORMAT_R8G8B8A8_UINT;
157 case kUByte_norm_GrVertexAttribType:
158 return DXGI_FORMAT_R8_UNORM;
159 case kUByte4_norm_GrVertexAttribType:
160 return DXGI_FORMAT_R8G8B8A8_UNORM;
161 case kShort2_GrVertexAttribType:
162 return DXGI_FORMAT_R16G16_SINT;
163 case kShort4_GrVertexAttribType:
164 return DXGI_FORMAT_R16G16B16A16_SINT;
165 case kUShort2_GrVertexAttribType:
166 return DXGI_FORMAT_R16G16_UINT;
167 case kUShort2_norm_GrVertexAttribType:
168 return DXGI_FORMAT_R16G16_UNORM;
169 case kInt_GrVertexAttribType:
170 return DXGI_FORMAT_R32_SINT;
171 case kUint_GrVertexAttribType:
172 return DXGI_FORMAT_R32_UINT;
173 case kUShort_norm_GrVertexAttribType:
174 return DXGI_FORMAT_R16_UNORM;
175 case kUShort4_norm_GrVertexAttribType:
176 return DXGI_FORMAT_R16G16B16A16_UNORM;
177 }
178 SK_ABORT("Unknown vertex attrib type");
179}
180
181static void setup_vertex_input_layout(const GrPrimitiveProcessor& primProc,
182 D3D12_INPUT_ELEMENT_DESC* inputElements) {
183 unsigned int slotNumber = 0;
184 unsigned int vertexSlot = 0;
185 unsigned int instanceSlot = 0;
186 if (primProc.hasVertexAttributes()) {
187 vertexSlot = slotNumber++;
188 }
189 if (primProc.hasInstanceAttributes()) {
190 instanceSlot = slotNumber++;
191 }
192
193 unsigned int currentAttrib = 0;
194 unsigned int vertexAttributeOffset = 0;
195
196 for (const auto& attrib : primProc.vertexAttributes()) {
197 // When using SPIRV-Cross it converts the location modifier in SPIRV to be
198 // TEXCOORD<N> where N is the location value for eveery vertext attribute
199 inputElements[currentAttrib] = { "TEXCOORD", currentAttrib,
200 attrib_type_to_format(attrib.cpuType()),
201 vertexSlot, vertexAttributeOffset,
202 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 };
203 vertexAttributeOffset += attrib.sizeAlign4();
204 currentAttrib++;
205 }
206 SkASSERT(vertexAttributeOffset == primProc.vertexStride());
207
208 unsigned int instanceAttributeOffset = 0;
209 for (const auto& attrib : primProc.instanceAttributes()) {
210 // When using SPIRV-Cross it converts the location modifier in SPIRV to be
211 // TEXCOORD<N> where N is the location value for eveery vertext attribute
212 inputElements[currentAttrib] = { "TEXCOORD", currentAttrib,
213 attrib_type_to_format(attrib.cpuType()),
214 instanceSlot, instanceAttributeOffset,
215 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 };
216 instanceAttributeOffset += attrib.sizeAlign4();
217 currentAttrib++;
218 }
219 SkASSERT(instanceAttributeOffset == primProc.instanceStride());
220}
221
222static D3D12_BLEND blend_coeff_to_d3d_blend(GrBlendCoeff coeff) {
223 switch (coeff) {
224 case kZero_GrBlendCoeff:
225 return D3D12_BLEND_ZERO;
226 case kOne_GrBlendCoeff:
227 return D3D12_BLEND_ONE;
228 case kSC_GrBlendCoeff:
229 return D3D12_BLEND_SRC_COLOR;
230 case kISC_GrBlendCoeff:
231 return D3D12_BLEND_INV_SRC_COLOR;
232 case kDC_GrBlendCoeff:
233 return D3D12_BLEND_DEST_COLOR;
234 case kIDC_GrBlendCoeff:
235 return D3D12_BLEND_INV_DEST_COLOR;
236 case kSA_GrBlendCoeff:
237 return D3D12_BLEND_SRC_ALPHA;
238 case kISA_GrBlendCoeff:
239 return D3D12_BLEND_INV_SRC_ALPHA;
240 case kDA_GrBlendCoeff:
241 return D3D12_BLEND_DEST_ALPHA;
242 case kIDA_GrBlendCoeff:
243 return D3D12_BLEND_INV_DEST_ALPHA;
244 case kConstC_GrBlendCoeff:
245 return D3D12_BLEND_BLEND_FACTOR;
246 case kIConstC_GrBlendCoeff:
247 return D3D12_BLEND_INV_BLEND_FACTOR;
248 case kS2C_GrBlendCoeff:
249 return D3D12_BLEND_SRC1_COLOR;
250 case kIS2C_GrBlendCoeff:
251 return D3D12_BLEND_INV_SRC1_COLOR;
252 case kS2A_GrBlendCoeff:
253 return D3D12_BLEND_SRC1_ALPHA;
254 case kIS2A_GrBlendCoeff:
255 return D3D12_BLEND_INV_SRC1_ALPHA;
256 case kIllegal_GrBlendCoeff:
257 return D3D12_BLEND_ZERO;
258 }
259 SkUNREACHABLE;
260}
261
262static D3D12_BLEND blend_coeff_to_d3d_blend_for_alpha(GrBlendCoeff coeff) {
263 switch (coeff) {
264 // Force all srcColor used in alpha slot to alpha version.
265 case kSC_GrBlendCoeff:
266 return D3D12_BLEND_SRC_ALPHA;
267 case kISC_GrBlendCoeff:
268 return D3D12_BLEND_INV_SRC_ALPHA;
269 case kDC_GrBlendCoeff:
270 return D3D12_BLEND_DEST_ALPHA;
271 case kIDC_GrBlendCoeff:
272 return D3D12_BLEND_INV_DEST_ALPHA;
273 case kS2C_GrBlendCoeff:
274 return D3D12_BLEND_SRC1_ALPHA;
275 case kIS2C_GrBlendCoeff:
276 return D3D12_BLEND_INV_SRC1_ALPHA;
277
278 default:
279 return blend_coeff_to_d3d_blend(coeff);
280 }
281}
282
283
284static D3D12_BLEND_OP blend_equation_to_d3d_op(GrBlendEquation equation) {
285 switch (equation) {
286 case kAdd_GrBlendEquation:
287 return D3D12_BLEND_OP_ADD;
288 case kSubtract_GrBlendEquation:
289 return D3D12_BLEND_OP_SUBTRACT;
290 case kReverseSubtract_GrBlendEquation:
291 return D3D12_BLEND_OP_REV_SUBTRACT;
292 default:
293 SkUNREACHABLE;
294 }
295}
296
297static void fill_in_blend_state(const GrPipeline& pipeline, D3D12_BLEND_DESC* blendDesc) {
298 blendDesc->AlphaToCoverageEnable = false;
299 blendDesc->IndependentBlendEnable = false;
300
301 const GrXferProcessor::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
302
303 GrBlendEquation equation = blendInfo.fEquation;
304 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
305 GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
306 bool blendOff = GrBlendShouldDisable(equation, srcCoeff, dstCoeff);
307
308 auto& rtBlend = blendDesc->RenderTarget[0];
309 rtBlend.BlendEnable = !blendOff;
310 if (!blendOff) {
311 rtBlend.SrcBlend = blend_coeff_to_d3d_blend(srcCoeff);
312 rtBlend.DestBlend = blend_coeff_to_d3d_blend(dstCoeff);
313 rtBlend.BlendOp = blend_equation_to_d3d_op(equation);
314 rtBlend.SrcBlendAlpha = blend_coeff_to_d3d_blend_for_alpha(srcCoeff);
315 rtBlend.DestBlendAlpha = blend_coeff_to_d3d_blend_for_alpha(dstCoeff);
316 rtBlend.BlendOpAlpha = blend_equation_to_d3d_op(equation);
317 }
318
319 if (!blendInfo.fWriteColor) {
320 rtBlend.RenderTargetWriteMask = 0;
321 } else {
322 rtBlend.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
323 }
324}
325
326static void fill_in_rasterizer_state(const GrPipeline& pipeline, const GrCaps* caps,
327 D3D12_RASTERIZER_DESC* rasterizer) {
328 rasterizer->FillMode = (caps->wireframeMode() || pipeline.isWireframe()) ?
329 D3D12_FILL_MODE_WIREFRAME : D3D12_FILL_MODE_SOLID;
330 rasterizer->CullMode = D3D12_CULL_MODE_NONE;
331 rasterizer->FrontCounterClockwise = true;
332 rasterizer->DepthBias = 0;
333 rasterizer->DepthBiasClamp = 0.0f;
334 rasterizer->SlopeScaledDepthBias = 0.0f;
335 rasterizer->DepthClipEnable = false;
336 rasterizer->MultisampleEnable = pipeline.isHWAntialiasState();
337 rasterizer->AntialiasedLineEnable = false;
338 rasterizer->ForcedSampleCount = 0;
339 rasterizer->ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
340}
341
342static D3D12_STENCIL_OP stencil_op_to_d3d_op(GrStencilOp op) {
343 switch (op) {
344 case GrStencilOp::kKeep:
345 return D3D12_STENCIL_OP_KEEP;
346 case GrStencilOp::kZero:
347 return D3D12_STENCIL_OP_ZERO;
348 case GrStencilOp::kReplace:
349 return D3D12_STENCIL_OP_REPLACE;
350 case GrStencilOp::kInvert:
351 return D3D12_STENCIL_OP_INVERT;
352 case GrStencilOp::kIncWrap:
353 return D3D12_STENCIL_OP_INCR;
354 case GrStencilOp::kDecWrap:
355 return D3D12_STENCIL_OP_DECR;
356 case GrStencilOp::kIncClamp:
357 return D3D12_STENCIL_OP_INCR_SAT;
358 case GrStencilOp::kDecClamp:
359 return D3D12_STENCIL_OP_DECR_SAT;
360 }
361 SkUNREACHABLE;
362}
363
364static D3D12_COMPARISON_FUNC stencil_test_to_d3d_func(GrStencilTest test) {
365 switch (test) {
366 case GrStencilTest::kAlways:
367 return D3D12_COMPARISON_FUNC_ALWAYS;
368 case GrStencilTest::kNever:
369 return D3D12_COMPARISON_FUNC_NEVER;
370 case GrStencilTest::kGreater:
371 return D3D12_COMPARISON_FUNC_GREATER;
372 case GrStencilTest::kGEqual:
373 return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
374 case GrStencilTest::kLess:
375 return D3D12_COMPARISON_FUNC_LESS;
376 case GrStencilTest::kLEqual:
377 return D3D12_COMPARISON_FUNC_LESS_EQUAL;
378 case GrStencilTest::kEqual:
379 return D3D12_COMPARISON_FUNC_EQUAL;
380 case GrStencilTest::kNotEqual:
381 return D3D12_COMPARISON_FUNC_NOT_EQUAL;
382 }
383 SkUNREACHABLE;
384}
385
386static void setup_stencilop_desc(D3D12_DEPTH_STENCILOP_DESC* desc,
387 const GrStencilSettings::Face& stencilFace) {
388 desc->StencilFailOp = stencil_op_to_d3d_op(stencilFace.fFailOp);
389 desc->StencilDepthFailOp = desc->StencilFailOp;
390 desc->StencilPassOp = stencil_op_to_d3d_op(stencilFace.fPassOp);
391 desc->StencilFunc = stencil_test_to_d3d_func(stencilFace.fTest);
392}
393
394static void fill_in_depth_stencil_state(const GrProgramInfo& programInfo,
395 D3D12_DEPTH_STENCIL_DESC* dsDesc) {
396 GrStencilSettings stencilSettings = programInfo.nonGLStencilSettings();
397 GrSurfaceOrigin origin = programInfo.origin();
398
399 dsDesc->DepthEnable = false;
400 dsDesc->DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
401 dsDesc->DepthFunc = D3D12_COMPARISON_FUNC_NEVER;
402 dsDesc->StencilEnable = !stencilSettings.isDisabled();
403 if (!stencilSettings.isDisabled()) {
404 if (stencilSettings.isTwoSided()) {
405 const auto& frontFace = stencilSettings.postOriginCCWFace(origin);
Greg Daniel90cf5d42020-06-16 09:39:35 -0400406 const auto& backFace = stencilSettings.postOriginCWFace(origin);
Jim Van Verthbe259dc2020-05-19 11:40:31 -0400407
408 SkASSERT(frontFace.fTestMask == backFace.fTestMask);
409 SkASSERT(frontFace.fWriteMask == backFace.fWriteMask);
410 dsDesc->StencilReadMask = frontFace.fTestMask;
411 dsDesc->StencilWriteMask = frontFace.fWriteMask;
412
413 setup_stencilop_desc(&dsDesc->FrontFace, frontFace);
414 setup_stencilop_desc(&dsDesc->BackFace, backFace);
415 } else {
416 dsDesc->StencilReadMask = stencilSettings.singleSidedFace().fTestMask;
Greg Daniel90cf5d42020-06-16 09:39:35 -0400417 dsDesc->StencilWriteMask = stencilSettings.singleSidedFace().fWriteMask;
Jim Van Verthbe259dc2020-05-19 11:40:31 -0400418 setup_stencilop_desc(&dsDesc->FrontFace, stencilSettings.singleSidedFace());
419 dsDesc->BackFace = dsDesc->FrontFace;
420 }
421 }
422}
423
424static D3D12_PRIMITIVE_TOPOLOGY_TYPE gr_primitive_type_to_d3d(GrPrimitiveType primitiveType) {
425 switch (primitiveType) {
Jim Van Verth83ed9572020-05-21 11:53:55 -0400426 case GrPrimitiveType::kTriangles:
427 case GrPrimitiveType::kTriangleStrip: //fall through
428 return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
429 case GrPrimitiveType::kPoints:
430 return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
431 case GrPrimitiveType::kLines: // fall through
432 case GrPrimitiveType::kLineStrip:
433 return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
434 case GrPrimitiveType::kPatches: // fall through, unsupported
435 case GrPrimitiveType::kPath: // fall through, unsupported
436 default:
437 SkUNREACHABLE;
Jim Van Verthbe259dc2020-05-19 11:40:31 -0400438 }
439}
440
441gr_cp<ID3D12PipelineState> create_pipeline_state(
Jim Van Verth83ed9572020-05-21 11:53:55 -0400442 GrD3DGpu* gpu, const GrProgramInfo& programInfo, const sk_sp<GrD3DRootSignature>& rootSig,
Jim Van Verthbe259dc2020-05-19 11:40:31 -0400443 gr_cp<ID3DBlob> vertexShader, gr_cp<ID3DBlob> geometryShader, gr_cp<ID3DBlob> pixelShader,
444 DXGI_FORMAT renderTargetFormat, DXGI_FORMAT depthStencilFormat,
445 unsigned int sampleQualityLevel) {
446 D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
447
448 psoDesc.pRootSignature = rootSig->rootSignature();
449
450 psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()),
451 vertexShader->GetBufferSize() };
452 psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()),
453 pixelShader->GetBufferSize() };
454
455 if (geometryShader.get()) {
456 psoDesc.GS = { reinterpret_cast<UINT8*>(geometryShader->GetBufferPointer()),
457 geometryShader->GetBufferSize() };
458 }
459
460 psoDesc.StreamOutput = { nullptr, 0, nullptr, 0, 0 };
461
462 fill_in_blend_state(programInfo.pipeline(), &psoDesc.BlendState);
463 psoDesc.SampleMask = UINT_MAX;
464
465 fill_in_rasterizer_state(programInfo.pipeline(), gpu->caps(), &psoDesc.RasterizerState);
466
467 fill_in_depth_stencil_state(programInfo, &psoDesc.DepthStencilState);
468
469 unsigned int totalAttributeCnt = programInfo.primProc().numVertexAttributes() +
470 programInfo.primProc().numInstanceAttributes();
471 SkAutoSTArray<4, D3D12_INPUT_ELEMENT_DESC> inputElements(totalAttributeCnt);
472 setup_vertex_input_layout(programInfo.primProc(), inputElements.get());
473
474 psoDesc.InputLayout = { inputElements.get(), totalAttributeCnt };
475
476 psoDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
477
478 // This is for geometry or hull shader primitives
479 psoDesc.PrimitiveTopologyType = gr_primitive_type_to_d3d(programInfo.primitiveType());
480
481 psoDesc.NumRenderTargets = 1;
482
483 psoDesc.RTVFormats[0] = renderTargetFormat;
484
485 psoDesc.DSVFormat = depthStencilFormat;
486
487 unsigned int numRasterSamples = programInfo.numRasterSamples();
488 psoDesc.SampleDesc = { numRasterSamples, sampleQualityLevel };
489
490 // Only used for multi-adapter systems.
491 psoDesc.NodeMask = 0;
492
493 psoDesc.CachedPSO = { nullptr, 0 };
494 psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
495
496 gr_cp<ID3D12PipelineState> pipelineState;
497 SkDEBUGCODE(HRESULT hr = )gpu->device()->CreateGraphicsPipelineState(
498 &psoDesc, IID_PPV_ARGS(&pipelineState));
499 SkASSERT(SUCCEEDED(hr));
500
501 return pipelineState;
502}
503
Greg Danielfd776732020-04-23 12:51:13 -0400504sk_sp<GrD3DPipelineState> GrD3DPipelineStateBuilder::finalize() {
Greg Daniel5fc5c812020-04-23 10:30:23 -0400505 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
506
507 // We need to enable the following extensions so that the compiler can correctly make spir-v
508 // from our glsl shaders.
509 fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
510 fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
511 fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
512 fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
513
514 this->finalizeShaders();
515
516 SkSL::Program::Settings settings;
517 settings.fCaps = this->caps()->shaderCaps();
518 settings.fFlipY = this->origin() != kTopLeft_GrSurfaceOrigin;
519 settings.fSharpenTextures =
520 this->gpu()->getContext()->priv().options().fSharpenMipmappedTextures;
521 settings.fRTHeightOffset = fUniformHandler.getRTHeightOffset();
522 settings.fRTHeightBinding = 0;
523 settings.fRTHeightSet = 0;
524
525 gr_cp<ID3DBlob> vertexShader;
526 gr_cp<ID3DBlob> geometryShader;
527 gr_cp<ID3DBlob> pixelShader;
528 SkSL::Program::Inputs vertInputs, fragInputs, geomInputs;
529
530 this->compileD3DProgram(SkSL::Program::kVertex_Kind, fVS.fCompilerString, settings,
531 &vertexShader, &vertInputs);
532 this->compileD3DProgram(SkSL::Program::kFragment_Kind, fFS.fCompilerString, settings,
533 &pixelShader, &fragInputs);
534
535 if (!vertexShader.get() || !pixelShader.get()) {
536 return nullptr;
537 }
538
Jim Van Verth40b4de22020-05-20 09:35:42 -0400539 const GrPrimitiveProcessor& primProc = this->primitiveProcessor();
540 if (primProc.willUseGeoShader()) {
Greg Daniel5fc5c812020-04-23 10:30:23 -0400541 this->compileD3DProgram(SkSL::Program::kGeometry_Kind, fGS.fCompilerString, settings,
542 &geometryShader, &geomInputs);
543 if (!geometryShader.get()) {
544 return nullptr;
545 }
546 }
547
Greg Danielc31edc02020-04-23 11:03:02 -0400548 sk_sp<GrD3DRootSignature> rootSig =
549 fGpu->resourceProvider().findOrCreateRootSignature(fUniformHandler.fTextures.count());
550 if (!rootSig) {
551 return nullptr;
552 }
Greg Daniel5fc5c812020-04-23 10:30:23 -0400553
554 const GrD3DRenderTarget* rt = static_cast<const GrD3DRenderTarget*>(fRenderTarget);
Jim Van Verthbe259dc2020-05-19 11:40:31 -0400555 gr_cp<ID3D12PipelineState> pipelineState = create_pipeline_state(
Jim Van Verth83ed9572020-05-21 11:53:55 -0400556 fGpu, fProgramInfo, rootSig, std::move(vertexShader),
Jim Van Verthbe259dc2020-05-19 11:40:31 -0400557 std::move(geometryShader), std::move(pixelShader), rt->dxgiFormat(),
558 rt->stencilDxgiFormat(), rt->sampleQualityLevel());
559
560 return sk_sp<GrD3DPipelineState>(new GrD3DPipelineState(std::move(pipelineState),
Jim Van Verth83ed9572020-05-21 11:53:55 -0400561 std::move(rootSig),
Jim Van Verthbe259dc2020-05-19 11:40:31 -0400562 fUniformHandles,
563 fUniformHandler.fUniforms,
564 fUniformHandler.fCurrentUBOOffset,
Jim Van Verth40b4de22020-05-20 09:35:42 -0400565 fUniformHandler.fSamplers.count(),
Jim Van Verthbe259dc2020-05-19 11:40:31 -0400566 std::move(fGeometryProcessor),
567 std::move(fXferProcessor),
568 std::move(fFragmentProcessors),
Jim Van Verth40b4de22020-05-20 09:35:42 -0400569 fFragmentProcessorCnt,
570 primProc.vertexStride(),
571 primProc.instanceStride()));
Greg Daniel5fc5c812020-04-23 10:30:23 -0400572}