Add GrD3DPipelineStateBuilder class.
This allows us to create the binary shaders for d3d. We generate spirv from sksl, then use spirv-cross to turn it into hlsl. Then that gets compiled into binary to be used in the pipeline. Adds hooks GrD3DOpsRenderPass to start creating the pipeline. Change-Id: Ie731dd945cdd9a00cebd78c1371a3d9784e4e1a3 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/284526 Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
1006a91ee8
commit
5fc5c8128c
@ -745,6 +745,8 @@ skia_direct3d_sources = [
|
||||
"$_src/gpu/d3d/GrD3DOpsRenderPass.h",
|
||||
"$_src/gpu/d3d/GrD3DPipelineState.cpp",
|
||||
"$_src/gpu/d3d/GrD3DPipelineState.h",
|
||||
"$_src/gpu/d3d/GrD3DPipelineStateBuilder.cpp",
|
||||
"$_src/gpu/d3d/GrD3DPipelineStateBuilder.h",
|
||||
"$_src/gpu/d3d/GrD3DRenderTarget.cpp",
|
||||
"$_src/gpu/d3d/GrD3DRenderTarget.h",
|
||||
"$_src/gpu/d3d/GrD3DResourceProvider.cpp",
|
||||
|
@ -68,7 +68,9 @@ private:
|
||||
uint32_t fCurrentUBOOffset = 0;
|
||||
uint32_t fRTHeightOffset = 0;
|
||||
|
||||
friend class GrD3DPipelineStateBuilder;
|
||||
friend class GrDawnProgramBuilder;
|
||||
|
||||
typedef GrGLSLUniformHandler INHERITED;
|
||||
};
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "src/gpu/d3d/GrD3DTexture.h"
|
||||
#include "src/gpu/d3d/GrD3DTextureRenderTarget.h"
|
||||
#include "src/gpu/d3d/GrD3DUtil.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
|
||||
#if GR_TEST_UTILS
|
||||
#include <DXProgrammableCapture.h>
|
||||
@ -43,7 +44,8 @@ GrD3DGpu::GrD3DGpu(GrContext* context, const GrContextOptions& contextOptions,
|
||||
|
||||
, fQueue(backendContext.fQueue)
|
||||
, fResourceProvider(this)
|
||||
, fOutstandingCommandLists(sizeof(OutstandingCommandList), kDefaultOutstandingAllocCnt) {
|
||||
, fOutstandingCommandLists(sizeof(OutstandingCommandList), kDefaultOutstandingAllocCnt)
|
||||
, fCompiler(new SkSL::Compiler()) {
|
||||
fCaps.reset(new GrD3DCaps(contextOptions,
|
||||
backendContext.fAdapter.get(),
|
||||
backendContext.fDevice.get()));
|
||||
|
@ -24,6 +24,10 @@ class GrPipeline;
|
||||
struct IDXGraphicsAnalysis;
|
||||
#endif
|
||||
|
||||
namespace SkSL {
|
||||
class Compiler;
|
||||
}
|
||||
|
||||
class GrD3DGpu : public GrGpu {
|
||||
public:
|
||||
static sk_sp<GrGpu> Make(const GrD3DBackendContext& backendContext, const GrContextOptions&,
|
||||
@ -94,6 +98,10 @@ public:
|
||||
|
||||
void checkFinishProcs() override {}
|
||||
|
||||
SkSL::Compiler* shaderCompiler() const {
|
||||
return fCompiler.get();
|
||||
}
|
||||
|
||||
private:
|
||||
enum class SyncQueue {
|
||||
kForce,
|
||||
@ -236,6 +244,8 @@ private:
|
||||
IDXGraphicsAnalysis* fGraphicsAnalysis;
|
||||
#endif
|
||||
|
||||
std::unique_ptr<SkSL::Compiler> fCompiler;
|
||||
|
||||
typedef GrGpu INHERITED;
|
||||
};
|
||||
|
||||
|
@ -8,8 +8,11 @@
|
||||
#include "src/gpu/d3d/GrD3DOpsRenderPass.h"
|
||||
|
||||
#include "src/gpu/GrContextPriv.h"
|
||||
#include "src/gpu/GrProgramDesc.h"
|
||||
#include "src/gpu/GrRenderTargetPriv.h"
|
||||
#include "src/gpu/d3d/GrD3DGpu.h"
|
||||
#include "src/gpu/d3d/GrD3DPipelineState.h"
|
||||
#include "src/gpu/d3d/GrD3DPipelineStateBuilder.h"
|
||||
|
||||
GrD3DOpsRenderPass::GrD3DOpsRenderPass(GrD3DGpu* gpu) : fGpu(gpu) {}
|
||||
|
||||
@ -30,3 +33,13 @@ bool GrD3DOpsRenderPass::set(GrRenderTarget* rt, GrSurfaceOrigin origin, const S
|
||||
GrD3DOpsRenderPass::~GrD3DOpsRenderPass() {}
|
||||
|
||||
GrGpu* GrD3DOpsRenderPass::gpu() { return fGpu; }
|
||||
|
||||
bool GrD3DOpsRenderPass::onBindPipeline(const GrProgramInfo& info, const SkRect& drawBounds) {
|
||||
GrProgramDesc desc = fGpu->caps()->makeDesc(fRenderTarget, info);
|
||||
std::unique_ptr<GrD3DPipelineState> pipelineState =
|
||||
GrD3DPipelineStateBuilder::CreatePipelineState(fGpu, fRenderTarget, desc, info);
|
||||
|
||||
// TODO: When this gets implemented fully make sure we bind the stencil reference value since
|
||||
// that is not part of the pipline in d3d12.
|
||||
return true;
|
||||
}
|
||||
|
@ -33,11 +33,7 @@ public:
|
||||
private:
|
||||
GrGpu* gpu() override;
|
||||
|
||||
bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) override {
|
||||
// TODO: When this gets implemented make sure we bind the stencil reference value since that
|
||||
// is not part of the pipline in d3d12.
|
||||
return true;
|
||||
}
|
||||
bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) override;
|
||||
void onSetScissorRect(const SkIRect&) override {}
|
||||
bool onBindTextures(const GrPrimitiveProcessor&, const GrSurfaceProxy* const primProcTextures[],
|
||||
const GrPipeline&) override {
|
||||
|
@ -268,6 +268,7 @@ static void fill_in_depth_stencil_state(const GrProgramInfo& programInfo,
|
||||
dsDesc->DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
|
||||
dsDesc->DepthFunc = D3D12_COMPARISON_FUNC_NEVER;
|
||||
dsDesc->StencilEnable = !stencilSettings.isDisabled();
|
||||
if (!stencilSettings.isDisabled()) {
|
||||
if (stencilSettings.isTwoSided()) {
|
||||
const auto& frontFace = stencilSettings.postOriginCCWFace(origin);
|
||||
const auto& backFace = stencilSettings.postOriginCCWFace(origin);
|
||||
@ -285,15 +286,30 @@ static void fill_in_depth_stencil_state(const GrProgramInfo& programInfo,
|
||||
setup_stencilop_desc(&dsDesc->FrontFace, stencilSettings.singleSidedFace());
|
||||
dsDesc->BackFace = dsDesc->FrontFace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<GrD3DPipelineState> GrD3DPipelineState::Make(GrD3DGpu* gpu,
|
||||
const GrProgramInfo& programInfo,
|
||||
gr_cp<ID3D12RootSignature> rootSig,
|
||||
gr_cp<ID3DBlob> vertexShader,
|
||||
gr_cp<ID3DBlob> geometryShader,
|
||||
gr_cp<ID3DBlob> pixelShader,
|
||||
DXGI_FORMAT renderTargetFormat,
|
||||
DXGI_FORMAT depthStencilFormat,
|
||||
unsigned int sampleQualityLevel) {
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
|
||||
|
||||
psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()),
|
||||
vertexShader->GetBufferSize() };
|
||||
psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()),
|
||||
pixelShader->GetBufferSize() };
|
||||
|
||||
if (geometryShader.get()) {
|
||||
psoDesc.GS = { reinterpret_cast<UINT8*>(geometryShader->GetBufferPointer()),
|
||||
geometryShader->GetBufferSize() };
|
||||
}
|
||||
|
||||
psoDesc.StreamOutput = {nullptr, 0, nullptr, 0, 0};
|
||||
|
||||
fill_in_blend_state(programInfo.pipeline(), &psoDesc.BlendState);
|
||||
@ -327,11 +343,8 @@ std::unique_ptr<GrD3DPipelineState> GrD3DPipelineState::Make(GrD3DGpu* gpu,
|
||||
psoDesc.CachedPSO = {nullptr, 0};
|
||||
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
|
||||
|
||||
// TODO: fill in the rest of the descriptor.
|
||||
// TODO: We need to create a real root descriptor before trying to make a pipeline
|
||||
#if 0
|
||||
psoDesc.pRootSignature = m_rootSignature.Get();
|
||||
psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() };
|
||||
psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() };
|
||||
ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState)));
|
||||
#endif
|
||||
|
||||
|
@ -18,6 +18,10 @@ class GrProgramInfo;
|
||||
class GrD3DPipelineState {
|
||||
public:
|
||||
static std::unique_ptr<GrD3DPipelineState> Make(GrD3DGpu* gpu, const GrProgramInfo&,
|
||||
gr_cp<ID3D12RootSignature> rootSig,
|
||||
gr_cp<ID3DBlob> vertexShader,
|
||||
gr_cp<ID3DBlob> geometryShader,
|
||||
gr_cp<ID3DBlob> pixelShader,
|
||||
DXGI_FORMAT renderTargetFormat,
|
||||
DXGI_FORMAT depthStencilFormat,
|
||||
unsigned int sampleQualityLevel);
|
||||
|
172
src/gpu/d3d/GrD3DPipelineStateBuilder.cpp
Normal file
172
src/gpu/d3d/GrD3DPipelineStateBuilder.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
//#include <d3dcompiler.h>
|
||||
|
||||
#include "src/gpu/d3d/GrD3DPipelineStateBuilder.h"
|
||||
|
||||
#include "include/gpu/GrContext.h"
|
||||
#include "include/gpu/d3d/GrD3DTypes.h"
|
||||
#include "src/core/SkTraceEvent.h"
|
||||
#include "src/gpu/GrAutoLocaleSetter.h"
|
||||
#include "src/gpu/GrContextPriv.h"
|
||||
#include "src/gpu/GrShaderCaps.h"
|
||||
#include "src/gpu/GrShaderUtils.h"
|
||||
#include "src/gpu/GrStencilSettings.h"
|
||||
#include "src/gpu/d3d/GrD3DGpu.h"
|
||||
#include "src/gpu/d3d/GrD3DRenderTarget.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
typedef size_t shader_size;
|
||||
|
||||
std::unique_ptr<GrD3DPipelineState> GrD3DPipelineStateBuilder::CreatePipelineState(
|
||||
GrD3DGpu* gpu,
|
||||
GrRenderTarget* renderTarget,
|
||||
const GrProgramDesc& desc,
|
||||
const GrProgramInfo& programInfo) {
|
||||
// ensure that we use "." as a decimal separator when creating SkSL code
|
||||
GrAutoLocaleSetter als("C");
|
||||
|
||||
// create a builder. This will be handed off to effects so they can use it to add
|
||||
// uniforms, varyings, textures, etc
|
||||
GrD3DPipelineStateBuilder builder(gpu, renderTarget, desc, programInfo);
|
||||
|
||||
if (!builder.emitAndInstallProcs()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return builder.finalize();
|
||||
}
|
||||
|
||||
GrD3DPipelineStateBuilder::GrD3DPipelineStateBuilder(GrD3DGpu* gpu,
|
||||
GrRenderTarget* renderTarget,
|
||||
const GrProgramDesc& desc,
|
||||
const GrProgramInfo& programInfo)
|
||||
: INHERITED(renderTarget, desc, programInfo)
|
||||
, fGpu(gpu)
|
||||
, fVaryingHandler(this)
|
||||
, fUniformHandler(this) {}
|
||||
|
||||
const GrCaps* GrD3DPipelineStateBuilder::caps() const {
|
||||
return fGpu->caps();
|
||||
}
|
||||
|
||||
void GrD3DPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
|
||||
outputColor.addLayoutQualifier("location = 0, index = 0");
|
||||
}
|
||||
|
||||
void GrD3DPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
|
||||
outputColor.addLayoutQualifier("location = 0, index = 1");
|
||||
}
|
||||
|
||||
void GrD3DPipelineStateBuilder::compileD3DProgram(SkSL::Program::Kind kind,
|
||||
const SkSL::String& sksl,
|
||||
const SkSL::Program::Settings& settings,
|
||||
ID3DBlob** shader,
|
||||
SkSL::Program::Inputs* outInputs) {
|
||||
auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler();
|
||||
std::unique_ptr<SkSL::Program> program = fGpu->shaderCompiler()->convertProgram(
|
||||
kind, sksl, settings);
|
||||
if (!program) {
|
||||
errorHandler->compileError(sksl.c_str(),
|
||||
fGpu->shaderCompiler()->errorText().c_str());
|
||||
return;
|
||||
}
|
||||
*outInputs = program->fInputs;
|
||||
SkSL::String outHLSL;
|
||||
if (!fGpu->shaderCompiler()->toHLSL(*program, &outHLSL)) {
|
||||
errorHandler->compileError(sksl.c_str(),
|
||||
fGpu->shaderCompiler()->errorText().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
const char* compileTarget = nullptr;
|
||||
switch (kind) {
|
||||
case SkSL::Program::kVertex_Kind:
|
||||
compileTarget = "vs_5_1";
|
||||
break;
|
||||
case SkSL::Program::kGeometry_Kind:
|
||||
compileTarget = "gs_5_1";
|
||||
break;
|
||||
case SkSL::Program::kFragment_Kind:
|
||||
compileTarget = "ps_5_1";
|
||||
break;
|
||||
default:
|
||||
SkUNREACHABLE;
|
||||
}
|
||||
|
||||
uint32_t compileFlags = 0;
|
||||
#ifdef SK_DEBUG
|
||||
// Enable better shader debugging with the graphics debugging tools.
|
||||
compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
|
||||
#endif
|
||||
// SPRIV-cross does matrix multiplication expecting row major matrices
|
||||
compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
|
||||
|
||||
// TODO: D3D Static Function
|
||||
gr_cp<ID3DBlob> errors;
|
||||
HRESULT hr = D3DCompile(outHLSL.c_str(), outHLSL.length(), nullptr, nullptr, nullptr, "main",
|
||||
compileTarget, compileFlags, 0, shader, &errors);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
errorHandler->compileError(outHLSL.c_str(),
|
||||
reinterpret_cast<char*>(errors->GetBufferPointer()));
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<GrD3DPipelineState> GrD3DPipelineStateBuilder::finalize() {
|
||||
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
|
||||
|
||||
// We need to enable the following extensions so that the compiler can correctly make spir-v
|
||||
// from our glsl shaders.
|
||||
fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
|
||||
fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
|
||||
fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
|
||||
fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
|
||||
|
||||
this->finalizeShaders();
|
||||
|
||||
SkSL::Program::Settings settings;
|
||||
settings.fCaps = this->caps()->shaderCaps();
|
||||
settings.fFlipY = this->origin() != kTopLeft_GrSurfaceOrigin;
|
||||
settings.fSharpenTextures =
|
||||
this->gpu()->getContext()->priv().options().fSharpenMipmappedTextures;
|
||||
settings.fRTHeightOffset = fUniformHandler.getRTHeightOffset();
|
||||
settings.fRTHeightBinding = 0;
|
||||
settings.fRTHeightSet = 0;
|
||||
|
||||
gr_cp<ID3DBlob> vertexShader;
|
||||
gr_cp<ID3DBlob> geometryShader;
|
||||
gr_cp<ID3DBlob> pixelShader;
|
||||
SkSL::Program::Inputs vertInputs, fragInputs, geomInputs;
|
||||
|
||||
this->compileD3DProgram(SkSL::Program::kVertex_Kind, fVS.fCompilerString, settings,
|
||||
&vertexShader, &vertInputs);
|
||||
this->compileD3DProgram(SkSL::Program::kFragment_Kind, fFS.fCompilerString, settings,
|
||||
&pixelShader, &fragInputs);
|
||||
|
||||
if (!vertexShader.get() || !pixelShader.get()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (this->primitiveProcessor().willUseGeoShader()) {
|
||||
this->compileD3DProgram(SkSL::Program::kGeometry_Kind, fGS.fCompilerString, settings,
|
||||
&geometryShader, &geomInputs);
|
||||
if (!geometryShader.get()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
gr_cp<ID3D12RootSignature> rootSignature;
|
||||
|
||||
const GrD3DRenderTarget* rt = static_cast<const GrD3DRenderTarget*>(fRenderTarget);
|
||||
return GrD3DPipelineState::Make(fGpu, fProgramInfo, std::move(rootSignature),
|
||||
std::move(vertexShader), std::move(geometryShader),
|
||||
std::move(pixelShader), rt->dxgiFormat(),
|
||||
rt->stencilDxgiFormat(), rt->sampleQualityLevel());
|
||||
}
|
67
src/gpu/d3d/GrD3DPipelineStateBuilder.h
Normal file
67
src/gpu/d3d/GrD3DPipelineStateBuilder.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrD3DPipelineStateBuilder_DEFINED
|
||||
#define GrD3DPipelineStateBuilder_DEFINED
|
||||
|
||||
#include "src/gpu/GrPipeline.h"
|
||||
#include "src/gpu/GrSpirvUniformHandler.h"
|
||||
#include "src/gpu/GrSpirvVaryingHandler.h"
|
||||
#include "src/gpu/d3d/GrD3DPipelineState.h"
|
||||
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
|
||||
#include "src/sksl/ir/SkSLProgram.h"
|
||||
|
||||
class GrProgramDesc;
|
||||
class GrD3DGpu;
|
||||
class GrVkRenderPass;
|
||||
class SkReader32;
|
||||
|
||||
class GrD3DPipelineStateBuilder : public GrGLSLProgramBuilder {
|
||||
public:
|
||||
/** Generates a pipeline state.
|
||||
*
|
||||
* The GrD3DPipelineState implements what is specified in the GrPipeline and
|
||||
* GrPrimitiveProcessor as input. After successful generation, the builder result objects are
|
||||
* available to be used.
|
||||
* @return the created pipeline if generation was successful; nullptr otherwise
|
||||
*/
|
||||
static std::unique_ptr<GrD3DPipelineState> CreatePipelineState(GrD3DGpu*,
|
||||
GrRenderTarget*,
|
||||
const GrProgramDesc&,
|
||||
const GrProgramInfo&);
|
||||
|
||||
const GrCaps* caps() const override;
|
||||
|
||||
GrD3DGpu* gpu() const { return fGpu; }
|
||||
|
||||
void finalizeFragmentOutputColor(GrShaderVar& outputColor) override;
|
||||
void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) override;
|
||||
|
||||
private:
|
||||
GrD3DPipelineStateBuilder(GrD3DGpu*, GrRenderTarget*, const GrProgramDesc&,
|
||||
const GrProgramInfo&);
|
||||
|
||||
std::unique_ptr<GrD3DPipelineState> finalize();
|
||||
|
||||
void compileD3DProgram(SkSL::Program::Kind kind,
|
||||
const SkSL::String& sksl,
|
||||
const SkSL::Program::Settings& settings,
|
||||
ID3DBlob** shader,
|
||||
SkSL::Program::Inputs* outInputs);
|
||||
|
||||
GrGLSLUniformHandler* uniformHandler() override { return &fUniformHandler; }
|
||||
const GrGLSLUniformHandler* uniformHandler() const override { return &fUniformHandler; }
|
||||
GrGLSLVaryingHandler* varyingHandler() override { return &fVaryingHandler; }
|
||||
|
||||
GrD3DGpu* fGpu;
|
||||
GrSpirvVaryingHandler fVaryingHandler;
|
||||
GrSpirvUniformHandler fUniformHandler;
|
||||
|
||||
typedef GrGLSLProgramBuilder INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
@ -158,3 +158,11 @@ GrD3DGpu* GrD3DRenderTarget::getD3DGpu() const {
|
||||
SkASSERT(!this->wasDestroyed());
|
||||
return static_cast<GrD3DGpu*>(this->getGpu());
|
||||
}
|
||||
|
||||
DXGI_FORMAT GrD3DRenderTarget::stencilDxgiFormat() const {
|
||||
if (auto stencil = this->renderTargetPriv().getStencilAttachment()) {
|
||||
auto d3dStencil = static_cast<GrD3DStencilAttachment*>(stencil);
|
||||
return d3dStencil->dxgiFormat();
|
||||
}
|
||||
return DXGI_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ public:
|
||||
|
||||
GrBackendRenderTarget getBackendRenderTarget() const override;
|
||||
|
||||
DXGI_FORMAT stencilDxgiFormat() const;
|
||||
|
||||
protected:
|
||||
GrD3DRenderTarget(GrD3DGpu* gpu,
|
||||
SkISize dimensions,
|
||||
|
@ -16,7 +16,7 @@
|
||||
class GrD3DGpu;
|
||||
|
||||
|
||||
class GrD3DStencilAttachment : public GrStencilAttachment, GrD3DTextureResource {
|
||||
class GrD3DStencilAttachment : public GrStencilAttachment, public GrD3DTextureResource {
|
||||
public:
|
||||
struct Format {
|
||||
DXGI_FORMAT fInternalFormat;
|
||||
|
@ -241,6 +241,7 @@ protected:
|
||||
friend class GrCCCoverageProcessor; // to access code().
|
||||
friend class GrGLSLProgramBuilder;
|
||||
friend class GrGLProgramBuilder;
|
||||
friend class GrD3DPipelineStateBuilder;
|
||||
friend class GrDawnProgramBuilder;
|
||||
friend class GrGLSLVaryingHandler; // to access noperspective interpolation feature.
|
||||
friend class GrGLPathProgramBuilder; // to access fInputs.
|
||||
|
@ -22,6 +22,20 @@ namespace SkSL {
|
||||
bool SPIRVtoHLSL(const String& spirv, String* hlsl) {
|
||||
spirv_cross::CompilerHLSL hlslCompiler((const uint32_t*)spirv.c_str(),
|
||||
spirv.size() / sizeof(uint32_t));
|
||||
|
||||
spirv_cross::CompilerGLSL::Options optionsGLSL;
|
||||
// Force all uninitialized variables to be 0, otherwise they will fail to compile
|
||||
// by FXC.
|
||||
optionsGLSL.force_zero_initialized_variables = true;
|
||||
|
||||
spirv_cross::CompilerHLSL::Options optionsHLSL;
|
||||
optionsHLSL.shader_model = 51;
|
||||
// PointCoord and PointSize are not supported in HLSL
|
||||
optionsHLSL.point_coord_compat = true;
|
||||
optionsHLSL.point_size_compat = true;
|
||||
|
||||
hlslCompiler.set_common_options(optionsGLSL);
|
||||
hlslCompiler.set_hlsl_options(optionsHLSL);
|
||||
hlsl->assign(hlslCompiler.compile());
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user