Working HECL shader generation on D3D11/12

This commit is contained in:
Jack Andersen 2015-11-17 20:14:49 -10:00
parent 742e062cf2
commit 998255efd5
12 changed files with 229 additions and 88 deletions

View File

@ -11,15 +11,21 @@
#include <vector>
#include <unordered_set>
typedef HRESULT (WINAPI *pD3DCreateBlob)
(SIZE_T Size,
ID3DBlob** ppBlob);
extern pD3DCreateBlob D3DCreateBlobPROC;
namespace boo
{
class ID3DDataFactory : public IGraphicsDataFactory
{
public:
bool bindingNeedsVertexFormat() const {return false;}
virtual IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource,
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut,
IVertexFormat* vtxFmt,
ComPtr<ID3DBlob>& pipelineBlob, IVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac,
bool depthTest, bool depthWrite, bool backfaceCulling)=0;
};

View File

@ -21,7 +21,7 @@ public:
~GLDataFactory() {}
Platform platform() const {return PlatformOGL;}
const char* platformName() const {return "OGL";}
const SystemChar* platformName() const {return _S("OGL");}
IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
IGraphicsBufferS* newStaticBuffer(BufferUse use, std::unique_ptr<uint8_t[]>&& data, size_t stride, size_t count);
@ -34,6 +34,7 @@ public:
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
ITextureR* newRenderTexture(size_t width, size_t height, size_t samples);
bool bindingNeedsVertexFormat() const {return true;}
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements);
IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource,

View File

@ -18,7 +18,7 @@ struct IGraphicsCommandQueue
using Platform = IGraphicsDataFactory::Platform;
virtual Platform platform() const=0;
virtual const char* platformName() const=0;
virtual const SystemChar* platformName() const=0;
virtual void setShaderDataBinding(IShaderDataBinding* binding)=0;
virtual void setRenderTarget(ITextureR* target)=0;

View File

@ -3,6 +3,7 @@
#include <memory>
#include <stdint.h>
#include "boo/System.hpp"
namespace boo
{
@ -169,7 +170,7 @@ struct IGraphicsDataFactory
PlatformGX2
};
virtual Platform platform() const=0;
virtual const char* platformName() const=0;
virtual const SystemChar* platformName() const=0;
virtual IGraphicsBufferS*
newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)=0;
@ -189,6 +190,7 @@ struct IGraphicsDataFactory
virtual ITextureR*
newRenderTexture(size_t width, size_t height, size_t samples)=0;
virtual bool bindingNeedsVertexFormat() const=0;
virtual IVertexFormat*
newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)=0;

View File

@ -74,7 +74,8 @@ class D3D11GraphicsBufferD : public IGraphicsBufferD
{
size_t sz = stride * count;
for (int i=0 ; i<3 ; ++i)
ThrowIfFailed(ctx->m_dev->CreateBuffer(&CD3D11_BUFFER_DESC(sz, USE_TABLE[use]), nullptr, &m_bufs[i]));
ThrowIfFailed(ctx->m_dev->CreateBuffer(&CD3D11_BUFFER_DESC(sz, USE_TABLE[use],
D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE), nullptr, &m_bufs[i]));
}
public:
size_t m_stride;
@ -439,7 +440,7 @@ struct D3D11ShaderDataBinding : IShaderDataBinding
struct D3D11CommandQueue : IGraphicsCommandQueue
{
Platform platform() const {return IGraphicsDataFactory::PlatformD3D11;}
const char* platformName() const {return "D3D11";}
const SystemChar* platformName() const {return _S("D3D11");}
D3D11Context* m_ctx;
D3D11Context::Window* m_windowCtx;
IGraphicsContext* m_parent;
@ -577,6 +578,8 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
m_deferredCtx->RSSetViewports(1, &vp);
}
void flushBufferUpdates() {}
std::unordered_map<D3D11TextureR*, std::pair<size_t, size_t>> m_texResizes;
void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)
{
@ -712,7 +715,7 @@ public:
~D3D11DataFactory() = default;
Platform platform() const {return PlatformD3D11;}
const char* platformName() const {return "D3D11";}
const SystemChar* platformName() const {return _S("D3D11");}
IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
{
@ -786,24 +789,31 @@ public:
IShaderPipeline* newShaderPipeline
(const char* vertSource, const char* fragSource,
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut,
IVertexFormat* vtxFmt, BlendFactor srcFac, BlendFactor dstFac,
bool depthTest, bool depthWrite, bool backfaceCulling)
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut,
ComPtr<ID3DBlob>& pipelineBlob, IVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac,
bool depthTest, bool depthWrite, bool backfaceCulling)
{
ComPtr<ID3DBlob> errBlob;
if (FAILED(D3DCompilePROC(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main",
"vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob)))
if (!vertBlobOut)
{
Log.report(LogVisor::FatalError, "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::FatalError, "error compiling vert shader: %s", errBlob->GetBufferPointer());
return nullptr;
}
}
if (FAILED(D3DCompilePROC(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main",
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob)))
if (!fragBlobOut)
{
Log.report(LogVisor::FatalError, "error compiling pixel shader: %s", errBlob->GetBufferPointer());
return nullptr;
if (FAILED(D3DCompilePROC(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main",
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob)))
{
Log.report(LogVisor::FatalError, "error compiling pixel shader: %s", errBlob->GetBufferPointer());
return nullptr;
}
}
D3D11ShaderPipeline* retval = new D3D11ShaderPipeline(m_ctx, vertBlobOut.Get(), fragBlobOut.Get(),

View File

@ -68,13 +68,15 @@ class D3D12GraphicsBufferS : public IGraphicsBufferS
: m_state(USE_TABLE[use]), m_stride(stride), m_count(count), m_sz(stride * count)
{
m_gpuDesc = CD3DX12_RESOURCE_DESC::Buffer(m_sz);
size_t reqSz = GetRequiredIntermediateSize(ctx->m_dev.Get(), &m_gpuDesc, 0, 1);
m_gpuDesc = CD3DX12_RESOURCE_DESC::Buffer(reqSz);
ThrowIfFailed(ctx->m_dev->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE, &m_gpuDesc,
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_buf));
D3D12_SUBRESOURCE_DATA upData = {data, m_sz, m_sz};
if (!PrepSubresources<16>(ctx->m_dev.Get(), m_gpuDesc, m_buf.Get(), 0, 0, 1, &upData))
D3D12_SUBRESOURCE_DATA upData = {data, LONG_PTR(m_sz), LONG_PTR(m_sz)};
if (!PrepSubresources<1>(ctx->m_dev.Get(), &m_gpuDesc, m_buf.Get(), 0, 0, 1, &upData))
Log.report(LogVisor::FatalError, "error preparing resource for upload");
}
public:
@ -90,7 +92,7 @@ public:
nullptr, __uuidof(ID3D12Resource), &m_gpuBuf));
/* Stage resource upload */
CommandSubresourcesTransfer<16>(ctx->m_dev.Get(), ctx->m_loadlist.Get(), m_gpuBuf.Get(), m_buf.Get(), 0, 0, 1);
CommandSubresourcesTransfer<1>(ctx->m_dev.Get(), ctx->m_loadlist.Get(), m_gpuBuf.Get(), m_buf.Get(), 0, 0, 1);
ctx->m_loadlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_gpuBuf.Get(),
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));
@ -104,15 +106,20 @@ class D3D12GraphicsBufferD : public IGraphicsBufferD
friend struct D3D12CommandQueue;
D3D12CommandQueue* m_q;
D3D12_RESOURCE_STATES m_state;
size_t m_mappedSz;
void* m_mappedBuf = nullptr;
D3D12GraphicsBufferD(D3D12CommandQueue* q, BufferUse use, D3D12Context* ctx, size_t stride, size_t count)
: m_state(USE_TABLE[use]), m_q(q), m_stride(stride), m_count(count)
{
size_t sz = stride * count;
D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Buffer(sz);
size_t reqSz = GetRequiredIntermediateSize(ctx->m_dev.Get(), &desc, 0, 1);
desc = CD3DX12_RESOURCE_DESC::Buffer(reqSz);
for (int i=0 ; i<2 ; ++i)
{
ThrowIfFailed(ctx->m_dev->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(sz),
D3D12_HEAP_FLAG_NONE, &desc,
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_bufs[i]));
}
}
@ -150,9 +157,10 @@ class D3D12TextureS : public ITextureS
: m_sz(sz)
{
m_gpuDesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, mips);
size_t reqSz = GetRequiredIntermediateSize(ctx->m_dev.Get(), &m_gpuDesc, 0, mips);
ThrowIfFailed(ctx->m_dev->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(sz),
D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(reqSz),
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_tex));
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
@ -167,7 +175,7 @@ class D3D12TextureS : public ITextureS
height /= 2;
}
if (!PrepSubresources<16>(ctx->m_dev.Get(), m_gpuDesc, m_tex.Get(), 0, 0, m_gpuDesc.MipLevels, upData))
if (!PrepSubresources<16>(ctx->m_dev.Get(), &m_gpuDesc, m_tex.Get(), 0, 0, m_gpuDesc.MipLevels, upData))
Log.report(LogVisor::FatalError, "error preparing resource for upload");
}
public:
@ -196,15 +204,20 @@ class D3D12TextureD : public ITextureD
size_t m_width = 0;
size_t m_height = 0;
D3D12CommandQueue* m_q;
D3D12_RESOURCE_DESC m_gpuDesc;
size_t m_mappedSz;
void* m_mappedBuf = nullptr;
D3D12TextureD(D3D12CommandQueue* q, D3D12Context* ctx, size_t width, size_t height, TextureFormat fmt)
: m_q(q)
{
m_gpuDesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height);
size_t reqSz = GetRequiredIntermediateSize(ctx->m_dev.Get(), &m_gpuDesc, 0, 1);
for (int i=0 ; i<2 ; ++i)
{
ThrowIfFailed(ctx->m_dev->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height),
&CD3DX12_RESOURCE_DESC::Buffer(reqSz),
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_texs[i]));
}
}
@ -221,11 +234,10 @@ public:
{
for (int i=0 ; i<2 ; ++i)
{
D3D12_RESOURCE_DESC desc = m_texs[i]->GetDesc();
ThrowIfFailed(ctx->m_dev->CreatePlacedResource(gpuHeap, offset, &desc,
ThrowIfFailed(ctx->m_dev->CreatePlacedResource(gpuHeap, offset, &m_gpuDesc,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
nullptr, __uuidof(ID3D12Resource), &m_gpuTexs[i]));
offset = NextHeapOffset(offset, ctx->m_dev->GetResourceAllocationInfo(0, 1, &desc));
offset = NextHeapOffset(offset, ctx->m_dev->GetResourceAllocationInfo(0, 1, &m_gpuDesc));
}
return offset;
}
@ -388,7 +400,7 @@ static const D3D12_BLEND BLEND_FACTOR_TABLE[] =
class D3D12ShaderPipeline : public IShaderPipeline
{
friend class D3D12DataFactory;
D3D12ShaderPipeline(D3D12Context* ctx, ID3DBlob* vert, ID3DBlob* pixel,
D3D12ShaderPipeline(D3D12Context* ctx, ID3DBlob* vert, ID3DBlob* pixel, ID3DBlob* pipeline,
const D3D12VertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac,
bool depthTest, bool depthWrite, bool backfaceCulling)
@ -420,6 +432,11 @@ class D3D12ShaderPipeline : public IShaderPipeline
desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
desc.SampleDesc.Count = 1;
if (pipeline)
{
desc.CachedPSO.pCachedBlob = pipeline->GetBufferPointer();
desc.CachedPSO.CachedBlobSizeInBytes = pipeline->GetBufferSize();
}
ThrowIfFailed(ctx->m_dev->CreateGraphicsPipelineState(&desc, __uuidof(ID3D12PipelineState), &m_state));
}
public:
@ -580,8 +597,6 @@ struct D3D12ShaderDataBinding : IShaderDataBinding
ThrowIfFailed(ctx->m_dev->CreateDescriptorHeap(&desc, _uuidof(ID3D12DescriptorHeap), &m_descHeap[b]));
CD3DX12_CPU_DESCRIPTOR_HANDLE handle(m_descHeap[b]->GetCPUDescriptorHandleForHeapStart());
D3D12_CONSTANT_BUFFER_VIEW_DESC viewDesc;
GetBufferGPUResource(m_vbuf, b, m_vboView[b]);
if (m_ibuf)
GetBufferGPUResource(m_ibuf, b, m_iboView[b]);
@ -589,7 +604,9 @@ struct D3D12ShaderDataBinding : IShaderDataBinding
{
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);
@ -598,7 +615,6 @@ struct D3D12ShaderDataBinding : IShaderDataBinding
{
if (i<m_texCount)
{
D3D12_SHADER_RESOURCE_VIEW_DESC viewDesc;
ctx->m_dev->CreateShaderResourceView(GetTextureGPUResource(m_texs[i], b), &Tex2DViewDesc, handle);
}
handle.Offset(1, incSz);
@ -636,7 +652,7 @@ static ID3D12GraphicsCommandList* WaitForLoadList(D3D12Context* ctx)
struct D3D12CommandQueue : IGraphicsCommandQueue
{
Platform platform() const {return IGraphicsDataFactory::PlatformD3D12;}
const char* platformName() const {return "D3D12";}
const SystemChar* platformName() const {return _S("D3D12");}
D3D12Context* m_ctx;
D3D12Context::Window* m_windowCtx;
IGraphicsContext* m_parent;
@ -703,12 +719,15 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
void setViewport(const SWindowRect& rect)
{
D3D12_VIEWPORT vp = {rect.location[0], rect.location[1], rect.size[0], rect.size[1], 0.0, 1.0};
D3D12_VIEWPORT vp = {FLOAT(rect.location[0]), FLOAT(rect.location[1]),
FLOAT(rect.size[0]), FLOAT(rect.size[1]), 0.0f, 1.0f};
m_cmdList->RSSetViewports(1, &vp);
D3D12_RECT r = {rect.location[0], rect.location[1], rect.size[0], rect.size[1]};
m_cmdList->RSSetScissorRects(1, &r);
}
void flushBufferUpdates() {}
std::unordered_map<D3D12TextureR*, std::pair<size_t, size_t>> m_texResizes;
void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)
{
@ -889,43 +908,71 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
void D3D12GraphicsBufferD::load(const void* data, size_t sz)
{
ID3D12Resource* res = m_bufs[m_q->m_fillBuf].Get();
void* d;
res->Map(0, nullptr, &d);
memcpy(d, data, sz);
res->Unmap(0, nullptr);
ID3D12Resource* gpuRes = m_gpuBufs[m_q->m_fillBuf].Get();
D3D12_SUBRESOURCE_DATA d = {data, LONG_PTR(sz), LONG_PTR(sz)};
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
m_state, D3D12_RESOURCE_STATE_COPY_DEST));
if (!UpdateSubresources<1>(m_q->m_cmdList.Get(), gpuRes, res, 0, 0, 1, &d))
Log.report(LogVisor::FatalError, "unable to update dynamic buffer data");
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
D3D12_RESOURCE_STATE_COPY_DEST, m_state));
}
void* D3D12GraphicsBufferD::map(size_t sz)
{
ID3D12Resource* res = m_bufs[m_q->m_fillBuf].Get();
void* d;
res->Map(0, nullptr, &d);
return d;
if (m_mappedBuf)
free(m_mappedBuf);
m_mappedSz = sz;
m_mappedBuf = malloc(sz);
return m_mappedBuf;
}
void D3D12GraphicsBufferD::unmap()
{
ID3D12Resource* res = m_bufs[m_q->m_fillBuf].Get();
res->Unmap(0, nullptr);
ID3D12Resource* gpuRes = m_gpuBufs[m_q->m_fillBuf].Get();
D3D12_SUBRESOURCE_DATA data = {m_mappedBuf, LONG_PTR(m_mappedSz), LONG_PTR(m_mappedSz)};
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
m_state, D3D12_RESOURCE_STATE_COPY_DEST));
if (!UpdateSubresources<1>(m_q->m_cmdList.Get(), gpuRes, res, 0, 0, 1, &data))
Log.report(LogVisor::FatalError, "unable to update dynamic buffer data");
free(m_mappedBuf);
m_mappedBuf = nullptr;
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
D3D12_RESOURCE_STATE_COPY_DEST, m_state));
}
void D3D12TextureD::load(const void* data, size_t sz)
{
ID3D12Resource* res = m_texs[m_q->m_fillBuf].Get();
void* d;
res->Map(0, nullptr, &d);
memcpy(d, data, sz);
res->Unmap(0, nullptr);
ID3D12Resource* gpuRes = m_gpuTexs[m_q->m_fillBuf].Get();
D3D12_SUBRESOURCE_DATA d = {data, LONG_PTR(m_width * 4), LONG_PTR(sz)};
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST));
if (!UpdateSubresources<1>(m_q->m_cmdList.Get(), gpuRes, res, 0, 0, 1, &d))
Log.report(LogVisor::FatalError, "unable to update dynamic texture data");
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
}
void* D3D12TextureD::map(size_t sz)
{
ID3D12Resource* res = m_texs[m_q->m_fillBuf].Get();
void* d;
res->Map(0, nullptr, &d);
return d;
if (m_mappedBuf)
free(m_mappedBuf);
m_mappedSz = sz;
m_mappedBuf = malloc(sz);
return m_mappedBuf;
}
void D3D12TextureD::unmap()
{
ID3D12Resource* res = m_texs[m_q->m_fillBuf].Get();
res->Unmap(0, nullptr);
ID3D12Resource* gpuRes = m_gpuTexs[m_q->m_fillBuf].Get();
D3D12_SUBRESOURCE_DATA data = {m_mappedBuf, LONG_PTR(m_width * 4), LONG_PTR(m_mappedSz)};
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST));
if (!UpdateSubresources<1>(m_q->m_cmdList.Get(), gpuRes, res, 0, 0, 1, &data))
Log.report(LogVisor::FatalError, "unable to update dynamic buffer data");
free(m_mappedBuf);
m_mappedBuf = nullptr;
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
}
class D3D12DataFactory : public ID3DDataFactory
@ -959,7 +1006,7 @@ public:
~D3D12DataFactory() = default;
Platform platform() const {return PlatformD3D12;}
const char* platformName() const {return "D3D12";}
const SystemChar* platformName() const {return _S("D3D12");}
IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
{
@ -1019,7 +1066,6 @@ public:
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)
{
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
D3D12VertexFormat* retval = new struct D3D12VertexFormat(elementCount, elements);
static_cast<D3D12Data*>(m_deferredData)->m_VFmts.emplace_back(retval);
return retval;
@ -1033,29 +1079,38 @@ public:
IShaderPipeline* newShaderPipeline
(const char* vertSource, const char* fragSource,
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut,
IVertexFormat* vtxFmt, BlendFactor srcFac, BlendFactor dstFac,
bool depthTest, bool depthWrite, bool backfaceCulling)
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut,
ComPtr<ID3DBlob>& pipelineBlob, IVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac,
bool depthTest, bool depthWrite, bool backfaceCulling)
{
ComPtr<ID3DBlob> errBlob;
if (FAILED(D3DCompilePROC(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main",
"vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob)))
if (!vertBlobOut)
{
Log.report(LogVisor::FatalError, "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::FatalError, "error compiling vert shader: %s", errBlob->GetBufferPointer());
return nullptr;
}
}
if (FAILED(D3DCompilePROC(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main",
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob)))
if (!fragBlobOut)
{
Log.report(LogVisor::FatalError, "error compiling pixel shader: %s", errBlob->GetBufferPointer());
return nullptr;
if (FAILED(D3DCompilePROC(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main",
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob)))
{
Log.report(LogVisor::FatalError, "error compiling pixel shader: %s", errBlob->GetBufferPointer());
return nullptr;
}
}
D3D12ShaderPipeline* retval = new D3D12ShaderPipeline(m_ctx, vertBlobOut.Get(), fragBlobOut.Get(),
static_cast<const D3D12VertexFormat*>(vtxFmt),
srcFac, dstFac, depthTest, depthWrite, backfaceCulling);
D3D12ShaderPipeline* retval = new D3D12ShaderPipeline(m_ctx, vertBlobOut.Get(), fragBlobOut.Get(), pipelineBlob.Get(),
static_cast<const D3D12VertexFormat*>(vtxFmt),
srcFac, dstFac, depthTest, depthWrite, backfaceCulling);
if (!pipelineBlob)
retval->m_state->GetCachedBlob(&pipelineBlob);
static_cast<D3D12Data*>(m_deferredData)->m_SPs.emplace_back(retval);
return retval;
}
@ -1144,12 +1199,20 @@ public:
++m_ctx->m_loadfenceval;
ThrowIfFailed(m_ctx->m_loadq->Signal(m_ctx->m_loadfence.Get(), m_ctx->m_loadfenceval));
WaitForLoadList(m_ctx);
/* Commit data bindings (create descriptor heaps) */
for (std::unique_ptr<D3D12ShaderDataBinding>& bind : retval->m_SBinds)
bind->commit(m_ctx);
/* Block handle return until data is ready on GPU */
WaitForLoadList(m_ctx);
/* Delete static upload heaps */
for (std::unique_ptr<D3D12GraphicsBufferS>& buf : retval->m_SBufs)
buf->m_buf.Reset();
for (std::unique_ptr<D3D12TextureS>& tex : retval->m_STexs)
tex->m_tex.Reset();
/* All set! */
m_deferredData = new struct D3D12Data();
m_committedData.insert(retval);

View File

@ -542,7 +542,7 @@ static const GLenum SEMANTIC_TYPE_TABLE[] =
struct GLCommandQueue : IGraphicsCommandQueue
{
Platform platform() const {return IGraphicsDataFactory::PlatformOGL;}
const char* platformName() const {return "OGL";}
const SystemChar* platformName() const {return _S("OGL");}
IGraphicsContext* m_parent = nullptr;
struct Command

View File

@ -3,7 +3,7 @@
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
// File: d3dx12.h
// Content: D3DX12 utility library
// Content: D3DX12 utility library (modified for boo data-handling)
//
//////////////////////////////////////////////////////////////////////////////
@ -1363,6 +1363,17 @@ inline UINT64 GetRequiredIntermediateSize(
return RequiredSize;
}
inline UINT64 GetRequiredIntermediateSize(
_In_ ID3D12Device* pDevice,
_In_ D3D12_RESOURCE_DESC* Desc,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources)
{
UINT64 RequiredSize = 0;
pDevice->GetCopyableFootprints(Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize);
return RequiredSize;
}
//------------------------------------------------------------------------------------------------
// All arrays must be populated (e.g. by calling GetCopyableFootprints)
inline UINT64 UpdateSubresources(
@ -1489,7 +1500,7 @@ inline UINT64 UpdateSubresources(
// All arrays must be populated (e.g. by calling GetCopyableFootprints)
inline UINT64 PrepSubresources(
_In_ ID3D12Device* pDevice,
_In_ D3D12_RESOURCE_DESC& DestinationDesc,
_In_ D3D12_RESOURCE_DESC* DestinationDesc,
_In_ ID3D12Resource* pIntermediate,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
@ -1504,7 +1515,7 @@ inline UINT64 PrepSubresources(
if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
RequiredSize > (SIZE_T)-1 ||
(DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
(DestinationDesc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
(FirstSubresource != 0 || NumSubresources != 1)))
{
return 0;
@ -1533,7 +1544,7 @@ inline UINT64 PrepSubresources(
template <UINT MaxSubresources>
inline UINT64 PrepSubresources(
_In_ ID3D12Device* pDevice,
_In_ D3D12_RESOURCE_DESC& DestinationDesc,
_In_ D3D12_RESOURCE_DESC* DestinationDesc,
_In_ ID3D12Resource* pIntermediate,
UINT64 IntermediateOffset,
_In_range_(0, MaxSubresources) UINT FirstSubresource,
@ -1545,7 +1556,7 @@ inline UINT64 PrepSubresources(
UINT NumRows[MaxSubresources];
UINT64 RowSizesInBytes[MaxSubresources];
pDevice->GetCopyableFootprints(&DestinationDesc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
pDevice->GetCopyableFootprints(DestinationDesc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
return PrepSubresources(pDevice, DestinationDesc, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData);
}

View File

@ -14,6 +14,7 @@
#include "boo/System.hpp"
#include "boo/IApplication.hpp"
#include "boo/inputdev/DeviceFinder.hpp"
#include "boo/graphicsdev/D3D.hpp"
#include <LogVisor/LogVisor.hpp>
DWORD g_mainThreadId = 0;
@ -23,6 +24,7 @@ static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignaturePROC = nullptr;
#endif
pD3DCompile D3DCompilePROC = nullptr;
pD3DCreateBlob D3DCreateBlobPROC = nullptr;
static bool FindBestD3DCompile()
{
@ -46,7 +48,8 @@ static bool FindBestD3DCompile()
if (d3dCompilelib)
{
D3DCompilePROC = (pD3DCompile)GetProcAddress(d3dCompilelib, "D3DCompile");
return D3DCompilePROC != nullptr;
D3DCreateBlobPROC = (pD3DCreateBlob)GetProcAddress(d3dCompilelib, "D3DCreateBlob");
return D3DCompilePROC != nullptr && D3DCreateBlobPROC != nullptr;
}
return false;
}
@ -202,7 +205,7 @@ public:
/* Build default sampler here */
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&CD3D11_SAMPLER_DESC(D3D11_DEFAULT), &m_3dCtx.m_ctx11.m_ss);
Log.report(LogVisor::Info, "initialized D3D12 renderer");
Log.report(LogVisor::Info, "initialized D3D11 renderer");
return;
}
@ -237,6 +240,7 @@ public:
case WM_DEVICECHANGE:
return DeviceFinder::winDevChangedHandler(wParam, lParam);
case WM_CLOSE:
case WM_SIZE:
case WM_MOVING:
case WM_SYSKEYDOWN:
@ -270,13 +274,18 @@ public:
/* Spawn client thread */
int clientReturn = 0;
std::thread clientThread([&]()
{clientReturn = m_callback.appMain(this);});
{
clientReturn = m_callback.appMain(this);
PostThreadMessage(g_mainThreadId, WM_USER+1, 0, 0);
});
/* Pump messages */
MSG msg = {0};
while (GetMessage(&msg, NULL, 0, 0))
{
if (msg.message == WM_USER)
switch (msg.message)
{
case WM_USER:
{
/* New-window message (coalesced onto main thread) */
std::unique_lock<std::mutex> lk(m_nwmt);
@ -286,8 +295,14 @@ public:
m_nwcv.notify_one();
continue;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
case WM_USER+1:
/* Quit message from client thread */
PostQuitMessage(0);
continue;
default:
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
m_callback.appQuitting(this);
@ -374,9 +389,9 @@ int ApplicationRun(IApplication::EPlatformType platform,
}
static const DEV_BROADCAST_DEVICEINTERFACE_A HOTPLUG_CONF =
static const DEV_BROADCAST_DEVICEINTERFACE HOTPLUG_CONF =
{
sizeof(DEV_BROADCAST_DEVICEINTERFACE_A),
sizeof(DEV_BROADCAST_DEVICEINTERFACE),
DBT_DEVTYP_DEVICEINTERFACE,
0,
GUID_DEVINTERFACE_USB_DEVICE
@ -387,7 +402,7 @@ static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
if (!HOTPLUG_REGISTERED && uMsg == WM_CREATE)
{
/* Register hotplug notification with windows */
RegisterDeviceNotificationA(hwnd, (LPVOID)&HOTPLUG_CONF, DEVICE_NOTIFY_WINDOW_HANDLE);
RegisterDeviceNotification(hwnd, (LPVOID)&HOTPLUG_CONF, DEVICE_NOTIFY_WINDOW_HANDLE);
HOTPLUG_REGISTERED = true;
}
return static_cast<boo::ApplicationWin32*>(boo::APP)->winHwndHandler(hwnd, uMsg, wParam, lParam);

View File

@ -132,7 +132,7 @@ struct Boo3DAppContext
D3D12Context::Window& win = m_ctx12.m_windows[window];
BOOL isFScr;
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
return isFScr;
return isFScr != 0;
}
#endif
if (m_ctx11.m_dev)
@ -167,7 +167,8 @@ struct Boo3DAppContext
out->GetDesc(&outDesc);
win.m_swapChain->SetFullscreenState(true, nullptr);
DXGI_MODE_DESC mdesc = {outDesc.DesktopCoordinates.right, outDesc.DesktopCoordinates.bottom};
DXGI_MODE_DESC mdesc = {UINT(outDesc.DesktopCoordinates.right - outDesc.DesktopCoordinates.left),
UINT(outDesc.DesktopCoordinates.bottom - outDesc.DesktopCoordinates.top)};
win.m_swapChain->ResizeTarget(&mdesc);
}
else

View File

@ -171,6 +171,11 @@ public:
return m_dataFactory;
}
IGraphicsDataFactory* getMainContextDataFactory()
{
return m_dataFactory;
}
IGraphicsDataFactory* getLoadContextDataFactory()
{
return m_dataFactory;
@ -331,6 +336,22 @@ public:
return m_dataFactory;
}
/* Creates a new context on current thread!! Call from client loading thread */
HGLRC m_mainCtx = 0;
IGraphicsDataFactory* getMainContextDataFactory()
{
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
if (!m_mainCtx)
{
m_mainCtx = wglCreateContextAttribsARB(w.m_deviceContext, w.m_mainContext, ContextAttribs);
if (!m_mainCtx)
Log.report(LogVisor::FatalError, "unable to make main WGL context");
}
if (!wglMakeCurrent(w.m_deviceContext, m_mainCtx))
Log.report(LogVisor::FatalError, "unable to make main WGL context current");
return m_dataFactory;
}
/* Creates a new context on current thread!! Call from client loading thread */
HGLRC m_loadCtx = 0;
IGraphicsDataFactory* getLoadContextDataFactory()
@ -595,6 +616,10 @@ public:
HWNDEvent& e = *static_cast<HWNDEvent*>(ev);
switch (e.uMsg)
{
case WM_CLOSE:
if (m_callback)
m_callback->destroyed();
return;
case WM_SIZE:
{
SWindowRect rect;
@ -811,6 +836,12 @@ public:
return m_gfxCtx->getDataFactory();
}
/* Creates a new context on current thread!! Call from main client thread */
IGraphicsDataFactory* getMainContextDataFactory()
{
return m_gfxCtx->getMainContextDataFactory();
}
/* Creates a new context on current thread!! Call from client loading thread */
IGraphicsDataFactory* getLoadContextDataFactory()
{

View File

@ -335,7 +335,8 @@ struct TestApplicationCallback : IApplicationCallback
ComPtr<ID3DBlob> vsCompile;
ComPtr<ID3DBlob> psCompile;
pipeline = d3dF->newShaderPipeline(VS, PS, vsCompile, psCompile, vfmt,
ComPtr<ID3DBlob> cachedPipeline;
pipeline = d3dF->newShaderPipeline(VS, PS, vsCompile, psCompile, cachedPipeline, vfmt,
BlendFactorOne, BlendFactorZero, true, true, false);
}
#elif __APPLE__