32#include <d3dcompiler.h>
48 if (!
builder.emitAndInstallProcs()) {
55GrD3DPipelineStateBuilder::GrD3DPipelineStateBuilder(
GrD3DGpu* gpu,
61 , fVaryingHandler(this)
62 , fUniformHandler(this)
63 , fRenderTarget(renderTarget) {}
74 const std::string& hlsl,
77 const char* compileTarget =
nullptr;
80 compileTarget =
"vs_5_1";
83 compileTarget =
"ps_5_1";
89 uint32_t compileFlags = 0;
92 compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
95 compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
99 HRESULT hr = D3DCompile(hlsl.c_str(), hlsl.length(),
nullptr,
nullptr,
nullptr,
"main",
100 compileTarget, compileFlags, 0, &shader, &
errors);
103 hlsl.c_str(),
reinterpret_cast<char*
>(
errors->GetBufferPointer()));
122 return shaders[shaderType].
get();
130 const std::string& sksl,
133 std::string* outHLSL) {
154 return DXGI_FORMAT_R32_FLOAT;
156 return DXGI_FORMAT_R32G32_FLOAT;
158 return DXGI_FORMAT_R32G32B32_FLOAT;
160 return DXGI_FORMAT_R32G32B32A32_FLOAT;
162 return DXGI_FORMAT_R16_FLOAT;
164 return DXGI_FORMAT_R16G16_FLOAT;
166 return DXGI_FORMAT_R16G16B16A16_FLOAT;
168 return DXGI_FORMAT_R32G32_SINT;
170 return DXGI_FORMAT_R32G32B32_SINT;
172 return DXGI_FORMAT_R32G32B32A32_SINT;
174 return DXGI_FORMAT_R8_SINT;
176 return DXGI_FORMAT_R8G8_SINT;
178 return DXGI_FORMAT_R8G8B8A8_SINT;
180 return DXGI_FORMAT_R8_UINT;
182 return DXGI_FORMAT_R8G8_UINT;
184 return DXGI_FORMAT_R8G8B8A8_UINT;
186 return DXGI_FORMAT_R8_UNORM;
188 return DXGI_FORMAT_R8G8B8A8_UNORM;
190 return DXGI_FORMAT_R16G16_SINT;
192 return DXGI_FORMAT_R16G16B16A16_SINT;
194 return DXGI_FORMAT_R16G16_UINT;
196 return DXGI_FORMAT_R16G16_UNORM;
198 return DXGI_FORMAT_R32_SINT;
200 return DXGI_FORMAT_R32_UINT;
202 return DXGI_FORMAT_R16_UNORM;
204 return DXGI_FORMAT_R16G16B16A16_UNORM;
206 SK_ABORT(
"Unknown vertex attrib type");
210 D3D12_INPUT_ELEMENT_DESC* inputElements) {
211 unsigned int slotNumber = 0;
212 unsigned int vertexSlot = 0;
213 unsigned int instanceSlot = 0;
215 vertexSlot = slotNumber++;
218 instanceSlot = slotNumber++;
221 unsigned int currentAttrib = 0;
226 inputElements[currentAttrib] = {
"TEXCOORD", currentAttrib,
228 vertexSlot,
SkToU32(*attrib.offset()),
229 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 };
236 inputElements[currentAttrib] = {
"TEXCOORD", currentAttrib,
238 instanceSlot,
SkToU32(*attrib.offset()),
239 D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1 };
247 return D3D12_BLEND_ZERO;
249 return D3D12_BLEND_ONE;
251 return D3D12_BLEND_SRC_COLOR;
253 return D3D12_BLEND_INV_SRC_COLOR;
255 return D3D12_BLEND_DEST_COLOR;
257 return D3D12_BLEND_INV_DEST_COLOR;
259 return D3D12_BLEND_SRC_ALPHA;
261 return D3D12_BLEND_INV_SRC_ALPHA;
263 return D3D12_BLEND_DEST_ALPHA;
265 return D3D12_BLEND_INV_DEST_ALPHA;
267 return D3D12_BLEND_BLEND_FACTOR;
269 return D3D12_BLEND_INV_BLEND_FACTOR;
271 return D3D12_BLEND_SRC1_COLOR;
273 return D3D12_BLEND_INV_SRC1_COLOR;
275 return D3D12_BLEND_SRC1_ALPHA;
277 return D3D12_BLEND_INV_SRC1_ALPHA;
279 return D3D12_BLEND_ZERO;
288 return D3D12_BLEND_SRC_ALPHA;
290 return D3D12_BLEND_INV_SRC_ALPHA;
292 return D3D12_BLEND_DEST_ALPHA;
294 return D3D12_BLEND_INV_DEST_ALPHA;
296 return D3D12_BLEND_SRC1_ALPHA;
298 return D3D12_BLEND_INV_SRC1_ALPHA;
309 return D3D12_BLEND_OP_ADD;
311 return D3D12_BLEND_OP_SUBTRACT;
313 return D3D12_BLEND_OP_REV_SUBTRACT;
320 blendDesc->AlphaToCoverageEnable =
false;
321 blendDesc->IndependentBlendEnable =
false;
330 auto& rtBlend = blendDesc->RenderTarget[0];
331 rtBlend.BlendEnable = !blendOff;
342 rtBlend.RenderTargetWriteMask = 0;
344 rtBlend.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
349 bool multisampleEnable,
351 D3D12_RASTERIZER_DESC* rasterizer) {
353 D3D12_FILL_MODE_WIREFRAME : D3D12_FILL_MODE_SOLID;
354 rasterizer->CullMode = D3D12_CULL_MODE_NONE;
355 rasterizer->FrontCounterClockwise =
true;
356 rasterizer->DepthBias = 0;
357 rasterizer->DepthBiasClamp = 0.0f;
358 rasterizer->SlopeScaledDepthBias = 0.0f;
359 rasterizer->DepthClipEnable =
false;
360 rasterizer->MultisampleEnable = multisampleEnable;
361 rasterizer->AntialiasedLineEnable =
false;
362 rasterizer->ForcedSampleCount = 0;
363 rasterizer->ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
369 return D3D12_STENCIL_OP_KEEP;
371 return D3D12_STENCIL_OP_ZERO;
373 return D3D12_STENCIL_OP_REPLACE;
375 return D3D12_STENCIL_OP_INVERT;
377 return D3D12_STENCIL_OP_INCR;
379 return D3D12_STENCIL_OP_DECR;
381 return D3D12_STENCIL_OP_INCR_SAT;
383 return D3D12_STENCIL_OP_DECR_SAT;
391 return D3D12_COMPARISON_FUNC_ALWAYS;
393 return D3D12_COMPARISON_FUNC_NEVER;
395 return D3D12_COMPARISON_FUNC_GREATER;
397 return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
399 return D3D12_COMPARISON_FUNC_LESS;
401 return D3D12_COMPARISON_FUNC_LESS_EQUAL;
403 return D3D12_COMPARISON_FUNC_EQUAL;
405 return D3D12_COMPARISON_FUNC_NOT_EQUAL;
413 desc->StencilDepthFailOp =
desc->StencilFailOp;
419 D3D12_DEPTH_STENCIL_DESC* dsDesc) {
423 dsDesc->DepthEnable =
false;
424 dsDesc->DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
425 dsDesc->DepthFunc = D3D12_COMPARISON_FUNC_NEVER;
426 dsDesc->StencilEnable = !stencilSettings.
isDisabled();
432 SkASSERT(frontFace.fTestMask == backFace.fTestMask);
433 SkASSERT(frontFace.fWriteMask == backFace.fWriteMask);
434 dsDesc->StencilReadMask = frontFace.fTestMask;
435 dsDesc->StencilWriteMask = frontFace.fWriteMask;
443 dsDesc->BackFace = dsDesc->FrontFace;
449 switch (primitiveType) {
452 return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
454 return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
457 return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
466 DXGI_FORMAT renderTargetFormat, DXGI_FORMAT depthStencilFormat,
467 unsigned int sampleQualityPattern) {
468 D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
472 psoDesc.VS = {
reinterpret_cast<UINT8*
>(vertexShader->GetBufferPointer()),
473 vertexShader->GetBufferSize() };
474 psoDesc.PS = {
reinterpret_cast<UINT8*
>(pixelShader->GetBufferPointer()),
475 pixelShader->GetBufferSize() };
477 psoDesc.StreamOutput = {
nullptr, 0,
nullptr, 0, 0 };
480 psoDesc.SampleMask = UINT_MAX;
483 &psoDesc.RasterizerState);
492 psoDesc.InputLayout = { inputElements.
get(), totalAttributeCnt };
494 psoDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
499 psoDesc.NumRenderTargets = 1;
501 psoDesc.RTVFormats[0] = renderTargetFormat;
503 psoDesc.DSVFormat = depthStencilFormat;
505 unsigned int numSamples = programInfo.
numSamples();
506 psoDesc.SampleDesc = { numSamples, sampleQualityPattern };
509 psoDesc.NodeMask = 0;
511 psoDesc.CachedPSO = {
nullptr, 0 };
512 psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
516 TRACE_EVENT0(
"skia.shaders",
"CreateGraphicsPipelineState");
518 gpu->
device()->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState)));
521 return pipelineState;
527std::unique_ptr<GrD3DPipelineState> GrD3DPipelineStateBuilder::finalize() {
542 if (persistentCache) {
547 cached = persistentCache->load(*
key);
557 if (
kHLSL_Tag == shaderType && this->loadHLSLFromCache(&reader, shaders)) {
572 sksl[
i] = &cached_sksl[
i];
578 shaders[shaderType] = this->compileD3DProgram(
579 kind, *sksl[shaderType],
settings, &intfs[shaderType], &hlsl[shaderType]);
580 return shaders[shaderType].
get();
588 if (persistentCache && !cached) {
603 persistentCache->store(*
key, *
data, description);
623 return std::unique_ptr<GrD3DPipelineState>(
627 fUniformHandler.fUniforms,
628 fUniformHandler.fCurrentUBOOffset,
629 fUniformHandler.fSamplers.
count(),
640 const char* shader) {
641 D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {};
648 uint32_t compileFlags = 0;
651 compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
655 HRESULT hr = D3DCompile(shader, strlen(shader),
nullptr,
nullptr,
nullptr,
"main",
656 "cs_5_1", compileFlags, 0, &shaderBlob, &
errors);
659 shader,
reinterpret_cast<char*
>(
errors->GetBufferPointer()));
662 psoDesc.CS = {
reinterpret_cast<UINT8*
>(shaderBlob->GetBufferPointer()),
663 shaderBlob->GetBufferSize() };
667 psoDesc.NodeMask = 0;
669 psoDesc.CachedPSO = {
nullptr, 0 };
670 psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
674 TRACE_EVENT0(
"skia.shaders",
"CreateComputePipelineState");
676 gpu->
device()->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState)));
static DXGI_FORMAT attrib_type_to_format(GrVertexAttribType type)
static void setup_vertex_input_layout(const GrGeometryProcessor &geomProc, D3D12_INPUT_ELEMENT_DESC *inputElements)
gr_cp< ID3D12PipelineState > 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)
static gr_cp< ID3DBlob > GrCompileHLSLShader(GrD3DGpu *gpu, const std::string &hlsl, SkSL::ProgramKind kind)
static constexpr SkFourByteTag kHLSL_Tag
static D3D12_STENCIL_OP stencil_op_to_d3d_op(GrStencilOp op)
static void fill_in_depth_stencil_state(const GrProgramInfo &programInfo, D3D12_DEPTH_STENCIL_DESC *dsDesc)
static D3D12_BLEND blend_coeff_to_d3d_blend_for_alpha(skgpu::BlendCoeff coeff)
static D3D12_BLEND blend_coeff_to_d3d_blend(skgpu::BlendCoeff coeff)
static void fill_in_rasterizer_state(const GrPipeline &pipeline, bool multisampleEnable, const GrCaps *caps, D3D12_RASTERIZER_DESC *rasterizer)
static D3D12_PRIMITIVE_TOPOLOGY_TYPE gr_primitive_type_to_d3d(GrPrimitiveType primitiveType)
static D3D12_COMPARISON_FUNC stencil_test_to_d3d_func(GrStencilTest test)
static void setup_stencilop_desc(D3D12_DEPTH_STENCILOP_DESC *desc, const GrStencilSettings::Face &stencilFace)
static void fill_in_blend_state(const GrPipeline &pipeline, D3D12_BLEND_DESC *blendDesc)
static D3D12_BLEND_OP blend_equation_to_d3d_op(skgpu::BlendEquation equation)
static constexpr SkFourByteTag kSKSL_Tag
#define GR_D3D_CALL_ERRCHECK(X)
@ kUShort_norm_GrVertexAttribType
@ kFloat2_GrVertexAttribType
@ kUShort2_GrVertexAttribType
@ kUInt_GrVertexAttribType
@ kUByte4_norm_GrVertexAttribType
@ kUByte_GrVertexAttribType
@ kShort2_GrVertexAttribType
@ kUShort4_norm_GrVertexAttribType
@ kInt_GrVertexAttribType
@ kByte_GrVertexAttribType
@ kByte4_GrVertexAttribType
@ kFloat3_GrVertexAttribType
@ kFloat_GrVertexAttribType
@ kByte2_GrVertexAttribType
@ kFloat4_GrVertexAttribType
@ kShort4_GrVertexAttribType
@ kUShort2_norm_GrVertexAttribType
@ kInt3_GrVertexAttribType
@ kHalf2_GrVertexAttribType
@ kHalf4_GrVertexAttribType
@ kUByte4_GrVertexAttribType
@ kUByte2_GrVertexAttribType
@ kInt4_GrVertexAttribType
@ kUByte_norm_GrVertexAttribType
@ kInt2_GrVertexAttribType
@ kHalf_GrVertexAttribType
static const int kGrShaderTypeCount
#define SK_ABORT(message,...)
#define INHERITED(method,...)
constexpr uint32_t SkToU32(S x)
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
const GrContextOptions & options() const
GrContextOptions::ShaderErrorHandler * getShaderErrorHandler() const
bool wireframeMode() const
GrD3DResourceProvider & resourceProvider()
ID3D12Device * device() const
static sk_sp< GrD3DPipeline > MakeComputePipeline(GrD3DGpu *, GrD3DRootSignature *, const char *shader)
const GrCaps * caps() const override
void finalizeFragmentSecondaryColor(GrShaderVar &outputColor) override
static std::unique_ptr< GrD3DPipelineState > MakePipelineState(GrD3DGpu *, GrD3DRenderTarget *, const GrProgramDesc &, const GrProgramInfo &)
static sk_sp< GrD3DPipeline > Make(gr_cp< ID3D12PipelineState > pipelineState)
DXGI_FORMAT stencilDxgiFormat() const
sk_sp< GrD3DRootSignature > findOrCreateRootSignature(int numTextureSamplers, int numUAVs=0)
ID3D12RootSignature * rootSignature() const
DXGI_FORMAT dxgiFormat() const
unsigned int sampleQualityPattern() const
GrContextOptions::PersistentCache * getPersistentCache()
GrDirectContextPriv priv()
const GrProgramDesc & desc() const
std::vector< std::unique_ptr< GrFragmentProcessor::ProgramImpl > > fFPImpls
std::unique_ptr< GrGeometryProcessor::ProgramImpl > fGPImpl
const GrShaderCaps * shaderCaps() const
const GrGeometryProcessor & geometryProcessor() const
std::unique_ptr< GrXferProcessor::ProgramImpl > fXPImpl
GrGLSLBuiltinUniformHandles fUniformHandles
const GrProgramInfo & fProgramInfo
GrGLSLFragmentShaderBuilder fFS
void addRTFlipUniform(const char *name)
const GrPipeline & pipeline() const
std::string fCompilerString
int numVertexAttributes() const
int numInstanceAttributes() const
size_t vertexStride() const
bool hasInstanceAttributes() const
const AttributeSet & vertexAttributes() const
const AttributeSet & instanceAttributes() const
size_t instanceStride() const
bool hasVertexAttributes() const
const GrCaps * caps() const
GrDirectContext * getContext()
const GrXferProcessor & getXferProcessor() const
static SkString Describe(const GrProgramInfo &, const GrCaps &)
GrSurfaceOrigin origin() const
GrPrimitiveType primitiveType() const
const GrPipeline & pipeline() const
const GrGeometryProcessor & geomProc() const
GrStencilSettings nonGLStencilSettings() const
void addLayoutQualifier(const char *layoutQualifier)
const Face & postOriginCCWFace(GrSurfaceOrigin origin) const
const Face & singleSidedFace() const
const Face & postOriginCWFace(GrSurfaceOrigin origin) const
skgpu::BlendInfo getBlendInfo() const
static sk_sp< SkData > MakeWithoutCopy(const void *data, size_t length)
const void * data() const
void setMemory(const void *, size_t)
virtual void compileError(const char *shader, const char *errors)
sk_sp< SkData > PackCachedShaders(SkFourByteTag shaderType, const std::string shaders[], const SkSL::Program::Interface interfaces[], int numInterfaces, const ShaderMetadata *meta)
bool UnpackCachedShaders(SkReadBuffer *reader, std::string shaders[], SkSL::Program::Interface interfaces[], int numInterfaces, ShaderMetadata *meta)
SkFourByteTag GetType(SkReadBuffer *reader)
std::string PrettyPrint(const std::string &string)
static constexpr bool BlendShouldDisable(BlendEquation equation, BlendCoeff srcCoeff, BlendCoeff dstCoeff)
bool SkSLToHLSL(const SkSL::ShaderCaps *caps, const std::string &sksl, SkSL::ProgramKind programKind, const SkSL::ProgramSettings &settings, std::string *hlsl, SkSL::ProgramInterface *outInterface, ShaderErrorHandler *errorHandler)
ShaderCacheStrategy fShaderCacheStrategy
skgpu::BlendCoeff fDstBlend
skgpu::BlendCoeff fSrcBlend
std::shared_ptr< const fml::Mapping > data
#define TRACE_EVENT0(category_group, name)