D3D sync of new lambda API

This commit is contained in:
Jack Andersen 2016-03-30 10:42:36 -10:00
parent bf6b4e37e8
commit ecc65a9fd5
7 changed files with 376 additions and 348 deletions

View File

@ -23,12 +23,17 @@ class ID3DDataFactory : public IGraphicsDataFactory
{ {
public: public:
virtual ~ID3DDataFactory() {} virtual ~ID3DDataFactory() {}
bool bindingNeedsVertexFormat() const {return false;}
virtual IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, class Context : public IGraphicsDataFactory::Context
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut, {
ComPtr<ID3DBlob>& pipelineBlob, IVertexFormat* vtxFmt, public:
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, bool bindingNeedsVertexFormat() const {return false;}
bool depthTest, bool depthWrite, bool backfaceCulling)=0; virtual IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource,
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut,
ComPtr<ID3DBlob>& pipelineBlob, IVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
bool depthTest, bool depthWrite, bool backfaceCulling)=0;
};
}; };
} }

View File

@ -2,6 +2,7 @@
#define IGFXDATAFACTORY_HPP #define IGFXDATAFACTORY_HPP
#include <memory> #include <memory>
#include <functional>
#include <stdint.h> #include <stdint.h>
#include "boo/System.hpp" #include "boo/System.hpp"

View File

@ -544,18 +544,16 @@ struct D3D11ShaderDataBinding : IShaderDataBinding
IGraphicsBuffer* m_ibuf; IGraphicsBuffer* m_ibuf;
size_t m_ubufCount; size_t m_ubufCount;
std::unique_ptr<IGraphicsBuffer*[]> m_ubufs; std::unique_ptr<IGraphicsBuffer*[]> m_ubufs;
std::vector<UINT> m_ubufFirstConsts;
std::vector<UINT> m_ubufNumConsts;
size_t m_texCount; size_t m_texCount;
std::unique_ptr<ITexture*[]> m_texs; std::unique_ptr<ITexture*[]> m_texs;
#ifndef NDEBUG
/* Debugging aids */
bool m_committed = false;
#endif
D3D11ShaderDataBinding(D3D11Context* ctx, D3D11ShaderDataBinding(D3D11Context* ctx,
IShaderPipeline* pipeline, IShaderPipeline* pipeline,
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbuf, IGraphicsBuffer* ibuf, IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbuf, IGraphicsBuffer* ibuf,
size_t ubufCount, IGraphicsBuffer** ubufs, size_t ubufCount, IGraphicsBuffer** ubufs,
const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, ITexture** texs) size_t texCount, ITexture** texs)
: m_pipeline(static_cast<D3D11ShaderPipeline*>(pipeline)), : m_pipeline(static_cast<D3D11ShaderPipeline*>(pipeline)),
m_vbuf(vbuf), m_vbuf(vbuf),
@ -566,20 +564,40 @@ struct D3D11ShaderDataBinding : IShaderDataBinding
m_texCount(texCount), m_texCount(texCount),
m_texs(new ITexture*[texCount]) m_texs(new ITexture*[texCount])
{ {
if (ubufOffs && ubufSizes)
{
m_ubufFirstConsts.reserve(ubufCount);
m_ubufNumConsts.reserve(ubufCount);
for (size_t i=0 ; i<ubufCount ; ++i)
{
#ifndef NDEBUG
if (ubufOffs[i] % 256)
Log.report(logvisor::Fatal, "non-256-byte-aligned uniform-offset %d provided to newShaderDataBinding", int(i));
#endif
m_ubufFirstConsts.push_back(ubufOffs[i] / 16);
m_ubufNumConsts.push_back(((ubufSizes[i] + 255) & ~255) / 16);
}
}
for (size_t i=0 ; i<ubufCount ; ++i) for (size_t i=0 ; i<ubufCount ; ++i)
{
#ifndef NDEBUG
if (!ubufs[i])
Log.report(logvisor::Fatal, "null uniform-buffer %d provided to newShaderDataBinding", int(i));
#endif
m_ubufs[i] = ubufs[i]; m_ubufs[i] = ubufs[i];
}
for (size_t i=0 ; i<texCount ; ++i) for (size_t i=0 ; i<texCount ; ++i)
{
#ifndef NDEBUG
if (!texs[i])
Log.report(logvisor::Fatal, "null texture %d provided to newShaderDataBinding", int(i));
#endif
m_texs[i] = texs[i]; m_texs[i] = texs[i];
}
} }
void bind(ID3D11DeviceContext* ctx, int b) void bind(ID3D11DeviceContext1* ctx, int b)
{ {
#ifndef NDEBUG
if (!m_committed)
Log.report(logvisor::Fatal,
"attempted to use uncommitted D3D11ShaderDataBinding");
#endif
m_pipeline->bind(ctx); m_pipeline->bind(ctx);
ID3D11Buffer* bufs[2] = {}; ID3D11Buffer* bufs[2] = {};
@ -636,21 +654,42 @@ struct D3D11ShaderDataBinding : IShaderDataBinding
if (m_ubufCount) if (m_ubufCount)
{ {
ID3D11Buffer* constBufs[8]; if (m_ubufFirstConsts.size())
for (int i=0 ; i<8 && i<m_ubufCount ; ++i)
{ {
if (m_ubufs[i]->dynamic()) ID3D11Buffer* constBufs[8];
for (int i=0 ; i<8 && i<m_ubufCount ; ++i)
{ {
D3D11GraphicsBufferD* cbuf = static_cast<D3D11GraphicsBufferD*>(m_ubufs[i]); if (m_ubufs[i]->dynamic())
constBufs[i] = cbuf->m_bufs[b].Get(); {
} D3D11GraphicsBufferD* cbuf = static_cast<D3D11GraphicsBufferD*>(m_ubufs[i]);
else constBufs[i] = cbuf->m_bufs[b].Get();
{ }
D3D11GraphicsBufferS* cbuf = static_cast<D3D11GraphicsBufferS*>(m_ubufs[i]); else
constBufs[i] = cbuf->m_buf.Get(); {
D3D11GraphicsBufferS* cbuf = static_cast<D3D11GraphicsBufferS*>(m_ubufs[i]);
constBufs[i] = cbuf->m_buf.Get();
}
} }
ctx->VSSetConstantBuffers1(0, m_ubufCount, constBufs, m_ubufFirstConsts.data(), m_ubufNumConsts.data());
}
else
{
ID3D11Buffer* constBufs[8];
for (int i=0 ; i<8 && i<m_ubufCount ; ++i)
{
if (m_ubufs[i]->dynamic())
{
D3D11GraphicsBufferD* cbuf = static_cast<D3D11GraphicsBufferD*>(m_ubufs[i]);
constBufs[i] = cbuf->m_bufs[b].Get();
}
else
{
D3D11GraphicsBufferS* cbuf = static_cast<D3D11GraphicsBufferS*>(m_ubufs[i]);
constBufs[i] = cbuf->m_buf.Get();
}
}
ctx->VSSetConstantBuffers(0, m_ubufCount, constBufs);
} }
ctx->VSSetConstantBuffers(0, m_ubufCount, constBufs);
} }
if (m_texCount) if (m_texCount)
@ -1055,90 +1094,71 @@ public:
Platform platform() const {return Platform::D3D11;} Platform platform() const {return Platform::D3D11;}
const SystemChar* platformName() const {return _S("D3D11");} const SystemChar* platformName() const {return _S("D3D11");}
IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) class Context : public ID3DDataFactory::Context
{ {
D3D11GraphicsBufferS* retval = new D3D11GraphicsBufferS(use, m_ctx, data, stride, count); friend class D3D11DataFactory;
if (!m_deferredData) D3D11DataFactory& m_parent;
m_deferredData = new struct D3D11Data(); Context(D3D11DataFactory& parent) : m_parent(parent) {}
static_cast<D3D11Data*>(m_deferredData)->m_SBufs.emplace_back(retval); public:
return retval; Platform platform() const {return Platform::D3D11;}
} const SystemChar* platformName() const {return _S("D3D11");}
IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count) IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
{ {
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue()); D3D11GraphicsBufferS* retval = new D3D11GraphicsBufferS(use, m_parent.m_ctx, data, stride, count);
D3D11GraphicsBufferD* retval = new D3D11GraphicsBufferD(q, use, m_ctx, stride, count); static_cast<D3D11Data*>(m_deferredData)->m_SBufs.emplace_back(retval);
if (!m_deferredData) return retval;
m_deferredData = new struct D3D11Data(); }
static_cast<D3D11Data*>(m_deferredData)->m_DBufs.emplace_back(retval);
return retval;
}
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count)
const void* data, size_t sz) {
{ D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent.m_parent->getCommandQueue());
D3D11TextureS* retval = new D3D11TextureS(m_ctx, width, height, mips, fmt, data, sz); D3D11GraphicsBufferD* retval = new D3D11GraphicsBufferD(q, use, m_parent.m_ctx, stride, count);
if (!m_deferredData) static_cast<D3D11Data*>(m_deferredData)->m_DBufs.emplace_back(retval);
m_deferredData = new struct D3D11Data(); return retval;
static_cast<D3D11Data*>(m_deferredData)->m_STexs.emplace_back(retval); }
return retval;
}
GraphicsDataToken ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
newStaticTextureNoContext(size_t width, size_t height, size_t mips, TextureFormat fmt, const void* data, size_t sz)
const void* data, size_t sz, ITextureS*& texOut) {
{ D3D11TextureS* retval = new D3D11TextureS(m_parent.m_ctx, width, height, mips, fmt, data, sz);
D3D11TextureS* retval = new D3D11TextureS(m_ctx, width, height, mips, fmt, data, sz); static_cast<D3D11Data*>(m_deferredData)->m_STexs.emplace_back(retval);
D3D11Data* tokData = new struct D3D11Data(); return retval;
tokData->m_STexs.emplace_back(retval); }
texOut = retval;
std::unique_lock<std::mutex> lk(m_committedMutex); ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt,
m_committedData.insert(tokData); const void* data, size_t sz)
return GraphicsDataToken(this, tokData); {
} D3D11TextureSA* retval = new D3D11TextureSA(m_parent.m_ctx, width, height, layers, fmt, data, sz);
static_cast<D3D11Data*>(m_deferredData)->m_SATexs.emplace_back(retval);
return retval;
}
ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt, ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
const void* data, size_t sz) {
{ D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent.m_parent->getCommandQueue());
D3D11TextureSA* retval = new D3D11TextureSA(m_ctx, width, height, layers, fmt, data, sz); D3D11TextureD* retval = new D3D11TextureD(q, m_parent.m_ctx, width, height, fmt);
if (!m_deferredData) static_cast<D3D11Data*>(m_deferredData)->m_DTexs.emplace_back(retval);
m_deferredData = new struct D3D11Data(); return retval;
static_cast<D3D11Data*>(m_deferredData)->m_SATexs.emplace_back(retval); }
return retval;
}
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt) ITextureR* newRenderTexture(size_t width, size_t height,
{ bool enableShaderColorBind, bool enableShaderDepthBind)
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue()); {
D3D11TextureD* retval = new D3D11TextureD(q, m_ctx, width, height, fmt); D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent.m_parent->getCommandQueue());
if (!m_deferredData) D3D11TextureR* retval = new D3D11TextureR(m_parent.m_ctx, width, height, m_parent.m_sampleCount,
m_deferredData = new struct D3D11Data(); enableShaderColorBind, enableShaderDepthBind);
static_cast<D3D11Data*>(m_deferredData)->m_DTexs.emplace_back(retval); static_cast<D3D11Data*>(m_deferredData)->m_RTexs.emplace_back(retval);
return retval; return retval;
} }
ITextureR* newRenderTexture(size_t width, size_t height, IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)
bool enableShaderColorBind, bool enableShaderDepthBind) {
{ D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent.m_parent->getCommandQueue());
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue()); D3D11VertexFormat* retval = new struct D3D11VertexFormat(elementCount, elements);
D3D11TextureR* retval = new D3D11TextureR(m_ctx, width, height, m_sampleCount, static_cast<D3D11Data*>(m_deferredData)->m_VFmts.emplace_back(retval);
enableShaderColorBind, enableShaderDepthBind); return retval;
if (!m_deferredData) }
m_deferredData = new struct D3D11Data();
static_cast<D3D11Data*>(m_deferredData)->m_RTexs.emplace_back(retval);
return retval;
}
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)
{
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue());
D3D11VertexFormat* retval = new struct D3D11VertexFormat(elementCount, elements);
if (!m_deferredData)
m_deferredData = new struct D3D11Data();
static_cast<D3D11Data*>(m_deferredData)->m_VFmts.emplace_back(retval);
return retval;
}
#if _DEBUG #if _DEBUG
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0 #define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0
@ -1146,75 +1166,76 @@ public:
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3 #define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif #endif
IShaderPipeline* newShaderPipeline IShaderPipeline* newShaderPipeline
(const char* vertSource, const char* fragSource, (const char* vertSource, const char* fragSource,
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut, ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut,
ComPtr<ID3DBlob>& pipelineBlob, IVertexFormat* vtxFmt, ComPtr<ID3DBlob>& pipelineBlob, IVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
bool depthTest, bool depthWrite, bool backfaceCulling) bool depthTest, bool depthWrite, bool backfaceCulling)
{
ComPtr<ID3DBlob> errBlob;
if (!vertBlobOut)
{ {
if (FAILED(D3DCompilePROC(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main", ComPtr<ID3DBlob> errBlob;
"vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob)))
if (!vertBlobOut)
{ {
Log.report(logvisor::Fatal, "error compiling vert shader: %s", errBlob->GetBufferPointer()); if (FAILED(D3DCompilePROC(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main",
return nullptr; "vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob)))
{
Log.report(logvisor::Fatal, "error compiling vert shader: %s", errBlob->GetBufferPointer());
return nullptr;
}
} }
if (!fragBlobOut)
{
if (FAILED(D3DCompilePROC(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main",
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob)))
{
Log.report(logvisor::Fatal, "error compiling pixel shader: %s", errBlob->GetBufferPointer());
return nullptr;
}
}
D3D11ShaderPipeline* retval = new D3D11ShaderPipeline(m_parent.m_ctx, vertBlobOut.Get(), fragBlobOut.Get(),
static_cast<const D3D11VertexFormat*>(vtxFmt),
srcFac, dstFac, prim, depthTest, depthWrite, backfaceCulling);
static_cast<D3D11Data*>(m_deferredData)->m_SPs.emplace_back(retval);
return retval;
} }
if (!fragBlobOut) IShaderDataBinding* newShaderDataBinding(IShaderPipeline* pipeline,
IVertexFormat* vtxFormat,
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibuf,
size_t ubufCount, IGraphicsBuffer** ubufs,
const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, ITexture** texs)
{ {
if (FAILED(D3DCompilePROC(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main", D3D11ShaderDataBinding* retval =
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob))) new D3D11ShaderDataBinding(m_parent.m_ctx, pipeline, vbuf, instVbo, ibuf,
{ ubufCount, ubufs, ubufOffs, ubufSizes, texCount, texs);
Log.report(logvisor::Fatal, "error compiling pixel shader: %s", errBlob->GetBufferPointer()); static_cast<D3D11Data*>(m_deferredData)->m_SBinds.emplace_back(retval);
return nullptr; return retval;
}
} }
};
D3D11ShaderPipeline* retval = new D3D11ShaderPipeline(m_ctx, vertBlobOut.Get(), fragBlobOut.Get(), GraphicsDataToken commitTransaction(const FactoryCommitFunc& trans)
static_cast<const D3D11VertexFormat*>(vtxFmt),
srcFac, dstFac, prim, depthTest, depthWrite, backfaceCulling);
if (!m_deferredData)
m_deferredData = new struct D3D11Data();
static_cast<D3D11Data*>(m_deferredData)->m_SPs.emplace_back(retval);
return retval;
}
IShaderDataBinding* newShaderDataBinding(IShaderPipeline* pipeline,
IVertexFormat* vtxFormat,
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibuf,
size_t ubufCount, IGraphicsBuffer** ubufs,
size_t texCount, ITexture** texs)
{ {
D3D11ShaderDataBinding* retval = if (m_deferredData)
new D3D11ShaderDataBinding(m_ctx, pipeline, vbuf, instVbo, ibuf, ubufCount, ubufs, texCount, texs); Log.report(logvisor::Fatal, "nested commitTransaction usage detected");
if (!m_deferredData) m_deferredData = new D3D11Data();
m_deferredData = new struct D3D11Data();
static_cast<D3D11Data*>(m_deferredData)->m_SBinds.emplace_back(retval);
return retval;
}
void reset() D3D11DataFactory::Context ctx(*this);
{ if (!trans(ctx))
delete static_cast<D3D11Data*>(m_deferredData); {
m_deferredData = nullptr; delete m_deferredData;
} m_deferredData = nullptr;
GraphicsDataToken commit()
{
if (!m_deferredData)
return GraphicsDataToken(this, nullptr); return GraphicsDataToken(this, nullptr);
}
std::unique_lock<std::mutex> lk(m_committedMutex);
D3D11Data* retval = m_deferredData; D3D11Data* retval = m_deferredData;
#ifndef NDEBUG
for (std::unique_ptr<D3D11ShaderDataBinding>& b : retval->m_SBinds)
b->m_committed = true;
#endif
m_deferredData = nullptr; m_deferredData = nullptr;
m_committedData.insert(retval); m_committedData.insert(retval);
lk.unlock();
return GraphicsDataToken(this, retval); return GraphicsDataToken(this, retval);
} }
}; };

View File

@ -891,20 +891,17 @@ struct D3D12ShaderDataBinding : IShaderDataBinding
IGraphicsBuffer* m_ibuf; IGraphicsBuffer* m_ibuf;
size_t m_ubufCount; size_t m_ubufCount;
std::unique_ptr<IGraphicsBuffer*[]> m_ubufs; std::unique_ptr<IGraphicsBuffer*[]> m_ubufs;
std::vector<std::pair<size_t,size_t>> m_ubufOffs;
size_t m_texCount; size_t m_texCount;
std::unique_ptr<ITexture*[]> m_texs; std::unique_ptr<ITexture*[]> m_texs;
D3D12_VERTEX_BUFFER_VIEW m_vboView[2][2] = {{},{}}; D3D12_VERTEX_BUFFER_VIEW m_vboView[2][2] = {{},{}};
D3D12_INDEX_BUFFER_VIEW m_iboView[2]; D3D12_INDEX_BUFFER_VIEW m_iboView[2];
#ifndef NDEBUG
/* Debugging aids */
bool m_committed = false;
#endif
D3D12ShaderDataBinding(D3D12Context* ctx, D3D12ShaderDataBinding(D3D12Context* ctx,
IShaderPipeline* pipeline, IShaderPipeline* pipeline,
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbuf, IGraphicsBuffer* ibuf, IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbuf, IGraphicsBuffer* ibuf,
size_t ubufCount, IGraphicsBuffer** ubufs, size_t ubufCount, IGraphicsBuffer** ubufs,
const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, ITexture** texs) size_t texCount, ITexture** texs)
: m_pipeline(static_cast<D3D12ShaderPipeline*>(pipeline)), : m_pipeline(static_cast<D3D12ShaderPipeline*>(pipeline)),
m_vbuf(vbuf), m_vbuf(vbuf),
@ -915,10 +912,34 @@ struct D3D12ShaderDataBinding : IShaderDataBinding
m_texCount(texCount), m_texCount(texCount),
m_texs(new ITexture*[texCount]) m_texs(new ITexture*[texCount])
{ {
if (ubufOffs && ubufSizes)
{
m_ubufOffs.reserve(ubufCount);
for (size_t i=0 ; i<ubufCount ; ++i)
{
#ifndef NDEBUG
if (ubufOffs[i] % 256)
Log.report(logvisor::Fatal, "non-256-byte-aligned uniform-offset %d provided to newShaderDataBinding", int(i));
#endif
m_ubufOffs.emplace_back(ubufOffs[i], (ubufSizes[i] + 255) & ~255);
}
}
for (size_t i=0 ; i<ubufCount ; ++i) for (size_t i=0 ; i<ubufCount ; ++i)
{
#ifndef NDEBUG
if (!ubufs[i])
Log.report(logvisor::Fatal, "null uniform-buffer %d provided to newShaderDataBinding", int(i));
#endif
m_ubufs[i] = ubufs[i]; m_ubufs[i] = ubufs[i];
}
for (size_t i=0 ; i<texCount ; ++i) for (size_t i=0 ; i<texCount ; ++i)
{
#ifndef NDEBUG
if (!texs[i])
Log.report(logvisor::Fatal, "null texture %d provided to newShaderDataBinding", int(i));
#endif
m_texs[i] = texs[i]; m_texs[i] = texs[i];
}
} }
void commit(D3D12Context* ctx) void commit(D3D12Context* ctx)
@ -942,16 +963,35 @@ struct D3D12ShaderDataBinding : IShaderDataBinding
GetBufferGPUResource(m_instVbuf, b, m_vboView[b][1]); GetBufferGPUResource(m_instVbuf, b, m_vboView[b][1]);
if (m_ibuf) if (m_ibuf)
GetBufferGPUResource(m_ibuf, b, m_iboView[b]); GetBufferGPUResource(m_ibuf, b, m_iboView[b]);
for (size_t i=0 ; i<MAX_UNIFORM_COUNT ; ++i) if (m_ubufOffs.size())
{ {
if (i<m_ubufCount) for (size_t i=0 ; i<MAX_UNIFORM_COUNT ; ++i)
{ {
D3D12_CONSTANT_BUFFER_VIEW_DESC viewDesc; if (i<m_ubufCount)
GetBufferGPUResource(m_ubufs[i], b, viewDesc); {
viewDesc.SizeInBytes = (viewDesc.SizeInBytes + 255) & ~255; const std::pair<size_t,size_t>& offPair = m_ubufOffs[i];
ctx->m_dev->CreateConstantBufferView(&viewDesc, handle); D3D12_CONSTANT_BUFFER_VIEW_DESC viewDesc;
GetBufferGPUResource(m_ubufs[i], b, viewDesc);
viewDesc.BufferLocation += offPair.first;
viewDesc.SizeInBytes = (offPair.second + 255) & ~255;
ctx->m_dev->CreateConstantBufferView(&viewDesc, handle);
}
handle.Offset(1, incSz);
}
}
else
{
for (size_t i=0 ; i<MAX_UNIFORM_COUNT ; ++i)
{
if (i<m_ubufCount)
{
D3D12_CONSTANT_BUFFER_VIEW_DESC viewDesc;
GetBufferGPUResource(m_ubufs[i], b, viewDesc);
viewDesc.SizeInBytes = (viewDesc.SizeInBytes + 255) & ~255;
ctx->m_dev->CreateConstantBufferView(&viewDesc, handle);
}
handle.Offset(1, incSz);
} }
handle.Offset(1, incSz);
} }
for (size_t i=0 ; i<MAX_TEXTURE_COUNT ; ++i) for (size_t i=0 ; i<MAX_TEXTURE_COUNT ; ++i)
{ {
@ -964,20 +1004,10 @@ struct D3D12ShaderDataBinding : IShaderDataBinding
handle.Offset(1, incSz); handle.Offset(1, incSz);
} }
} }
#ifndef NDEBUG
m_committed = true;
#endif
} }
void bind(ID3D12GraphicsCommandList* list, int b) void bind(ID3D12GraphicsCommandList* list, int b)
{ {
#ifndef NDEBUG
if (!m_committed)
Log.report(logvisor::Fatal,
"attempted to use uncommitted D3D12ShaderDataBinding");
#endif
ID3D12DescriptorHeap* heap[] = {m_descHeap[b].Get()}; ID3D12DescriptorHeap* heap[] = {m_descHeap[b].Get()};
list->SetDescriptorHeaps(1, heap); list->SetDescriptorHeaps(1, heap);
list->SetGraphicsRootDescriptorTable(0, m_descHeap[b]->GetGPUDescriptorHandleForHeapStart()); list->SetGraphicsRootDescriptorTable(0, m_descHeap[b]->GetGPUDescriptorHandleForHeapStart());
@ -1491,117 +1521,70 @@ public:
Platform platform() const {return Platform::D3D12;} Platform platform() const {return Platform::D3D12;}
const SystemChar* platformName() const {return _S("D3D12");} const SystemChar* platformName() const {return _S("D3D12");}
IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) class Context : public ID3DDataFactory::Context
{ {
D3D12GraphicsBufferS* retval = new D3D12GraphicsBufferS(use, m_ctx, data, stride, count); friend class D3D12DataFactory;
if (!m_deferredData) D3D12DataFactory& m_parent;
m_deferredData = new struct D3D12Data(); Context(D3D12DataFactory& parent) : m_parent(parent) {}
static_cast<D3D12Data*>(m_deferredData)->m_SBufs.emplace_back(retval); public:
return retval; Platform platform() const {return Platform::D3D12;}
} const SystemChar* platformName() const {return _S("D3D12");}
IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count) IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
{ {
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue()); D3D12GraphicsBufferS* retval = new D3D12GraphicsBufferS(use, m_parent.m_ctx, data, stride, count);
D3D12GraphicsBufferD* retval = new D3D12GraphicsBufferD(q, use, m_ctx, stride, count); static_cast<D3D12Data*>(m_deferredData)->m_SBufs.emplace_back(retval);
if (!m_deferredData) return retval;
m_deferredData = new struct D3D12Data(); }
static_cast<D3D12Data*>(m_deferredData)->m_DBufs.emplace_back(retval);
return retval;
}
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count)
const void* data, size_t sz) {
{ D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent.m_parent->getCommandQueue());
D3D12TextureS* retval = new D3D12TextureS(m_ctx, width, height, mips, fmt, data, sz); D3D12GraphicsBufferD* retval = new D3D12GraphicsBufferD(q, use, m_parent.m_ctx, stride, count);
if (!m_deferredData) static_cast<D3D12Data*>(m_deferredData)->m_DBufs.emplace_back(retval);
m_deferredData = new struct D3D12Data(); return retval;
static_cast<D3D12Data*>(m_deferredData)->m_STexs.emplace_back(retval); }
return retval;
}
GraphicsDataToken ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
newStaticTextureNoContext(size_t width, size_t height, size_t mips, TextureFormat fmt, const void* data, size_t sz)
const void* data, size_t sz, ITextureS*& texOut) {
{ D3D12TextureS* retval = new D3D12TextureS(m_parent.m_ctx, width, height, mips, fmt, data, sz);
D3D12TextureS* retval = new D3D12TextureS(m_ctx, width, height, mips, fmt, data, sz); static_cast<D3D12Data*>(m_deferredData)->m_STexs.emplace_back(retval);
D3D12Data* tokData = new struct D3D12Data(); return retval;
tokData->m_STexs.emplace_back(retval); }
texOut = retval;
/* Create heap */ ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt,
D3D12_RESOURCE_ALLOCATION_INFO texAllocInfo = const void* data, size_t sz)
m_ctx->m_dev->GetResourceAllocationInfo(0, 1, &retval->m_gpuDesc); {
ThrowIfFailed(m_ctx->m_dev->CreateHeap(&CD3DX12_HEAP_DESC(texAllocInfo, D3D12TextureSA* retval = new D3D12TextureSA(m_parent.m_ctx, width, height, layers, fmt, data, sz);
D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES), static_cast<D3D12Data*>(m_deferredData)->m_SATexs.emplace_back(retval);
__uuidof(ID3D12Heap), &tokData->m_texHeap)); return retval;
ID3D12Heap* texHeap = tokData->m_texHeap.Get(); }
/* Place resources */ ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
PlaceTextureForGPU(retval, m_ctx, texHeap, 0); {
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent.m_parent->getCommandQueue());
D3D12TextureD* retval = new D3D12TextureD(q, m_parent.m_ctx, width, height, fmt);
static_cast<D3D12Data*>(m_deferredData)->m_DTexs.emplace_back(retval);
return retval;
}
/* Execute static uploads */ ITextureR* newRenderTexture(size_t width, size_t height,
ThrowIfFailed(m_ctx->m_loadlist->Close()); bool enableShaderColorBind, bool enableShaderDepthBind)
ID3D12CommandList* list[] = {m_ctx->m_loadlist.Get()}; {
m_ctx->m_loadq->ExecuteCommandLists(1, list); D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent.m_parent->getCommandQueue());
++m_ctx->m_loadfenceval; D3D12TextureR* retval = new D3D12TextureR(m_parent.m_ctx, q, width, height, m_parent.m_sampleCount,
ThrowIfFailed(m_ctx->m_loadq->Signal(m_ctx->m_loadfence.Get(), m_ctx->m_loadfenceval)); enableShaderColorBind, enableShaderDepthBind);
static_cast<D3D12Data*>(m_deferredData)->m_RTexs.emplace_back(retval);
return retval;
}
/* Block handle return until data is ready on GPU */ IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)
WaitForLoadList(m_ctx); {
D3D12VertexFormat* retval = new struct D3D12VertexFormat(elementCount, elements);
/* Reset allocator and list */ static_cast<D3D12Data*>(m_deferredData)->m_VFmts.emplace_back(retval);
ThrowIfFailed(m_ctx->m_loadqalloc->Reset()); return retval;
ThrowIfFailed(m_ctx->m_loadlist->Reset(m_ctx->m_loadqalloc.Get(), nullptr)); }
/* Delete static upload heap */
retval->m_tex.Reset();
std::unique_lock<std::mutex> lk(m_committedMutex);
m_committedData.insert(tokData);
return GraphicsDataToken(this, tokData);
}
ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt,
const void* data, size_t sz)
{
D3D12TextureSA* retval = new D3D12TextureSA(m_ctx, width, height, layers, fmt, data, sz);
if (!m_deferredData)
m_deferredData = new struct D3D12Data();
static_cast<D3D12Data*>(m_deferredData)->m_SATexs.emplace_back(retval);
return retval;
}
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
{
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
D3D12TextureD* retval = new D3D12TextureD(q, m_ctx, width, height, fmt);
if (!m_deferredData)
m_deferredData = new struct D3D12Data();
static_cast<D3D12Data*>(m_deferredData)->m_DTexs.emplace_back(retval);
return retval;
}
ITextureR* newRenderTexture(size_t width, size_t height,
bool enableShaderColorBind, bool enableShaderDepthBind)
{
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
D3D12TextureR* retval = new D3D12TextureR(m_ctx, q, width, height, m_sampleCount,
enableShaderColorBind, enableShaderDepthBind);
if (!m_deferredData)
m_deferredData = new struct D3D12Data();
static_cast<D3D12Data*>(m_deferredData)->m_RTexs.emplace_back(retval);
return retval;
}
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)
{
D3D12VertexFormat* retval = new struct D3D12VertexFormat(elementCount, elements);
if (!m_deferredData)
m_deferredData = new struct D3D12Data();
static_cast<D3D12Data*>(m_deferredData)->m_VFmts.emplace_back(retval);
return retval;
}
#if _DEBUG #if _DEBUG
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0 #define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0
@ -1609,70 +1592,72 @@ public:
#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3 #define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif #endif
IShaderPipeline* newShaderPipeline IShaderPipeline* newShaderPipeline
(const char* vertSource, const char* fragSource, (const char* vertSource, const char* fragSource,
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut, ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut,
ComPtr<ID3DBlob>& pipelineBlob, IVertexFormat* vtxFmt, ComPtr<ID3DBlob>& pipelineBlob, IVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
bool depthTest, bool depthWrite, bool backfaceCulling) bool depthTest, bool depthWrite, bool backfaceCulling)
{
ComPtr<ID3DBlob> errBlob;
if (!vertBlobOut)
{ {
if (FAILED(D3DCompilePROC(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main", ComPtr<ID3DBlob> errBlob;
"vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob)))
if (!vertBlobOut)
{ {
Log.report(logvisor::Fatal, "error compiling vert shader: %s", errBlob->GetBufferPointer()); if (FAILED(D3DCompilePROC(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main",
return nullptr; "vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob)))
{
Log.report(logvisor::Fatal, "error compiling vert shader: %s", errBlob->GetBufferPointer());
return nullptr;
}
} }
if (!fragBlobOut)
{
if (FAILED(D3DCompilePROC(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main",
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob)))
{
Log.report(logvisor::Fatal, "error compiling pixel shader: %s", errBlob->GetBufferPointer());
return nullptr;
}
}
D3D12ShaderPipeline* retval = new D3D12ShaderPipeline(m_parent.m_ctx, vertBlobOut.Get(), fragBlobOut.Get(), pipelineBlob.Get(),
static_cast<const D3D12VertexFormat*>(vtxFmt),
srcFac, dstFac, prim, depthTest, depthWrite, backfaceCulling);
if (!pipelineBlob)
retval->m_state->GetCachedBlob(&pipelineBlob);
static_cast<D3D12Data*>(m_deferredData)->m_SPs.emplace_back(retval);
return retval;
} }
if (!fragBlobOut) IShaderDataBinding* newShaderDataBinding(IShaderPipeline* pipeline,
IVertexFormat* vtxFormat,
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbuf, IGraphicsBuffer* ibuf,
size_t ubufCount, IGraphicsBuffer** ubufs,
const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, ITexture** texs)
{ {
if (FAILED(D3DCompilePROC(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main", D3D12ShaderDataBinding* retval =
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob))) new D3D12ShaderDataBinding(m_parent.m_ctx, pipeline, vbuf, instVbuf, ibuf,
{ ubufCount, ubufs, ubufOffs, ubufSizes, texCount, texs);
Log.report(logvisor::Fatal, "error compiling pixel shader: %s", errBlob->GetBufferPointer()); static_cast<D3D12Data*>(m_deferredData)->m_SBinds.emplace_back(retval);
return nullptr; return retval;
}
} }
};
D3D12ShaderPipeline* retval = new D3D12ShaderPipeline(m_ctx, vertBlobOut.Get(), fragBlobOut.Get(), pipelineBlob.Get(), GraphicsDataToken commitTransaction(const FactoryCommitFunc& trans)
static_cast<const D3D12VertexFormat*>(vtxFmt),
srcFac, dstFac, prim, depthTest, depthWrite, backfaceCulling);
if (!pipelineBlob)
retval->m_state->GetCachedBlob(&pipelineBlob);
if (!m_deferredData)
m_deferredData = new struct D3D12Data();
static_cast<D3D12Data*>(m_deferredData)->m_SPs.emplace_back(retval);
return retval;
}
IShaderDataBinding* newShaderDataBinding(IShaderPipeline* pipeline,
IVertexFormat* vtxFormat,
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbuf, IGraphicsBuffer* ibuf,
size_t ubufCount, IGraphicsBuffer** ubufs,
size_t texCount, ITexture** texs)
{ {
D3D12ShaderDataBinding* retval = if (m_deferredData)
new D3D12ShaderDataBinding(m_ctx, pipeline, vbuf, instVbuf, ibuf, ubufCount, ubufs, texCount, texs); Log.report(logvisor::Fatal, "nested commitTransaction usage detected");
if (!m_deferredData) m_deferredData = new D3D12Data();
m_deferredData = new struct D3D12Data();
static_cast<D3D12Data*>(m_deferredData)->m_SBinds.emplace_back(retval);
return retval;
}
void reset() D3D12DataFactory::Context ctx(*this);
{ if (!trans(ctx))
delete static_cast<D3D12Data*>(m_deferredData); {
m_deferredData = nullptr; delete m_deferredData;
} m_deferredData = nullptr;
GraphicsDataToken commit()
{
if (!m_deferredData)
return GraphicsDataToken(this, nullptr); return GraphicsDataToken(this, nullptr);
}
D3D12Data* retval = static_cast<D3D12Data*>(m_deferredData); D3D12Data* retval = static_cast<D3D12Data*>(m_deferredData);
@ -1771,8 +1756,10 @@ public:
tex->m_tex.Reset(); tex->m_tex.Reset();
/* All set! */ /* All set! */
std::unique_lock<std::mutex> lk(m_committedMutex);
m_deferredData = nullptr; m_deferredData = nullptr;
m_committedData.insert(retval); m_committedData.insert(retval);
lk.unlock();
return GraphicsDataToken(this, retval); return GraphicsDataToken(this, retval);
} }
}; };

View File

@ -563,7 +563,13 @@ struct GLShaderDataBinding : IShaderDataBinding
{ {
m_ubufOffs.reserve(ubufCount); m_ubufOffs.reserve(ubufCount);
for (size_t i=0 ; i<ubufCount ; ++i) for (size_t i=0 ; i<ubufCount ; ++i)
m_ubufOffs.emplace_back(ubufOffs[i], ubufSizes[i]); {
#ifndef NDEBUG
if (ubufOffs[i] % 256)
Log.report(logvisor::Fatal, "non-256-byte-aligned uniform-offset %d provided to newShaderDataBinding", int(i));
#endif
m_ubufOffs.emplace_back(ubufOffs[i], (ubufSizes[i] + 255) & ~255);
}
} }
for (size_t i=0 ; i<ubufCount ; ++i) for (size_t i=0 ; i<ubufCount ; ++i)
{ {

View File

@ -2085,7 +2085,13 @@ struct VulkanShaderDataBinding : IShaderDataBinding
{ {
m_ubufOffs.reserve(ubufCount); m_ubufOffs.reserve(ubufCount);
for (size_t i=0 ; i<ubufCount ; ++i) for (size_t i=0 ; i<ubufCount ; ++i)
m_ubufOffs.push_back({VK_NULL_HANDLE, ubufOffs[i], ubufSizes[i]}); {
#ifndef NDEBUG
if (ubufOffs[i] % 256)
Log.report(logvisor::Fatal, "non-256-byte-aligned uniform-offset %d provided to newShaderDataBinding", int(i));
#endif
m_ubufOffs.push_back({VK_NULL_HANDLE, ubufOffs[i], (ubufSizes[i] + 255) & ~255});
}
} }
for (size_t i=0 ; i<ubufCount ; ++i) for (size_t i=0 ; i<ubufCount ; ++i)
{ {

View File

@ -310,7 +310,7 @@ struct TestApplicationCallback : IApplicationCallback
else if (ctx.platform() == IGraphicsDataFactory::Platform::D3D12 || else if (ctx.platform() == IGraphicsDataFactory::Platform::D3D12 ||
ctx.platform() == IGraphicsDataFactory::Platform::D3D11) ctx.platform() == IGraphicsDataFactory::Platform::D3D11)
{ {
ID3DDataFactory* d3dF = dynamic_cast<ID3DDataFactory*>(factory); ID3DDataFactory::Context& d3dF = dynamic_cast<ID3DDataFactory::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"
@ -335,14 +335,14 @@ struct TestApplicationCallback : IApplicationCallback
ComPtr<ID3DBlob> vsCompile; ComPtr<ID3DBlob> vsCompile;
ComPtr<ID3DBlob> psCompile; ComPtr<ID3DBlob> psCompile;
ComPtr<ID3DBlob> cachedPipeline; ComPtr<ID3DBlob> cachedPipeline;
pipeline = d3dF->newShaderPipeline(VS, PS, vsCompile, psCompile, cachedPipeline, vfmt, pipeline = d3dF.newShaderPipeline(VS, PS, vsCompile, psCompile, cachedPipeline, vfmt,
BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips, BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips,
true, true, false); true, true, false);
} }
#elif BOO_HAS_METAL #elif BOO_HAS_METAL
else if (ctx.platform() == IGraphicsDataFactory::Platform::Metal) else if (ctx.platform() == IGraphicsDataFactory::Platform::Metal)
{ {
MetalDataFactory* metalF = dynamic_cast<MetalDataFactory*>(factory); MetalDataFactory::Context& metalF = dynamic_cast<MetalDataFactory::Context&>(ctx);
static const char* VS = static const char* VS =
"#include <metal_stdlib>\n" "#include <metal_stdlib>\n"
@ -367,15 +367,17 @@ struct TestApplicationCallback : IApplicationCallback
" return tex.sample(samp, d.out_uv);\n" " return tex.sample(samp, d.out_uv);\n"
"}\n"; "}\n";
pipeline = metalF->newShaderPipeline(VS, FS, vfmt, 1, pipeline = metalF.newShaderPipeline(VS, FS, vfmt, 1,
BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips, BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips,
true, true, false); true, true, false);
} }
#endif #endif
/* Make shader data binding */ /* Make shader data binding */
self->m_binding = self->m_binding =
ctx.newShaderDataBinding(pipeline, vfmt, vbo, nullptr, nullptr, 0, nullptr, 1, &texture); ctx.newShaderDataBinding(pipeline, vfmt, vbo, nullptr, nullptr, 0, nullptr, 1, &texture);
return true;
}); });
/* Return control to client */ /* Return control to client */