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:
virtual ~ID3DDataFactory() {}
bool bindingNeedsVertexFormat() const {return false;}
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;
class Context : public IGraphicsDataFactory::Context
{
public:
bool bindingNeedsVertexFormat() const {return false;}
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
#include <memory>
#include <functional>
#include <stdint.h>
#include "boo/System.hpp"

View File

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

View File

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

View File

@ -563,7 +563,13 @@ struct GLShaderDataBinding : IShaderDataBinding
{
m_ubufOffs.reserve(ubufCount);
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)
{

View File

@ -2085,7 +2085,13 @@ struct VulkanShaderDataBinding : IShaderDataBinding
{
m_ubufOffs.reserve(ubufCount);
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)
{

View File

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