Windows sync for API changes

This commit is contained in:
Jack Andersen 2018-10-14 09:59:19 -10:00
parent f917d154b2
commit 592ffa1372
8 changed files with 341 additions and 435 deletions

View File

@ -267,6 +267,7 @@ if(NOT NX)
function(glslang_set_link_args TARGET) function(glslang_set_link_args TARGET)
endfunction(glslang_set_link_args) endfunction(glslang_set_link_args)
set(ENABLE_SPVREMAPPER On)
add_definitions("-DENABLE_OPT=0") add_definitions("-DENABLE_OPT=0")
add_subdirectory(glslang/glslang) add_subdirectory(glslang/glslang)
add_subdirectory(glslang/OGLCompilersDLL) add_subdirectory(glslang/OGLCompilersDLL)

View File

@ -16,37 +16,61 @@ extern pD3DCreateBlob D3DCreateBlobPROC;
namespace boo namespace boo
{ {
struct BaseGraphicsData;
class D3DDataFactory : public IGraphicsDataFactory class D3D11DataFactory : public IGraphicsDataFactory
{ {
public: public:
virtual ~D3DDataFactory() {} virtual ~D3D11DataFactory() = default;
Platform platform() const {return Platform::D3D11;}
const SystemChar* platformName() const {return _SYS_STR("D3D11");}
class Context final : public IGraphicsDataFactory::Context class Context final : public IGraphicsDataFactory::Context
{ {
friend class D3D11DataFactoryImpl;
D3D11DataFactory& m_parent;
boo::ObjToken<BaseGraphicsData> m_data;
Context(D3D11DataFactory& parent __BooTraceArgs);
~Context();
public: public:
bool bindingNeedsVertexFormat() const {return false;} Platform platform() const {return Platform::D3D11;}
virtual boo::ObjToken<IShaderPipeline> const SystemChar* platformName() const {return _SYS_STR("D3D11");}
newShaderPipeline(const char* vertSource, const char* fragSource,
ComPtr<ID3DBlob>* vertBlobOut, boo::ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
ComPtr<ID3DBlob>* fragBlobOut, boo::ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count);
ComPtr<ID3DBlob>* pipelineBlob,
const boo::ObjToken<IVertexFormat>& vtxFmt, boo::ObjToken<ITextureS> newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, TextureClampMode clampMode, const void* data, size_t sz);
ZTest depthTest, bool depthWrite, bool colorWrite, boo::ObjToken<ITextureSA> newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
bool alphaWrite, CullMode culling, bool overwriteAlpha=true)=0; TextureFormat fmt, TextureClampMode clampMode,
virtual boo::ObjToken<IShaderPipeline> const void* data, size_t sz);
newTessellationShaderPipeline( boo::ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode);
const char* vertSource, const char* fragSource, boo::ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
const char* controlSource, const char* evaluationSource, size_t colorBindCount, size_t depthBindCount);
ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut,
ComPtr<ID3DBlob>* controlBlobOut, ComPtr<ID3DBlob>* evaluationBlobOut, ObjToken<IShaderStage>
ComPtr<ID3DBlob>* pipelineBlob, newShaderStage(const uint8_t* data, size_t size, PipelineStage stage);
const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, uint32_t patchSize, ObjToken<IShaderPipeline>
ZTest depthTest, bool depthWrite, bool colorWrite, newShaderPipeline(ObjToken<IShaderStage> vertex, ObjToken<IShaderStage> fragment,
bool alphaWrite, CullMode culling, bool overwriteAlpha=true)=0; ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control,
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
const AdditionalPipelineInfo& additionalInfo);
boo::ObjToken<IShaderDataBinding>
newShaderDataBinding(const boo::ObjToken<IShaderPipeline>& pipeline,
const boo::ObjToken<IGraphicsBuffer>& vbo,
const boo::ObjToken<IGraphicsBuffer>& instVbo,
const boo::ObjToken<IGraphicsBuffer>& ibo,
size_t ubufCount, const boo::ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages,
const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, const boo::ObjToken<ITexture>* texs,
const int* bindIdxs, const bool* bindDepth,
size_t baseVert = 0, size_t baseInst = 0);
}; };
static std::vector<uint8_t> CompileHLSL(const char* source, PipelineStage stage);
}; };
} }

View File

@ -22,7 +22,7 @@ public:
~Context(); ~Context();
public: public:
Platform platform() const { return Platform::Metal; } Platform platform() const { return Platform::Metal; }
const SystemChar* platformName() const { return _S("Metal"); } const SystemChar* platformName() const { return _SYS_STR("Metal"); }
ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count); ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count); ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count);

View File

@ -904,7 +904,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine
if (!ret) if (!ret)
return {}; return {};
SystemString name = SystemString(APP->getFriendlyName()) + _S(" MIDI-In"); SystemString name = SystemString(APP->getFriendlyName()) + _SYS_STR(" MIDI-In");
auto port = virtualMIDICreatePortEx2PROC(name.c_str(), LPVM_MIDI_DATA_CB(VirtualMIDIReceiveProc), auto port = virtualMIDICreatePortEx2PROC(name.c_str(), LPVM_MIDI_DATA_CB(VirtualMIDIReceiveProc),
DWORD_PTR(static_cast<IMIDIReceiver*>(ret.get())), 512, DWORD_PTR(static_cast<IMIDIReceiver*>(ret.get())), 512,
TE_VM_FLAGS_PARSE_RX | TE_VM_FLAGS_INSTANTIATE_RX_ONLY); TE_VM_FLAGS_PARSE_RX | TE_VM_FLAGS_INSTANTIATE_RX_ONLY);
@ -927,7 +927,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine
if (!ret) if (!ret)
return {}; return {};
SystemString name = SystemString(APP->getFriendlyName()) + _S(" MIDI-Out"); SystemString name = SystemString(APP->getFriendlyName()) + _SYS_STR(" MIDI-Out");
auto port = virtualMIDICreatePortEx2PROC(name.c_str(), nullptr, 0, 512, auto port = virtualMIDICreatePortEx2PROC(name.c_str(), nullptr, 0, 512,
TE_VM_FLAGS_PARSE_TX | TE_VM_FLAGS_INSTANTIATE_TX_ONLY); TE_VM_FLAGS_PARSE_TX | TE_VM_FLAGS_INSTANTIATE_TX_ONLY);
if (!port) if (!port)
@ -949,7 +949,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine
if (!ret) if (!ret)
return {}; return {};
SystemString name = SystemString(APP->getFriendlyName()) + _S(" MIDI-In/Out"); SystemString name = SystemString(APP->getFriendlyName()) + _SYS_STR(" MIDI-In/Out");
auto port = virtualMIDICreatePortEx2PROC(name.c_str(), LPVM_MIDI_DATA_CB(VirtualMIDIReceiveProc), auto port = virtualMIDICreatePortEx2PROC(name.c_str(), LPVM_MIDI_DATA_CB(VirtualMIDIReceiveProc),
DWORD_PTR(static_cast<IMIDIReceiver*>(ret.get())), 512, DWORD_PTR(static_cast<IMIDIReceiver*>(ret.get())), 512,
TE_VM_FLAGS_SUPPORTED); TE_VM_FLAGS_SUPPORTED);

View File

@ -64,18 +64,6 @@ namespace boo
static logvisor::Module Log("boo::D3D11"); static logvisor::Module Log("boo::D3D11");
class D3D11DataFactory; class D3D11DataFactory;
struct D3D11ShareableShader : IShareableShader<D3D11DataFactory, D3D11ShareableShader>
{
ComPtr<ID3D11DeviceChild> m_shader;
ComPtr<ID3DBlob> m_vtxBlob;
D3D11ShareableShader(D3D11DataFactory& fac, uint64_t srcKey, uint64_t binKey,
ComPtr<ID3D11DeviceChild>&& s, ComPtr<ID3DBlob>&& vb)
: IShareableShader(fac, srcKey, binKey), m_shader(std::move(s)), m_vtxBlob(std::move(vb)) {}
D3D11ShareableShader(D3D11DataFactory& fac, uint64_t srcKey, uint64_t binKey,
ComPtr<ID3D11DeviceChild>&& s)
: IShareableShader(fac, srcKey, binKey), m_shader(std::move(s)) {}
};
static inline void ThrowIfFailed(HRESULT hr) static inline void ThrowIfFailed(HRESULT hr)
{ {
if (FAILED(hr)) if (FAILED(hr))
@ -101,7 +89,7 @@ static const D3D11_BIND_FLAG USE_TABLE[] =
class D3D11GraphicsBufferS : public GraphicsDataNode<IGraphicsBufferS> class D3D11GraphicsBufferS : public GraphicsDataNode<IGraphicsBufferS>
{ {
friend class D3D11DataFactory; friend class D3D11DataFactory::Context;
friend struct D3D11CommandQueue; friend struct D3D11CommandQueue;
size_t m_sz; size_t m_sz;
@ -125,7 +113,8 @@ public:
template <class DataCls> template <class DataCls>
class D3D11GraphicsBufferD : public GraphicsDataNode<IGraphicsBufferD, DataCls> class D3D11GraphicsBufferD : public GraphicsDataNode<IGraphicsBufferD, DataCls>
{ {
friend class D3D11DataFactory; friend class D3D11DataFactory::Context;
friend class D3D11DataFactoryImpl;
friend struct D3D11CommandQueue; friend struct D3D11CommandQueue;
D3D11CommandQueue* m_q; D3D11CommandQueue* m_q;
@ -161,7 +150,7 @@ public:
class D3D11TextureS : public GraphicsDataNode<ITextureS> class D3D11TextureS : public GraphicsDataNode<ITextureS>
{ {
friend class D3D11DataFactory; friend class D3D11DataFactory::Context;
D3D11TextureS(const boo::ObjToken<BaseGraphicsData>& parent, D3D11TextureS(const boo::ObjToken<BaseGraphicsData>& parent,
D3D11Context* ctx, size_t width, size_t height, size_t mips, D3D11Context* ctx, size_t width, size_t height, size_t mips,
@ -226,7 +215,7 @@ public:
class D3D11TextureSA : public GraphicsDataNode<ITextureSA> class D3D11TextureSA : public GraphicsDataNode<ITextureSA>
{ {
friend class D3D11DataFactory; friend class D3D11DataFactory::Context;
D3D11TextureSA(const boo::ObjToken<BaseGraphicsData>& parent, D3D11TextureSA(const boo::ObjToken<BaseGraphicsData>& parent,
D3D11Context* ctx, size_t width, size_t height, size_t layers, D3D11Context* ctx, size_t width, size_t height, size_t layers,
@ -287,7 +276,7 @@ public:
class D3D11TextureD : public GraphicsDataNode<ITextureD> class D3D11TextureD : public GraphicsDataNode<ITextureD>
{ {
friend class D3D11DataFactory; friend class D3D11DataFactory::Context;
friend struct D3D11CommandQueue; friend struct D3D11CommandQueue;
size_t m_width = 0; size_t m_width = 0;
@ -347,7 +336,7 @@ public:
class D3D11TextureR : public GraphicsDataNode<ITextureR> class D3D11TextureR : public GraphicsDataNode<ITextureR>
{ {
friend class D3D11DataFactory; friend class D3D11DataFactory::Context;
friend struct D3D11CommandQueue; friend struct D3D11CommandQueue;
size_t m_width = 0; size_t m_width = 0;
@ -491,45 +480,6 @@ static const DXGI_FORMAT SEMANTIC_TYPE_TABLE[] =
DXGI_FORMAT_R32G32B32A32_FLOAT DXGI_FORMAT_R32G32B32A32_FLOAT
}; };
struct D3D11VertexFormat : GraphicsDataNode<IVertexFormat>
{
size_t m_elementCount;
std::unique_ptr<D3D11_INPUT_ELEMENT_DESC[]> m_elements;
size_t m_stride = 0;
size_t m_instStride = 0;
D3D11VertexFormat(const boo::ObjToken<BaseGraphicsData>& parent,
size_t elementCount, const VertexElementDescriptor* elements)
: GraphicsDataNode<IVertexFormat>(parent), m_elementCount(elementCount),
m_elements(new D3D11_INPUT_ELEMENT_DESC[elementCount])
{
memset(m_elements.get(), 0, elementCount * sizeof(D3D11_INPUT_ELEMENT_DESC));
for (size_t i=0 ; i<elementCount ; ++i)
{
const VertexElementDescriptor* elemin = &elements[i];
D3D11_INPUT_ELEMENT_DESC& elem = m_elements[i];
int semantic = int(elemin->semantic & boo::VertexSemantic::SemanticMask);
elem.SemanticName = SEMANTIC_NAME_TABLE[semantic];
elem.SemanticIndex = elemin->semanticIdx;
elem.Format = SEMANTIC_TYPE_TABLE[semantic];
if ((elemin->semantic & boo::VertexSemantic::Instanced) != boo::VertexSemantic::None)
{
elem.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
elem.InstanceDataStepRate = 1;
elem.InputSlot = 1;
elem.AlignedByteOffset = m_instStride;
m_instStride += SEMANTIC_SIZE_TABLE[semantic];
}
else
{
elem.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
elem.AlignedByteOffset = m_stride;
m_stride += SEMANTIC_SIZE_TABLE[semantic];
}
}
}
};
static const D3D11_PRIMITIVE_TOPOLOGY PRIMITIVE_TABLE[] = static const D3D11_PRIMITIVE_TOPOLOGY PRIMITIVE_TABLE[] =
{ {
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
@ -553,32 +503,93 @@ static const D3D11_BLEND BLEND_FACTOR_TABLE[] =
D3D11_BLEND_INV_SRC1_COLOR D3D11_BLEND_INV_SRC1_COLOR
}; };
class D3D11ShaderStage : public GraphicsDataNode<IShaderStage>
{
friend class D3D11DataFactory;
ComPtr<ID3D11DeviceChild> m_shader;
D3D11ShaderStage(const boo::ObjToken<BaseGraphicsData>& parent, D3D11Context* ctx,
const uint8_t* data, size_t size, PipelineStage stage)
: GraphicsDataNode<IShaderStage>(parent)
{
switch (stage)
{
case PipelineStage::Vertex:
{
ThrowIfFailed(D3DCreateBlobPROC(size, &m_vtxBlob));
memcpy(m_vtxBlob->GetBufferPointer(), data, size);
ComPtr<ID3D11VertexShader> vShader;
ThrowIfFailed(ctx->m_dev->CreateVertexShader(data, size, nullptr, &vShader));
m_shader = vShader;
break;
}
case PipelineStage::Fragment:
{
ComPtr<ID3D11PixelShader> pShader;
ThrowIfFailed(ctx->m_dev->CreatePixelShader(data, size, nullptr, &pShader));
m_shader = pShader;
break;
}
case PipelineStage::Geometry:
{
ComPtr<ID3D11GeometryShader> gShader;
ThrowIfFailed(ctx->m_dev->CreateGeometryShader(data, size, nullptr, &gShader));
m_shader = gShader;
break;
}
case PipelineStage::Control:
{
ComPtr<ID3D11HullShader> hShader;
ThrowIfFailed(ctx->m_dev->CreateHullShader(data, size, nullptr, &hShader));
m_shader = hShader;
break;
}
case PipelineStage::Evaluation:
{
ComPtr<ID3D11DomainShader> dShader;
ThrowIfFailed(ctx->m_dev->CreateDomainShader(data, size, nullptr, &dShader));
m_shader = dShader;
break;
}
default:
break;
}
}
public:
ComPtr<ID3DBlob> m_vtxBlob;
template <class T>
void shader(ComPtr<T>& ret) const { m_shader.As<T>(&ret); }
};
class D3D11ShaderPipeline : public GraphicsDataNode<IShaderPipeline> class D3D11ShaderPipeline : public GraphicsDataNode<IShaderPipeline>
{ {
protected:
friend class D3D11DataFactory; friend class D3D11DataFactory;
friend struct D3D11ShaderDataBinding; friend struct D3D11ShaderDataBinding;
boo::ObjToken<IVertexFormat> m_vtxFmt;
D3D11ShareableShader::Token m_vert;
D3D11ShareableShader::Token m_pixel;
D3D11ShaderPipeline(const boo::ObjToken<BaseGraphicsData>& parent, D3D11ShaderPipeline(const boo::ObjToken<BaseGraphicsData>& parent,
D3D11Context* ctx, D3D11Context* ctx,
D3D11ShareableShader::Token&& vert, ObjToken<IShaderStage> vertex,
D3D11ShareableShader::Token&& pixel, ObjToken<IShaderStage> fragment,
const boo::ObjToken<IVertexFormat>& vtxFmt, ObjToken<IShaderStage> geometry,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, ObjToken<IShaderStage> control,
ZTest depthTest, bool depthWrite, bool colorWrite, ObjToken<IShaderStage> evaluation,
bool alphaWrite, bool overwriteAlpha, CullMode culling) const VertexFormatInfo& vtxFmt,
: GraphicsDataNode<IShaderPipeline>(parent), m_vtxFmt(vtxFmt), const AdditionalPipelineInfo& info)
m_vert(std::move(vert)), m_pixel(std::move(pixel)), : GraphicsDataNode<IShaderPipeline>(parent),
m_topology(PRIMITIVE_TABLE[int(prim)]) m_topology(PRIMITIVE_TABLE[int(info.prim)])
{ {
m_vert.get().m_shader.As<ID3D11VertexShader>(&m_vShader); if (auto* s = vertex.cast<D3D11ShaderStage>())
m_pixel.get().m_shader.As<ID3D11PixelShader>(&m_pShader); s->shader(m_vShader);
if (auto* s = fragment.cast<D3D11ShaderStage>())
s->shader(m_pShader);
if (auto* s = geometry.cast<D3D11ShaderStage>())
s->shader(m_gShader);
if (auto* s = control.cast<D3D11ShaderStage>())
s->shader(m_hShader);
if (auto* s = evaluation.cast<D3D11ShaderStage>())
s->shader(m_dShader);
D3D11_CULL_MODE cullMode; D3D11_CULL_MODE cullMode;
switch (culling) switch (info.culling)
{ {
case CullMode::None: case CullMode::None:
default: default:
@ -598,9 +609,9 @@ protected:
ThrowIfFailed(ctx->m_dev->CreateRasterizerState(&rasDesc, &m_rasState)); ThrowIfFailed(ctx->m_dev->CreateRasterizerState(&rasDesc, &m_rasState));
CD3D11_DEPTH_STENCIL_DESC dsDesc(D3D11_DEFAULT); CD3D11_DEPTH_STENCIL_DESC dsDesc(D3D11_DEFAULT);
dsDesc.DepthEnable = depthTest != ZTest::None; dsDesc.DepthEnable = info.depthTest != ZTest::None;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK(depthWrite); dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK(info.depthWrite);
switch (depthTest) switch (info.depthTest)
{ {
case ZTest::None: case ZTest::None:
default: default:
@ -622,13 +633,13 @@ protected:
ThrowIfFailed(ctx->m_dev->CreateDepthStencilState(&dsDesc, &m_dsState)); ThrowIfFailed(ctx->m_dev->CreateDepthStencilState(&dsDesc, &m_dsState));
CD3D11_BLEND_DESC blDesc(D3D11_DEFAULT); CD3D11_BLEND_DESC blDesc(D3D11_DEFAULT);
blDesc.RenderTarget[0].BlendEnable = (dstFac != BlendFactor::Zero); blDesc.RenderTarget[0].BlendEnable = (info.dstFac != BlendFactor::Zero);
if (srcFac == BlendFactor::Subtract || dstFac == BlendFactor::Subtract) if (info.srcFac == BlendFactor::Subtract || info.dstFac == BlendFactor::Subtract)
{ {
blDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; blDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
blDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_REV_SUBTRACT; blDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_REV_SUBTRACT;
if (overwriteAlpha) if (info.overwriteAlpha)
{ {
blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
@ -643,56 +654,84 @@ protected:
} }
else else
{ {
blDesc.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)]; blDesc.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(info.srcFac)];
blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)]; blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(info.dstFac)];
blDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
if (overwriteAlpha) if (info.overwriteAlpha)
{ {
blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
} }
else else
{ {
blDesc.RenderTarget[0].SrcBlendAlpha = BLEND_FACTOR_TABLE[int(srcFac)]; blDesc.RenderTarget[0].SrcBlendAlpha = BLEND_FACTOR_TABLE[int(info.srcFac)];
blDesc.RenderTarget[0].DestBlendAlpha = BLEND_FACTOR_TABLE[int(dstFac)]; blDesc.RenderTarget[0].DestBlendAlpha = BLEND_FACTOR_TABLE[int(info.dstFac)];
} }
blDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
} }
blDesc.RenderTarget[0].RenderTargetWriteMask = blDesc.RenderTarget[0].RenderTargetWriteMask =
(colorWrite ? (D3D11_COLOR_WRITE_ENABLE_RED | (info.colorWrite ? (D3D11_COLOR_WRITE_ENABLE_RED |
D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_GREEN |
D3D11_COLOR_WRITE_ENABLE_BLUE) : 0) | D3D11_COLOR_WRITE_ENABLE_BLUE) : 0) |
(alphaWrite ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0); (info.alphaWrite ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0);
ThrowIfFailed(ctx->m_dev->CreateBlendState(&blDesc, &m_blState)); ThrowIfFailed(ctx->m_dev->CreateBlendState(&blDesc, &m_blState));
const auto& vertBuf = m_vert.get().m_vtxBlob; {
D3D11VertexFormat* cvtxFmt = vtxFmt.cast<D3D11VertexFormat>(); std::vector<D3D11_INPUT_ELEMENT_DESC> elements(vtxFmt.elementCount);
ThrowIfFailed(ctx->m_dev->CreateInputLayout(cvtxFmt->m_elements.get(), cvtxFmt->m_elementCount,
vertBuf->GetBufferPointer(), vertBuf->GetBufferSize(), &m_inLayout)); for (size_t i=0 ; i<vtxFmt.elementCount ; ++i)
{
const VertexElementDescriptor* elemin = &vtxFmt.elements[i];
D3D11_INPUT_ELEMENT_DESC& elem = elements[i];
int semantic = int(elemin->semantic & boo::VertexSemantic::SemanticMask);
elem.SemanticName = SEMANTIC_NAME_TABLE[semantic];
elem.SemanticIndex = elemin->semanticIdx;
elem.Format = SEMANTIC_TYPE_TABLE[semantic];
if ((elemin->semantic & boo::VertexSemantic::Instanced) != boo::VertexSemantic::None)
{
elem.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
elem.InstanceDataStepRate = 1;
elem.InputSlot = 1;
elem.AlignedByteOffset = m_instStride;
m_instStride += SEMANTIC_SIZE_TABLE[semantic];
}
else
{
elem.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
elem.AlignedByteOffset = m_stride;
m_stride += SEMANTIC_SIZE_TABLE[semantic];
}
}
const auto& vertBuf = vertex.cast<D3D11ShaderStage>()->m_vtxBlob;
ThrowIfFailed(ctx->m_dev->CreateInputLayout(elements.data(), vtxFmt.elementCount,
vertBuf->GetBufferPointer(), vertBuf->GetBufferSize(), &m_inLayout));
}
} }
public: public:
ComPtr<ID3D11VertexShader> m_vShader; ComPtr<ID3D11VertexShader> m_vShader;
ComPtr<ID3D11PixelShader> m_pShader; ComPtr<ID3D11PixelShader> m_pShader;
ComPtr<ID3D11GeometryShader> m_gShader;
ComPtr<ID3D11HullShader> m_hShader;
ComPtr<ID3D11DomainShader> m_dShader;
ComPtr<ID3D11RasterizerState> m_rasState; ComPtr<ID3D11RasterizerState> m_rasState;
ComPtr<ID3D11DepthStencilState> m_dsState; ComPtr<ID3D11DepthStencilState> m_dsState;
ComPtr<ID3D11BlendState> m_blState; ComPtr<ID3D11BlendState> m_blState;
ComPtr<ID3D11InputLayout> m_inLayout; ComPtr<ID3D11InputLayout> m_inLayout;
D3D11_PRIMITIVE_TOPOLOGY m_topology; D3D11_PRIMITIVE_TOPOLOGY m_topology;
size_t m_stride = 0;
size_t m_instStride = 0;
~D3D11ShaderPipeline() = default; ~D3D11ShaderPipeline() = default;
D3D11ShaderPipeline& operator=(const D3D11ShaderPipeline&) = delete; D3D11ShaderPipeline& operator=(const D3D11ShaderPipeline&) = delete;
D3D11ShaderPipeline(const D3D11ShaderPipeline&) = delete; D3D11ShaderPipeline(const D3D11ShaderPipeline&) = delete;
virtual void bindExtraStages(ID3D11DeviceContext* ctx)
{
ctx->HSSetShader(nullptr, nullptr, 0);
ctx->DSSetShader(nullptr, nullptr, 0);
}
void bind(ID3D11DeviceContext* ctx) void bind(ID3D11DeviceContext* ctx)
{ {
ctx->VSSetShader(m_vShader.Get(), nullptr, 0); ctx->VSSetShader(m_vShader.Get(), nullptr, 0);
ctx->PSSetShader(m_pShader.Get(), nullptr, 0); ctx->PSSetShader(m_pShader.Get(), nullptr, 0);
bindExtraStages(ctx); ctx->GSSetShader(m_gShader.Get(), nullptr, 0);
ctx->HSSetShader(m_hShader.Get(), nullptr, 0);
ctx->DSSetShader(m_dShader.Get(), nullptr, 0);
ctx->RSSetState(m_rasState.Get()); ctx->RSSetState(m_rasState.Get());
ctx->OMSetDepthStencilState(m_dsState.Get(), 0); ctx->OMSetDepthStencilState(m_dsState.Get(), 0);
ctx->OMSetBlendState(m_blState.Get(), nullptr, 0xffffffff); ctx->OMSetBlendState(m_blState.Get(), nullptr, 0xffffffff);
@ -701,44 +740,6 @@ public:
} }
}; };
class D3D11TessellationShaderPipeline : public D3D11ShaderPipeline
{
friend class D3D11DataFactory;
friend struct D3D11ShaderDataBinding;
D3D11ShareableShader::Token m_hull;
D3D11ShareableShader::Token m_domain;
ComPtr<ID3D11HullShader> m_hShader;
ComPtr<ID3D11DomainShader> m_dShader;
D3D11TessellationShaderPipeline(const boo::ObjToken<BaseGraphicsData>& parent,
D3D11Context* ctx,
D3D11ShareableShader::Token&& vert,
D3D11ShareableShader::Token&& pixel,
D3D11ShareableShader::Token&& hull,
D3D11ShareableShader::Token&& domain,
const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, uint32_t patchSize,
ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, bool overwriteAlpha, CullMode culling)
: D3D11ShaderPipeline(parent, ctx, std::move(vert), std::move(pixel), vtxFmt, srcFac, dstFac,
Primitive::Patches, depthTest, depthWrite, colorWrite, alphaWrite,
overwriteAlpha, culling), m_hull(std::move(hull)), m_domain(std::move(domain))
{
m_topology = D3D11_PRIMITIVE_TOPOLOGY(int(D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST) + patchSize - 1);
m_hull.get().m_shader.As<ID3D11HullShader>(&m_hShader);
m_domain.get().m_shader.As<ID3D11DomainShader>(&m_dShader);
}
public:
~D3D11TessellationShaderPipeline() = default;
void bindExtraStages(ID3D11DeviceContext* ctx)
{
ctx->HSSetShader(m_hShader.Get(), nullptr, 0);
ctx->DSSetShader(m_dShader.Get(), nullptr, 0);
}
};
struct D3D11ShaderDataBinding : public GraphicsDataNode<IShaderDataBinding> struct D3D11ShaderDataBinding : public GraphicsDataNode<IShaderDataBinding>
{ {
boo::ObjToken<IShaderPipeline> m_pipeline; boo::ObjToken<IShaderPipeline> m_pipeline;
@ -779,9 +780,8 @@ struct D3D11ShaderDataBinding : public GraphicsDataNode<IShaderDataBinding>
m_texs.reserve(texCount); m_texs.reserve(texCount);
D3D11ShaderPipeline* cpipeline = m_pipeline.cast<D3D11ShaderPipeline>(); D3D11ShaderPipeline* cpipeline = m_pipeline.cast<D3D11ShaderPipeline>();
D3D11VertexFormat* vtxFmt = cpipeline->m_vtxFmt.cast<D3D11VertexFormat>(); m_baseOffsets[0] = UINT(baseVert * cpipeline->m_stride);
m_baseOffsets[0] = UINT(baseVert * vtxFmt->m_stride); m_baseOffsets[1] = UINT(baseInst * cpipeline->m_instStride);
m_baseOffsets[1] = UINT(baseInst * vtxFmt->m_instStride);
if (ubufStages) if (ubufStages)
{ {
@ -1016,7 +1016,7 @@ struct D3D11ShaderDataBinding : public GraphicsDataNode<IShaderDataBinding>
struct D3D11CommandQueue : IGraphicsCommandQueue struct D3D11CommandQueue : IGraphicsCommandQueue
{ {
Platform platform() const {return IGraphicsDataFactory::Platform::D3D11;} Platform platform() const {return IGraphicsDataFactory::Platform::D3D11;}
const SystemChar* platformName() const {return _S("D3D11");} const SystemChar* platformName() const {return _SYS_STR("D3D11");}
D3D11Context* m_ctx; D3D11Context* m_ctx;
D3D11Context::Window* m_windowCtx; D3D11Context::Window* m_windowCtx;
IGraphicsContext* m_parent; IGraphicsContext* m_parent;
@ -1304,32 +1304,36 @@ void D3D11TextureD::unmap()
m_q->m_dynamicLock.unlock(); m_q->m_dynamicLock.unlock();
} }
class D3D11DataFactory : public D3DDataFactory, public GraphicsDataFactoryHead class D3D11DataFactoryImpl : public D3D11DataFactory, public GraphicsDataFactoryHead
{ {
friend struct D3D11CommandQueue; friend struct D3D11CommandQueue;
friend class D3D11DataFactory::Context;
IGraphicsContext* m_parent; IGraphicsContext* m_parent;
struct D3D11Context* m_ctx; struct D3D11Context* m_ctx;
std::unordered_map<uint64_t, std::unique_ptr<D3D11ShareableShader>> m_sharedShaders;
std::unordered_map<uint64_t, uint64_t> m_sourceToBinary;
float m_gamma = 1.f; float m_gamma = 1.f;
ObjToken<IShaderPipeline> m_gammaShader; ObjToken<IShaderPipeline> m_gammaShader;
ObjToken<ITextureD> m_gammaLUT; ObjToken<ITextureD> m_gammaLUT;
ObjToken<IGraphicsBufferS> m_gammaVBO; ObjToken<IGraphicsBufferS> m_gammaVBO;
ObjToken<IVertexFormat> m_gammaVFMT;
ObjToken<IShaderDataBinding> m_gammaBinding; ObjToken<IShaderDataBinding> m_gammaBinding;
void SetupGammaResources() void SetupGammaResources()
{ {
commitTransaction([this](IGraphicsDataFactory::Context& ctx) commitTransaction([this](IGraphicsDataFactory::Context& ctx)
{ {
auto vertexHlsl = D3D11DataFactory::CompileHLSL(GammaVS, PipelineStage::Vertex);
auto vertexShader = ctx.newShaderStage(vertexHlsl, PipelineStage::Vertex);
auto fragmentHlsl = D3D11DataFactory::CompileHLSL(GammaFS, PipelineStage::Fragment);
auto fragmentShader = ctx.newShaderStage(fragmentHlsl, PipelineStage::Fragment);
const VertexElementDescriptor vfmt[] = { const VertexElementDescriptor vfmt[] = {
{nullptr, nullptr, VertexSemantic::Position4}, {VertexSemantic::Position4},
{nullptr, nullptr, VertexSemantic::UV4} {VertexSemantic::UV4}
}; };
m_gammaVFMT = ctx.newVertexFormat(2, vfmt); AdditionalPipelineInfo info =
m_gammaShader = static_cast<Context&>(ctx).newShaderPipeline(GammaVS, GammaFS, {
nullptr, nullptr, nullptr, m_gammaVFMT, BlendFactor::One, BlendFactor::Zero, BlendFactor::One, BlendFactor::Zero,
Primitive::TriStrips, ZTest::None, false, true, false, CullMode::None, true); Primitive::TriStrips, ZTest::None, false, true, false, CullMode::None
};
m_gammaShader = ctx.newShaderPipeline(vertexShader, fragmentShader, vfmt, info);
m_gammaLUT = ctx.newDynamicTexture(256, 256, TextureFormat::I16, TextureClampMode::ClampToEdge); m_gammaLUT = ctx.newDynamicTexture(256, 256, TextureFormat::I16, TextureClampMode::ClampToEdge);
setDisplayGamma(1.f); setDisplayGamma(1.f);
const struct Vert { const struct Vert {
@ -1343,14 +1347,14 @@ class D3D11DataFactory : public D3DDataFactory, public GraphicsDataFactoryHead
}; };
m_gammaVBO = ctx.newStaticBuffer(BufferUse::Vertex, verts, 32, 4); m_gammaVBO = ctx.newStaticBuffer(BufferUse::Vertex, verts, 32, 4);
ObjToken<ITexture> texs[] = {{}, m_gammaLUT.get()}; ObjToken<ITexture> texs[] = {{}, m_gammaLUT.get()};
m_gammaBinding = ctx.newShaderDataBinding(m_gammaShader, m_gammaVFMT, m_gammaVBO.get(), {}, {}, m_gammaBinding = ctx.newShaderDataBinding(m_gammaShader, m_gammaVBO.get(), {}, {},
0, nullptr, nullptr, 2, texs, nullptr, nullptr); 0, nullptr, nullptr, 2, texs, nullptr, nullptr);
return true; return true;
} BooTrace); } BooTrace);
} }
public: public:
D3D11DataFactory(IGraphicsContext* parent, D3D11Context* ctx) D3D11DataFactoryImpl(IGraphicsContext* parent, D3D11Context* ctx)
: m_parent(parent), m_ctx(ctx) : m_parent(parent), m_ctx(ctx)
{ {
UINT qLevels; UINT qLevels;
@ -1359,241 +1363,6 @@ public:
m_ctx->m_sampleCount = flp2(m_ctx->m_sampleCount - 1); m_ctx->m_sampleCount = flp2(m_ctx->m_sampleCount - 1);
} }
Platform platform() const {return Platform::D3D11;}
const SystemChar* platformName() const {return _S("D3D11");}
#if _DEBUG && 0
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0
#else
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
uint64_t Compile(ComPtr<ID3DBlob>& blobOut, const char* source, uint64_t srcKey, const char* shaderType)
{
ComPtr<ID3DBlob> errBlob;
if (FAILED(D3DCompilePROC(source, strlen(source), "Boo HLSL Source", nullptr, nullptr, "main",
shaderType, BOO_D3DCOMPILE_FLAG, 0, &blobOut, &errBlob)))
{
printf("%s\n", source);
Log.report(logvisor::Fatal, "error compiling shader: %s", errBlob->GetBufferPointer());
}
XXH64_state_t hashState;
XXH64_reset(&hashState, 0);
XXH64_update(&hashState, blobOut->GetBufferPointer(), blobOut->GetBufferSize());
uint64_t binKey = XXH64_digest(&hashState);
m_sourceToBinary[srcKey] = binKey;
return binKey;
}
D3D11ShareableShader::Token PrepareShaderStage(const char* source, ComPtr<ID3DBlob>* blobOut,
const char* shaderType, const std::function<ComPtr<ID3D11DeviceChild>(ID3DBlob* blob)>& MakeShader)
{
XXH64_state_t hashState;
uint64_t srcHash = 0;
uint64_t binHash = 0;
XXH64_reset(&hashState, 0);
if (source)
{
XXH64_update(&hashState, source, strlen(source));
srcHash = XXH64_digest(&hashState);
auto binSearch = m_sourceToBinary.find(srcHash);
if (binSearch != m_sourceToBinary.cend())
binHash = binSearch->second;
}
else if (blobOut && *blobOut)
{
XXH64_update(&hashState, (*blobOut)->GetBufferPointer(), (*blobOut)->GetBufferSize());
binHash = XXH64_digest(&hashState);
}
if (blobOut && !*blobOut)
binHash = Compile(*blobOut, source, srcHash, shaderType);
auto search = binHash ? m_sharedShaders.find(binHash) : m_sharedShaders.end();
if (search != m_sharedShaders.end())
{
return search->second->lock();
}
else
{
ComPtr<ID3DBlob> useBlob;
if (blobOut)
useBlob = *blobOut;
else
binHash = Compile(useBlob, source, srcHash, shaderType);
ComPtr<ID3D11DeviceChild> comShader = MakeShader(useBlob.Get());
auto it =
m_sharedShaders.emplace(std::make_pair(binHash,
std::make_unique<D3D11ShareableShader>(*this, srcHash, binHash,
std::move(comShader), std::move(useBlob)))).first;
return it->second->lock();
}
}
class Context : public D3DDataFactory::Context
{
friend class D3D11DataFactory;
D3D11DataFactory& m_parent;
boo::ObjToken<BaseGraphicsData> m_data;
Context(D3D11DataFactory& parent __BooTraceArgs)
: m_parent(parent), m_data(new BaseGraphicsData(parent __BooTraceArgsUse)) {}
public:
Platform platform() const {return Platform::D3D11;}
const SystemChar* platformName() const {return _S("D3D11");}
boo::ObjToken<IGraphicsBufferS> newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
{
return {new D3D11GraphicsBufferS(m_data, use, m_parent.m_ctx, data, stride, count)};
}
boo::ObjToken<IGraphicsBufferD> newDynamicBuffer(BufferUse use, size_t stride, size_t count)
{
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent.m_parent->getCommandQueue());
return {new D3D11GraphicsBufferD<BaseGraphicsData>(m_data, q, use, m_parent.m_ctx, stride, count)};
}
boo::ObjToken<ITextureS> newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
TextureClampMode clampMode, const void* data, size_t sz)
{
return {new D3D11TextureS(m_data, m_parent.m_ctx, width, height, mips, fmt, data, sz)};
}
boo::ObjToken<ITextureSA> newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, TextureClampMode clampMode, const void* data, size_t sz)
{
return {new D3D11TextureSA(m_data, m_parent.m_ctx, width, height, layers, mips, fmt, data, sz)};
}
boo::ObjToken<ITextureD> newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode)
{
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent.m_parent->getCommandQueue());
return {new D3D11TextureD(m_data, q, m_parent.m_ctx, width, height, fmt)};
}
boo::ObjToken<ITextureR> newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
size_t colorBindCount, size_t depthBindCount)
{
return {new D3D11TextureR(m_data, m_parent.m_ctx, width, height, m_parent.m_ctx->m_sampleCount,
colorBindCount, depthBindCount)};
}
boo::ObjToken<IVertexFormat> newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
size_t baseVert, size_t baseInst)
{
return {new struct D3D11VertexFormat(m_data, elementCount, elements)};
}
boo::ObjToken<IShaderPipeline> newShaderPipeline
(const char* vertSource, const char* fragSource,
ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut,
ComPtr<ID3DBlob>* pipelineBlob, const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling, bool overwriteAlpha)
{
struct D3D11Context* ctx = m_parent.m_ctx;
D3D11ShareableShader::Token vertShader =
m_parent.PrepareShaderStage(vertSource, vertBlobOut, "vs_5_0", [ctx](ID3DBlob* blob)
{
ComPtr<ID3D11VertexShader> vShader;
ThrowIfFailed(ctx->m_dev->CreateVertexShader(blob->GetBufferPointer(),
blob->GetBufferSize(), nullptr, &vShader));
return vShader;
});
D3D11ShareableShader::Token fragShader =
m_parent.PrepareShaderStage(fragSource, fragBlobOut, "ps_5_0", [ctx](ID3DBlob* blob)
{
ComPtr<ID3D11PixelShader> pShader;
ThrowIfFailed(ctx->m_dev->CreatePixelShader(blob->GetBufferPointer(),
blob->GetBufferSize(), nullptr, &pShader));
return pShader;
});
return {new D3D11ShaderPipeline(m_data, ctx,
std::move(vertShader), std::move(fragShader),
vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite, colorWrite,
alphaWrite, overwriteAlpha, culling)};
}
boo::ObjToken<IShaderPipeline> newTessellationShaderPipeline
(const char* vertSource, const char* fragSource,
const char* controlSource, const char* evaluationSource,
ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut,
ComPtr<ID3DBlob>* controlBlobOut, ComPtr<ID3DBlob>* evaluationBlobOut,
ComPtr<ID3DBlob>* pipelineBlob,
const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, uint32_t patchSize,
ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling, bool overwriteAlpha)
{
struct D3D11Context* ctx = m_parent.m_ctx;
D3D11ShareableShader::Token vertShader =
m_parent.PrepareShaderStage(vertSource, vertBlobOut, "vs_5_0", [ctx](ID3DBlob* blob)
{
ComPtr<ID3D11VertexShader> vShader;
ThrowIfFailed(ctx->m_dev->CreateVertexShader(blob->GetBufferPointer(),
blob->GetBufferSize(), nullptr, &vShader));
return vShader;
});
D3D11ShareableShader::Token fragShader =
m_parent.PrepareShaderStage(fragSource, fragBlobOut, "ps_5_0", [ctx](ID3DBlob* blob)
{
ComPtr<ID3D11PixelShader> pShader;
ThrowIfFailed(ctx->m_dev->CreatePixelShader(blob->GetBufferPointer(),
blob->GetBufferSize(), nullptr, &pShader));
return pShader;
});
D3D11ShareableShader::Token controlShader =
m_parent.PrepareShaderStage(controlSource, controlBlobOut, "hs_5_0", [ctx](ID3DBlob* blob)
{
ComPtr<ID3D11HullShader> hShader;
ThrowIfFailed(ctx->m_dev->CreateHullShader(blob->GetBufferPointer(),
blob->GetBufferSize(), nullptr, &hShader));
return hShader;
});
D3D11ShareableShader::Token evaluationShader =
m_parent.PrepareShaderStage(evaluationSource, evaluationBlobOut, "ds_5_0", [ctx](ID3DBlob* blob)
{
ComPtr<ID3D11DomainShader> dShader;
ThrowIfFailed(ctx->m_dev->CreateDomainShader(blob->GetBufferPointer(),
blob->GetBufferSize(), nullptr, &dShader));
return dShader;
});
return {new D3D11TessellationShaderPipeline(m_data, ctx,
std::move(vertShader), std::move(fragShader),
std::move(controlShader), std::move(evaluationShader),
vtxFmt, srcFac, dstFac, patchSize, depthTest, depthWrite, colorWrite,
alphaWrite, overwriteAlpha, culling)};
}
boo::ObjToken<IShaderDataBinding> newShaderDataBinding(
const boo::ObjToken<IShaderPipeline>& pipeline,
const boo::ObjToken<IVertexFormat>& vtxFormat,
const boo::ObjToken<IGraphicsBuffer>& vbuf,
const boo::ObjToken<IGraphicsBuffer>& instVbo,
const boo::ObjToken<IGraphicsBuffer>& ibuf,
size_t ubufCount, const boo::ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages,
const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, const boo::ObjToken<ITexture>* texs,
const int* texBindIdx, const bool* depthBind,
size_t baseVert, size_t baseInst)
{
return {new D3D11ShaderDataBinding(m_data, m_parent.m_ctx, pipeline, vbuf, instVbo, ibuf,
ubufCount, ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs,
texBindIdx, depthBind, baseVert, baseInst)};
}
};
boo::ObjToken<IGraphicsBufferD> newPoolBuffer(BufferUse use, size_t stride, size_t count __BooTraceArgs) boo::ObjToken<IGraphicsBufferD> newPoolBuffer(BufferUse use, size_t stride, size_t count __BooTraceArgs)
{ {
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue()); D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue());
@ -1607,13 +1376,6 @@ public:
trans(ctx); trans(ctx);
} }
void _unregisterShareableShader(uint64_t srcKey, uint64_t binKey)
{
if (srcKey)
m_sourceToBinary.erase(srcKey);
m_sharedShaders.erase(binKey);
}
void setDisplayGamma(float gamma) void setDisplayGamma(float gamma)
{ {
if (m_ctx->m_fbFormat == DXGI_FORMAT_R16G16B16A16_FLOAT) if (m_ctx->m_fbFormat == DXGI_FORMAT_R16G16B16A16_FLOAT)
@ -1631,13 +1393,101 @@ public:
} }
}; };
D3D11DataFactory::Context::Context(D3D11DataFactory& parent __BooTraceArgs)
: m_parent(parent), m_data(new BaseGraphicsData(static_cast<D3D11DataFactoryImpl&>(parent) __BooTraceArgsUse)) {}
D3D11DataFactory::Context::~Context() {}
boo::ObjToken<IGraphicsBufferS> D3D11DataFactory::Context::newStaticBuffer(
BufferUse use, const void* data, size_t stride, size_t count)
{
D3D11DataFactoryImpl& factory = static_cast<D3D11DataFactoryImpl&>(m_parent);
return {new D3D11GraphicsBufferS(m_data, use, factory.m_ctx, data, stride, count)};
}
boo::ObjToken<IGraphicsBufferD> D3D11DataFactory::Context::newDynamicBuffer(
BufferUse use, size_t stride, size_t count)
{
D3D11DataFactoryImpl& factory = static_cast<D3D11DataFactoryImpl&>(m_parent);
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(factory.m_parent->getCommandQueue());
return {new D3D11GraphicsBufferD<BaseGraphicsData>(m_data, q, use, factory.m_ctx, stride, count)};
}
boo::ObjToken<ITextureS> D3D11DataFactory::Context::newStaticTexture(
size_t width, size_t height, size_t mips, TextureFormat fmt,
TextureClampMode clampMode, const void* data, size_t sz)
{
D3D11DataFactoryImpl& factory = static_cast<D3D11DataFactoryImpl&>(m_parent);
return {new D3D11TextureS(m_data, factory.m_ctx, width, height, mips, fmt, data, sz)};
}
boo::ObjToken<ITextureSA> D3D11DataFactory::Context::newStaticArrayTexture(
size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, TextureClampMode clampMode, const void* data, size_t sz)
{
D3D11DataFactoryImpl& factory = static_cast<D3D11DataFactoryImpl&>(m_parent);
return {new D3D11TextureSA(m_data, factory.m_ctx, width, height, layers, mips, fmt, data, sz)};
}
boo::ObjToken<ITextureD> D3D11DataFactory::Context::newDynamicTexture(
size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode)
{
D3D11DataFactoryImpl& factory = static_cast<D3D11DataFactoryImpl&>(m_parent);
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(factory.m_parent->getCommandQueue());
return {new D3D11TextureD(m_data, q, factory.m_ctx, width, height, fmt)};
}
boo::ObjToken<ITextureR> D3D11DataFactory::Context::newRenderTexture(
size_t width, size_t height, TextureClampMode clampMode,
size_t colorBindCount, size_t depthBindCount)
{
D3D11DataFactoryImpl& factory = static_cast<D3D11DataFactoryImpl&>(m_parent);
return {new D3D11TextureR(m_data, factory.m_ctx, width, height, factory.m_ctx->m_sampleCount,
colorBindCount, depthBindCount)};
}
boo::ObjToken<IShaderStage> D3D11DataFactory::Context::newShaderStage(
const uint8_t* data, size_t size, PipelineStage stage)
{
D3D11DataFactoryImpl& factory = static_cast<D3D11DataFactoryImpl&>(m_parent);
return {new D3D11ShaderStage(m_data, factory.m_ctx, data, size, stage)};
}
boo::ObjToken<IShaderPipeline> D3D11DataFactory::Context::newShaderPipeline
(ObjToken<IShaderStage> vertex, ObjToken<IShaderStage> fragment,
ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control,
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
const AdditionalPipelineInfo& additionalInfo)
{
D3D11DataFactoryImpl& factory = static_cast<D3D11DataFactoryImpl&>(m_parent);
struct D3D11Context* ctx = factory.m_ctx;
return {new D3D11ShaderPipeline(m_data, ctx, vertex, fragment, geometry, control, evaluation, vtxFmt, additionalInfo)};
}
boo::ObjToken<IShaderDataBinding> D3D11DataFactory::Context::newShaderDataBinding(
const boo::ObjToken<IShaderPipeline>& pipeline,
const boo::ObjToken<IGraphicsBuffer>& vbuf,
const boo::ObjToken<IGraphicsBuffer>& instVbo,
const boo::ObjToken<IGraphicsBuffer>& ibuf,
size_t ubufCount, const boo::ObjToken<IGraphicsBuffer>* ubufs, const PipelineStage* ubufStages,
const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, const boo::ObjToken<ITexture>* texs,
const int* texBindIdx, const bool* depthBind,
size_t baseVert, size_t baseInst)
{
D3D11DataFactoryImpl& factory = static_cast<D3D11DataFactoryImpl&>(m_parent);
return {new D3D11ShaderDataBinding(m_data, factory.m_ctx, pipeline, vbuf, instVbo, ibuf,
ubufCount, ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs,
texBindIdx, depthBind, baseVert, baseInst)};
}
void D3D11CommandQueue::RenderingWorker(D3D11CommandQueue* self) void D3D11CommandQueue::RenderingWorker(D3D11CommandQueue* self)
{ {
{ {
std::unique_lock<std::mutex> lk(self->m_initmt); std::unique_lock<std::mutex> lk(self->m_initmt);
} }
self->m_initcv.notify_one(); self->m_initcv.notify_one();
D3D11DataFactory* dataFactory = static_cast<D3D11DataFactory*>(self->m_parent->getDataFactory()); D3D11DataFactoryImpl* dataFactory = static_cast<D3D11DataFactoryImpl*>(self->m_parent->getDataFactory());
while (self->m_running) while (self->m_running)
{ {
{ {
@ -1743,7 +1593,7 @@ void D3D11CommandQueue::RenderingWorker(D3D11CommandQueue* self)
void D3D11CommandQueue::startRenderer() void D3D11CommandQueue::startRenderer()
{ {
static_cast<D3D11DataFactory*>(m_parent->getDataFactory())->SetupGammaResources(); static_cast<D3D11DataFactoryImpl*>(m_parent->getDataFactory())->SetupGammaResources();
} }
void D3D11CommandQueue::execute() void D3D11CommandQueue::execute()
@ -1774,7 +1624,7 @@ void D3D11CommandQueue::execute()
void D3D11CommandQueue::ProcessDynamicLoads(ID3D11DeviceContext* ctx) void D3D11CommandQueue::ProcessDynamicLoads(ID3D11DeviceContext* ctx)
{ {
D3D11DataFactory* gfxF = static_cast<D3D11DataFactory*>(m_parent->getDataFactory()); D3D11DataFactoryImpl* gfxF = static_cast<D3D11DataFactoryImpl*>(m_parent->getDataFactory());
std::unique_lock<std::recursive_mutex> lk(m_dynamicLock); std::unique_lock<std::recursive_mutex> lk(m_dynamicLock);
std::unique_lock<std::recursive_mutex> datalk(gfxF->m_dataMutex); std::unique_lock<std::recursive_mutex> datalk(gfxF->m_dataMutex);
@ -1810,7 +1660,39 @@ _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraph
std::unique_ptr<IGraphicsDataFactory> std::unique_ptr<IGraphicsDataFactory>
_NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent) _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent)
{ {
return std::make_unique<D3D11DataFactory>(parent, ctx); return std::make_unique<D3D11DataFactoryImpl>(parent, ctx);
}
static const char* D3DShaderTypes[] =
{
nullptr,
"vs_5_0",
"ps_5_0",
"gs_5_0",
"hs_5_0",
"ds_5_0"
};
#if _DEBUG && 0
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0
#else
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
std::vector<uint8_t> D3D11DataFactory::CompileHLSL(const char* source, PipelineStage stage)
{
ComPtr<ID3DBlob> errBlob;
ComPtr<ID3DBlob> blobOut;
if (FAILED(D3DCompilePROC(source, strlen(source), "Boo HLSL Source", nullptr, nullptr, "main",
D3DShaderTypes[int(stage)], BOO_D3DCOMPILE_FLAG, 0, &blobOut, &errBlob)))
{
printf("%s\n", source);
Log.report(logvisor::Fatal, "error compiling shader: %s", errBlob->GetBufferPointer());
return {};
}
std::vector<uint8_t> ret(blobOut->GetBufferSize());
memcpy(ret.data(), blobOut->GetBufferPointer(), ret.size());
return ret;
} }
} }

View File

@ -413,7 +413,7 @@ bool VulkanContext::initVulkan(std::string_view appName, PFN_vkGetInstanceProcAd
#ifndef NDEBUG #ifndef NDEBUG
m_layerNames.push_back("VK_LAYER_LUNARG_standard_validation"); m_layerNames.push_back("VK_LAYER_LUNARG_standard_validation");
m_layerNames.push_back("VK_LAYER_RENDERDOC_Capture"); //m_layerNames.push_back("VK_LAYER_RENDERDOC_Capture");
//m_layerNames.push_back("VK_LAYER_LUNARG_api_dump"); //m_layerNames.push_back("VK_LAYER_LUNARG_api_dump");
//m_layerNames.push_back("VK_LAYER_LUNARG_core_validation"); //m_layerNames.push_back("VK_LAYER_LUNARG_core_validation");
//m_layerNames.push_back("VK_LAYER_LUNARG_object_tracker"); //m_layerNames.push_back("VK_LAYER_LUNARG_object_tracker");

View File

@ -23,7 +23,7 @@ static const int ContextAttribs[] =
{ {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
//WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, //WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
//WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, //WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
0, 0 0, 0

View File

@ -417,8 +417,6 @@ struct TestApplicationCallback : IApplicationCallback
#if _WIN32 #if _WIN32
if (plat == IGraphicsDataFactory::Platform::D3D11) if (plat == IGraphicsDataFactory::Platform::D3D11)
{ {
D3DDataFactory::Context& d3dF = dynamic_cast<D3DDataFactory::Context&>(ctx);
static const char* VS = static const char* VS =
"struct VertData {float3 in_pos : POSITION; float2 in_uv : UV;};\n" "struct VertData {float3 in_pos : POSITION; float2 in_uv : UV;};\n"
"struct VertToFrag {float4 out_pos : SV_Position; float2 out_uv : UV;};\n" "struct VertToFrag {float4 out_pos : SV_Position; float2 out_uv : UV;};\n"
@ -440,10 +438,11 @@ struct TestApplicationCallback : IApplicationCallback
" return float4(d.out_uv.xy, 0.0, 1.0);\n" " return float4(d.out_uv.xy, 0.0, 1.0);\n"
"}\n"; "}\n";
pipeline = d3dF.newShaderPipeline(VS, PS, nullptr, nullptr, nullptr, vfmt, auto vertexSiprv = D3D11DataFactory::CompileHLSL(VS, PipelineStage::Vertex);
BlendFactor::One, BlendFactor::Zero, auto vertexShader = ctx.newShaderStage(vertexSiprv, PipelineStage::Vertex);
Primitive::TriStrips, boo::ZTest::LEqual, auto fragmentSiprv = D3D11DataFactory::CompileHLSL(PS, PipelineStage::Fragment);
true, true, false, CullMode::None); auto fragmentShader = ctx.newShaderStage(fragmentSiprv, PipelineStage::Fragment);
pipeline = ctx.newShaderPipeline(vertexShader, fragmentShader, descs, info);
} else } else
#elif BOO_HAS_METAL #elif BOO_HAS_METAL
if (plat == IGraphicsDataFactory::Platform::Metal) if (plat == IGraphicsDataFactory::Platform::Metal)
@ -609,7 +608,7 @@ int WINAPIV main(Platform::Array<Platform::String^>^ params)
logvisor::RegisterConsoleLogger(); logvisor::RegisterConsoleLogger();
boo::TestApplicationCallback appCb; boo::TestApplicationCallback appCb;
boo::ViewProvider^ viewProvider = boo::ViewProvider^ viewProvider =
ref new boo::ViewProvider(appCb, _S("boo"), _S("boo"), _S("boo"), params, false); ref new boo::ViewProvider(appCb, _SYS_STR("boo"), _SYS_STR("boo"), _SYS_STR("boo"), params, false);
CoreApplication::Run(viewProvider); CoreApplication::Run(viewProvider);
return 0; return 0;
} }