More D3D12 work

This commit is contained in:
Jack Andersen 2015-11-03 14:27:32 -10:00
parent 50bca6f58e
commit bc84471d4d
7 changed files with 293 additions and 94 deletions

View File

@ -35,6 +35,7 @@ public:
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
const void* data, size_t sz); const void* data, size_t sz);
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt); ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
ITextureR* newRenderTexture(size_t width, size_t height, size_t samples);
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements); IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements);

View File

@ -21,8 +21,7 @@ struct IGraphicsCommandQueue
virtual const char* platformName() const=0; virtual const char* platformName() const=0;
virtual void setShaderDataBinding(IShaderDataBinding* binding)=0; virtual void setShaderDataBinding(IShaderDataBinding* binding)=0;
virtual void setRenderTarget(IWindow* window)=0; virtual void setRenderTarget(ITextureR* target)=0;
virtual void setRenderTarget(ITextureD* target)=0;
virtual void setViewport(const SWindowRect& rect)=0; virtual void setViewport(const SWindowRect& rect)=0;
virtual void setClearColor(const float rgba[4])=0; virtual void setClearColor(const float rgba[4])=0;
@ -34,7 +33,7 @@ struct IGraphicsCommandQueue
virtual void drawInstances(size_t start, size_t count, size_t instCount)=0; virtual void drawInstances(size_t start, size_t count, size_t instCount)=0;
virtual void drawInstancesIndexed(size_t start, size_t count, size_t instCount)=0; virtual void drawInstancesIndexed(size_t start, size_t count, size_t instCount)=0;
virtual void present()=0; virtual void resolveDisplay(ITextureR* source)=0;
virtual void execute()=0; virtual void execute()=0;
}; };

View File

@ -41,19 +41,31 @@ enum BufferUse
BufferUseUniform BufferUseUniform
}; };
enum TextureType
{
TextureStatic,
Texture
};
struct ITexture struct ITexture
{ {
bool dynamic() const {return m_dynamic;} enum Type
{
TextureStatic,
TextureDynamic,
TextureRender
};
Type type() const {return m_type;}
protected: protected:
bool m_dynamic; Type m_type;
ITexture(bool dynamic) : m_dynamic(dynamic) {} ITexture(Type type) : m_type(type) {}
}; };
/** Static resource buffer for textures */ /** Static resource buffer for textures */
struct ITextureS : ITexture struct ITextureS : ITexture
{ {
protected: protected:
ITextureS() : ITexture(false) {} ITextureS() : ITexture(TextureStatic) {}
}; };
/** Dynamic resource buffer for textures */ /** Dynamic resource buffer for textures */
@ -63,7 +75,14 @@ struct ITextureD : ITexture
virtual void* map(size_t sz)=0; virtual void* map(size_t sz)=0;
virtual void unmap()=0; virtual void unmap()=0;
protected: protected:
ITextureD() : ITexture(true) {} ITextureD() : ITexture(TextureDynamic) {}
};
/** Resource buffer for render-target textures */
struct ITextureR : ITexture
{
protected:
ITextureR() : ITexture(TextureRender) {}
}; };
/** Supported texture formats */ /** Supported texture formats */
@ -157,6 +176,8 @@ struct IGraphicsDataFactory
const void* data, size_t sz)=0; const void* data, size_t sz)=0;
virtual ITextureD* virtual ITextureD*
newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0; newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0;
virtual ITextureR*
newRenderTexture(size_t width, size_t height, size_t samples)=0;
virtual IVertexFormat* virtual IVertexFormat*
newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)=0; newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)=0;

View File

@ -38,6 +38,7 @@ struct D3D12Data : IGraphicsData
std::vector<std::unique_ptr<class D3D12GraphicsBufferD>> m_DBufs; std::vector<std::unique_ptr<class D3D12GraphicsBufferD>> m_DBufs;
std::vector<std::unique_ptr<class D3D12TextureS>> m_STexs; std::vector<std::unique_ptr<class D3D12TextureS>> m_STexs;
std::vector<std::unique_ptr<class D3D12TextureD>> m_DTexs; std::vector<std::unique_ptr<class D3D12TextureD>> m_DTexs;
std::vector<std::unique_ptr<class D3D12TextureR>> m_RTexs;
std::vector<std::unique_ptr<struct D3D12VertexFormat>> m_VFmts; std::vector<std::unique_ptr<struct D3D12VertexFormat>> m_VFmts;
ComPtr<ID3D12Heap> m_gpuHeap; ComPtr<ID3D12Heap> m_gpuHeap;
}; };
@ -94,7 +95,7 @@ class D3D12GraphicsBufferD : public IGraphicsBufferD
: m_state(USE_TABLE[use]), m_q(q), m_stride(stride), m_count(count) : m_state(USE_TABLE[use]), m_q(q), m_stride(stride), m_count(count)
{ {
size_t sz = stride * count; size_t sz = stride * count;
for (int i=0 ; i<3 ; ++i) for (int i=0 ; i<2 ; ++i)
{ {
ThrowIfFailed(ctx->m_dev->CreateCommittedResource( ThrowIfFailed(ctx->m_dev->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
@ -105,8 +106,8 @@ class D3D12GraphicsBufferD : public IGraphicsBufferD
public: public:
size_t m_stride; size_t m_stride;
size_t m_count; size_t m_count;
ComPtr<ID3D12Resource> m_bufs[3]; ComPtr<ID3D12Resource> m_bufs[2];
ComPtr<ID3D12Resource> m_gpuBufs[3]; ComPtr<ID3D12Resource> m_gpuBufs[2];
~D3D12GraphicsBufferD() = default; ~D3D12GraphicsBufferD() = default;
void load(const void* data, size_t sz); void load(const void* data, size_t sz);
@ -115,7 +116,7 @@ public:
UINT64 placeForGPU(D3D12Context* ctx, ID3D12Heap* gpuHeap, UINT64 offset) UINT64 placeForGPU(D3D12Context* ctx, ID3D12Heap* gpuHeap, UINT64 offset)
{ {
for (int i=0 ; i<3 ; ++i) for (int i=0 ; i<2 ; ++i)
{ {
D3D12_RESOURCE_DESC desc = m_bufs[i]->GetDesc(); D3D12_RESOURCE_DESC desc = m_bufs[i]->GetDesc();
ThrowIfFailed(ctx->m_dev->CreatePlacedResource(gpuHeap, offset, &desc, m_state, ThrowIfFailed(ctx->m_dev->CreatePlacedResource(gpuHeap, offset, &desc, m_state,
@ -184,40 +185,23 @@ class D3D12TextureD : public ITextureD
D3D12CommandQueue* m_q; D3D12CommandQueue* m_q;
D3D12TextureD(D3D12CommandQueue* q, D3D12Context* ctx, size_t width, size_t height, TextureFormat fmt) D3D12TextureD(D3D12CommandQueue* q, D3D12Context* ctx, size_t width, size_t height, TextureFormat fmt)
: m_q(q) : m_q(q)
{
for (int i=0 ; i<2 ; ++i)
{ {
ThrowIfFailed(ctx->m_dev->CreateCommittedResource( ThrowIfFailed(ctx->m_dev->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height),
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_texs[0])); D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_texs[i]));
ThrowIfFailed(ctx->m_dev->CreateCommittedResource( }
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D24_UNORM_S8_UINT, width, height),
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_texs[1]));
} }
public: public:
ComPtr<ID3D12Resource> m_texs[2]; ComPtr<ID3D12Resource> m_texs[2];
ComPtr<ID3D12Resource> m_gpuTexs[2]; ComPtr<ID3D12Resource> m_gpuTexs[2];
ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
ComPtr<ID3D12DescriptorHeap> m_dsvHeap;
~D3D12TextureD() = default; ~D3D12TextureD() = default;
void load(const void* data, size_t sz) void load(const void* data, size_t sz);
{ void* map(size_t sz);
void* buf; void unmap();
m_texs[0]->Map(0, nullptr, &buf);
memcpy(buf, data, sz);
m_texs[0]->Unmap(0, nullptr);
}
void* map(size_t sz)
{
void* buf;
m_texs[0]->Map(0, nullptr, &buf);
return buf;
}
void unmap()
{
m_texs[0]->Unmap(0, nullptr);
}
UINT64 placeForGPU(D3D12Context* ctx, ID3D12Heap* gpuHeap, UINT64 offset) UINT64 placeForGPU(D3D12Context* ctx, ID3D12Heap* gpuHeap, UINT64 offset)
{ {
@ -225,10 +209,39 @@ public:
{ {
D3D12_RESOURCE_DESC desc = m_texs[i]->GetDesc(); D3D12_RESOURCE_DESC desc = m_texs[i]->GetDesc();
ThrowIfFailed(ctx->m_dev->CreatePlacedResource(gpuHeap, offset, &desc, ThrowIfFailed(ctx->m_dev->CreatePlacedResource(gpuHeap, offset, &desc,
i ? D3D12_RESOURCE_STATE_DEPTH_WRITE : D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
nullptr, __uuidof(ID3D12Resource), &m_gpuTexs[i])); 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, &desc));
} }
return offset;
}
};
static const float BLACK_COLOR[] = {0.0,0.0,0.0,1.0};
class D3D12TextureR : public ITextureR
{
friend class D3D12DataFactory;
friend struct D3D12CommandQueue;
size_t m_width = 0;
size_t m_height = 0;
size_t m_samples = 0;
D3D12TextureR(D3D12Context* ctx, size_t width, size_t height, size_t samples)
: m_width(width), m_height(height), m_samples(samples)
{
if (samples == 0) m_samples = 1;
CD3DX12_RESOURCE_DESC rtvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, m_width, m_height, 1, 0, m_samples,
0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT);
ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE,
&rtvresdesc, D3D12_RESOURCE_STATE_RENDER_TARGET, &CD3DX12_CLEAR_VALUE(DXGI_FORMAT_R8G8B8A8_UNORM, BLACK_COLOR),
__uuidof(ID3D12Resource), &m_gpuTexs[0]));
CD3DX12_RESOURCE_DESC dsvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D24_UNORM_S8_UINT, m_width, m_height, 1, 0, m_samples,
0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT);
ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE,
&dsvresdesc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &CD3DX12_CLEAR_VALUE(DXGI_FORMAT_D24_UNORM_S8_UINT, 1.0, 0),
__uuidof(ID3D12Resource), &m_gpuTexs[1]));
D3D12_DESCRIPTOR_HEAP_DESC rtvdesc = {D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1}; D3D12_DESCRIPTOR_HEAP_DESC rtvdesc = {D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1};
ThrowIfFailed(ctx->m_dev->CreateDescriptorHeap(&rtvdesc, __uuidof(ID3D12DescriptorHeap), &m_rtvHeap)); ThrowIfFailed(ctx->m_dev->CreateDescriptorHeap(&rtvdesc, __uuidof(ID3D12DescriptorHeap), &m_rtvHeap));
@ -239,9 +252,12 @@ public:
ThrowIfFailed(ctx->m_dev->CreateDescriptorHeap(&dsvdesc, __uuidof(ID3D12DescriptorHeap), &m_dsvHeap)); ThrowIfFailed(ctx->m_dev->CreateDescriptorHeap(&dsvdesc, __uuidof(ID3D12DescriptorHeap), &m_dsvHeap));
D3D12_DEPTH_STENCIL_VIEW_DESC dsvvdesc = {DXGI_FORMAT_D24_UNORM_S8_UINT, D3D12_DSV_DIMENSION_TEXTURE2D}; D3D12_DEPTH_STENCIL_VIEW_DESC dsvvdesc = {DXGI_FORMAT_D24_UNORM_S8_UINT, D3D12_DSV_DIMENSION_TEXTURE2D};
ctx->m_dev->CreateDepthStencilView(m_gpuTexs[1].Get(), &dsvvdesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); ctx->m_dev->CreateDepthStencilView(m_gpuTexs[1].Get(), &dsvvdesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
return offset;
} }
public:
ComPtr<ID3D12Resource> m_gpuTexs[2];
ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
ComPtr<ID3D12DescriptorHeap> m_dsvHeap;
~D3D12TextureR() = default;
}; };
ITextureS* ITextureS*
@ -397,9 +413,9 @@ static UINT64 PlaceBufferForGPU(IGraphicsBuffer* buf, D3D12Context* ctx, ID3D12H
static UINT64 PlaceTextureForGPU(ITexture* tex, D3D12Context* ctx, ID3D12Heap* gpuHeap, UINT64 offset) static UINT64 PlaceTextureForGPU(ITexture* tex, D3D12Context* ctx, ID3D12Heap* gpuHeap, UINT64 offset)
{ {
if (tex->dynamic()) if (tex->type() == ITexture::TextureDynamic)
return static_cast<D3D12TextureD*>(tex)->placeForGPU(ctx, gpuHeap, offset); return static_cast<D3D12TextureD*>(tex)->placeForGPU(ctx, gpuHeap, offset);
else else if (tex->type() == ITexture::TextureStatic)
return static_cast<D3D12TextureS*>(tex)->placeForGPU(ctx, gpuHeap, offset); return static_cast<D3D12TextureS*>(tex)->placeForGPU(ctx, gpuHeap, offset);
} }
@ -429,12 +445,12 @@ static ID3D12Resource* GetBufferGPUResource(const IGraphicsBuffer* buf, int idx,
static ID3D12Resource* GetTextureGPUResource(const ITexture* tex, int idx) static ID3D12Resource* GetTextureGPUResource(const ITexture* tex, int idx)
{ {
if (tex->dynamic()) if (tex->type() == ITexture::TextureDynamic)
{ {
const D3D12TextureD* ctex = static_cast<const D3D12TextureD*>(tex); const D3D12TextureD* ctex = static_cast<const D3D12TextureD*>(tex);
return ctex->m_gpuTexs[0].Get(); return ctex->m_gpuTexs[0].Get();
} }
else else if (tex->type() == ITexture::TextureStatic)
{ {
const D3D12TextureS* ctex = static_cast<const D3D12TextureS*>(tex); const D3D12TextureS* ctex = static_cast<const D3D12TextureS*>(tex);
return ctex->m_gpuTex.Get(); return ctex->m_gpuTex.Get();
@ -456,7 +472,7 @@ struct D3D12ShaderDataBinding : IShaderDataBinding
{ {
D3D12ShaderPipeline* m_pipeline; D3D12ShaderPipeline* m_pipeline;
ComPtr<ID3D12Heap> m_gpuHeap; ComPtr<ID3D12Heap> m_gpuHeap;
ComPtr<ID3D12DescriptorHeap> m_descHeap[3]; ComPtr<ID3D12DescriptorHeap> m_descHeap[2];
IGraphicsBuffer* m_vbuf; IGraphicsBuffer* m_vbuf;
IGraphicsBuffer* m_ibuf; IGraphicsBuffer* m_ibuf;
size_t m_ubufCount; size_t m_ubufCount;
@ -484,7 +500,7 @@ struct D3D12ShaderDataBinding : IShaderDataBinding
void commit(D3D12Context* ctx) void commit(D3D12Context* ctx)
{ {
/* Create triple-buffered descriptor heaps */ /* Create double-buffered descriptor heaps */
D3D12_DESCRIPTOR_HEAP_DESC desc; D3D12_DESCRIPTOR_HEAP_DESC desc;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
desc.NumDescriptors = 2 + m_ubufCount + m_texCount; desc.NumDescriptors = 2 + m_ubufCount + m_texCount;
@ -492,7 +508,7 @@ struct D3D12ShaderDataBinding : IShaderDataBinding
desc.NodeMask = 0; desc.NodeMask = 0;
UINT incSz = ctx->m_dev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); UINT incSz = ctx->m_dev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
for (int b=0 ; b<3 ; ++b) for (int b=0 ; b<2 ; ++b)
{ {
ThrowIfFailed(ctx->m_dev->CreateDescriptorHeap(&desc, _uuidof(ID3D12DescriptorHeap), &m_descHeap[b])); ThrowIfFailed(ctx->m_dev->CreateDescriptorHeap(&desc, _uuidof(ID3D12DescriptorHeap), &m_descHeap[b]));
CD3DX12_CPU_DESCRIPTOR_HANDLE handle(m_descHeap[b]->GetCPUDescriptorHandleForHeapStart()); CD3DX12_CPU_DESCRIPTOR_HANDLE handle(m_descHeap[b]->GetCPUDescriptorHandleForHeapStart());
@ -561,7 +577,7 @@ IGraphicsData* D3D12DataFactory::commit()
/* Gather resource descriptions */ /* Gather resource descriptions */
std::vector<D3D12_RESOURCE_DESC> descs; std::vector<D3D12_RESOURCE_DESC> descs;
descs.reserve(retval->m_SBufs.size() + retval->m_DBufs.size() * 3 + descs.reserve(retval->m_SBufs.size() + retval->m_DBufs.size() * 2 +
retval->m_STexs.size() + retval->m_DTexs.size() * 2); retval->m_STexs.size() + retval->m_DTexs.size() * 2);
for (std::unique_ptr<D3D12GraphicsBufferS>& buf : retval->m_SBufs) for (std::unique_ptr<D3D12GraphicsBufferS>& buf : retval->m_SBufs)
@ -571,7 +587,6 @@ IGraphicsData* D3D12DataFactory::commit()
{ {
descs.push_back(buf->m_bufs[0]->GetDesc()); descs.push_back(buf->m_bufs[0]->GetDesc());
descs.push_back(buf->m_bufs[1]->GetDesc()); descs.push_back(buf->m_bufs[1]->GetDesc());
descs.push_back(buf->m_bufs[2]->GetDesc());
} }
for (std::unique_ptr<D3D12TextureS>& tex : retval->m_STexs) for (std::unique_ptr<D3D12TextureS>& tex : retval->m_STexs)
@ -581,7 +596,6 @@ IGraphicsData* D3D12DataFactory::commit()
{ {
descs.push_back(tex->m_texs[0]->GetDesc()); descs.push_back(tex->m_texs[0]->GetDesc());
descs.push_back(tex->m_texs[1]->GetDesc()); descs.push_back(tex->m_texs[1]->GetDesc());
descs.push_back(tex->m_texs[2]->GetDesc());
} }
/* Calculate resources allocation */ /* Calculate resources allocation */
@ -636,19 +650,29 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
Platform platform() const {return IGraphicsDataFactory::PlatformD3D12;} Platform platform() const {return IGraphicsDataFactory::PlatformD3D12;}
const char* platformName() const {return "Direct 3D 12";} const char* platformName() const {return "Direct 3D 12";}
D3D12Context* m_ctx; D3D12Context* m_ctx;
D3D12Context::Window* m_windowCtx;
IGraphicsContext* m_parent; IGraphicsContext* m_parent;
ComPtr<ID3D12GraphicsCommandList> m_cmdList; ComPtr<ID3D12GraphicsCommandList> m_cmdList;
size_t m_fillBuf = 0; size_t m_fillBuf = 0;
size_t m_completeBuf = 0;
size_t m_drawBuf = 0; size_t m_drawBuf = 0;
D3D12CommandQueue(D3D12Context* ctx, IGraphicsContext* parent) void resetCommandList()
: m_ctx(ctx), m_parent(parent) {
ThrowIfFailed(m_ctx->m_qalloc[m_fillBuf]->Reset());
ThrowIfFailed(m_cmdList->Reset(m_ctx->m_qalloc[m_fillBuf].Get(), nullptr));
m_cmdList->SetGraphicsRootSignature(m_ctx->m_rs.Get());
}
D3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent)
: m_ctx(ctx), m_windowCtx(windowCtx), m_parent(parent)
{ {
ThrowIfFailed(ctx->m_dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, ThrowIfFailed(ctx->m_dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
__uuidof(ID3D12CommandAllocator), __uuidof(ID3D12CommandAllocator),
&ctx->m_qalloc)); &ctx->m_qalloc[0]));
ThrowIfFailed(ctx->m_dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
__uuidof(ID3D12CommandAllocator),
&ctx->m_qalloc[1]));
D3D12_COMMAND_QUEUE_DESC desc = D3D12_COMMAND_QUEUE_DESC desc =
{ {
D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_LIST_TYPE_DIRECT,
@ -658,7 +682,7 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
ThrowIfFailed(ctx->m_dev->CreateCommandQueue(&desc, __uuidof(ID3D12CommandQueue), &ctx->m_q)); ThrowIfFailed(ctx->m_dev->CreateCommandQueue(&desc, __uuidof(ID3D12CommandQueue), &ctx->m_q));
ThrowIfFailed(ctx->m_dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, ThrowIfFailed(ctx->m_dev->CreateFence(0, D3D12_FENCE_FLAG_NONE,
__uuidof(ID3D12Fence), &ctx->m_frameFence)); __uuidof(ID3D12Fence), &ctx->m_frameFence));
ThrowIfFailed(ctx->m_dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, ctx->m_qalloc.Get(), ThrowIfFailed(ctx->m_dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, ctx->m_qalloc[0].Get(),
nullptr, __uuidof(ID3D12GraphicsCommandList), &m_cmdList)); nullptr, __uuidof(ID3D12GraphicsCommandList), &m_cmdList));
m_cmdList->SetGraphicsRootSignature(m_ctx->m_rs.Get()); m_cmdList->SetGraphicsRootSignature(m_ctx->m_rs.Get());
} }
@ -671,19 +695,13 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
m_cmdList->SetPipelineState(cbind->m_pipeline->m_state.Get()); m_cmdList->SetPipelineState(cbind->m_pipeline->m_state.Get());
} }
D3D12TextureD* m_boundTarget = nullptr; ID3D12Resource* m_boundTarget = nullptr;
void setRenderTarget(ITextureR* target)
void setRenderTarget(IWindow* window)
{ {
D3D12TextureR* ctarget = static_cast<D3D12TextureR*>(target);
}
void setRenderTarget(ITextureD* target)
{
D3D12TextureD* ctarget = static_cast<D3D12TextureD*>(target);
if (m_boundTarget) if (m_boundTarget)
m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_boundTarget->m_gpuTexs[0].Get(), m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_boundTarget,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
m_cmdList->OMSetRenderTargets(1, &ctarget->m_rtvHeap->GetCPUDescriptorHandleForHeapStart(), m_cmdList->OMSetRenderTargets(1, &ctarget->m_rtvHeap->GetCPUDescriptorHandleForHeapStart(),
@ -692,12 +710,13 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ctarget->m_gpuTexs[0].Get(), m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ctarget->m_gpuTexs[0].Get(),
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET)); D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET));
m_boundTarget = ctarget; m_boundTarget = ctarget->m_gpuTexs[0].Get();
} }
void setViewport(const SWindowRect& rect) void setViewport(const SWindowRect& rect)
{ {
D3D12_VIEWPORT vp = {rect.location[0], rect.location[1], rect.size[0], rect.size[1], 0.0, 1.0};
m_cmdList->RSSetViewports(1, &vp);
} }
float m_clearColor[4] = {0.0,0.0,0.0,1.0}; float m_clearColor[4] = {0.0,0.0,0.0,1.0};
@ -751,21 +770,90 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
m_cmdList->DrawIndexedInstanced(count, instCount, start, 0, 0); m_cmdList->DrawIndexedInstanced(count, instCount, start, 0, 0);
} }
void present() bool m_doPresent = false;
void resolveDisplay(ITextureR* source)
{ {
m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); D3D12TextureR* csource = static_cast<D3D12TextureR*>(source);
ID3D12Resource* src = csource->m_gpuTexs[0].Get();
ID3D12Resource* dest = m_windowCtx->m_fb[m_windowCtx->m_backBuf].Get();
if (csource->m_samples > 1)
{
D3D12_RESOURCE_BARRIER msaaSetup[] =
{
CD3DX12_RESOURCE_BARRIER::Transition(src,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE),
CD3DX12_RESOURCE_BARRIER::Transition(dest,
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RESOLVE_DEST)
};
m_cmdList->ResourceBarrier(2, msaaSetup);
m_cmdList->ResolveSubresource(dest, 0, src, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
D3D12_RESOURCE_BARRIER msaaTeardown[] =
{
CD3DX12_RESOURCE_BARRIER::Transition(src,
D3D12_RESOURCE_STATE_RESOLVE_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET),
CD3DX12_RESOURCE_BARRIER::Transition(dest,
D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_PRESENT)
};
m_cmdList->ResourceBarrier(2, msaaTeardown);
}
else
{
D3D12_RESOURCE_BARRIER copySetup[] =
{
CD3DX12_RESOURCE_BARRIER::Transition(src,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE),
CD3DX12_RESOURCE_BARRIER::Transition(dest,
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_COPY_DEST)
};
m_cmdList->ResourceBarrier(2, copySetup);
m_cmdList->CopyResource(dest, src);
D3D12_RESOURCE_BARRIER copyTeardown[] =
{
CD3DX12_RESOURCE_BARRIER::Transition(src,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET),
CD3DX12_RESOURCE_BARRIER::Transition(dest,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PRESENT)
};
m_cmdList->ResourceBarrier(2, copyTeardown);
}
m_doPresent = true;
} }
UINT64 m_submittedFenceVal = 0;
void execute() void execute()
{ {
m_completeBuf = m_fillBuf; /* Check on fence */
for (size_t i=0 ; i<3 ; ++i) if (m_ctx->m_frameFence->GetCompletedValue() < m_submittedFenceVal)
{ {
if (i == m_completeBuf || i == m_drawBuf) resetCommandList();
continue; return;
m_fillBuf = i;
break;
} }
m_drawBuf = m_fillBuf;
++m_fillBuf;
if (m_fillBuf == 2)
m_fillBuf = 0;
m_cmdList->Close();
ID3D12CommandList* cl[] = {m_cmdList.Get()};
m_ctx->m_q->ExecuteCommandLists(1, cl);
if (m_doPresent)
{
ThrowIfFailed(m_windowCtx->m_swapChain->Present(1, 0));
m_windowCtx->m_backBuf = m_windowCtx->m_swapChain->GetCurrentBackBufferIndex();
}
++m_submittedFenceVal;
ThrowIfFailed(m_ctx->m_q->Signal(m_ctx->m_frameFence.Get(), m_submittedFenceVal));
resetCommandList();
} }
}; };
@ -799,27 +887,57 @@ D3D12DataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
return retval; return retval;
} }
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);
}
void* D3D12TextureD::map(size_t sz)
{
ID3D12Resource* res = m_texs[m_q->m_fillBuf].Get();
void* d;
res->Map(0, nullptr, &d);
return d;
}
void D3D12TextureD::unmap()
{
ID3D12Resource* res = m_texs[m_q->m_fillBuf].Get();
res->Unmap(0, nullptr);
}
ITextureD* ITextureD*
D3D12DataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt) D3D12DataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
{ {
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue()); D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
D3D12TextureD* retval = new D3D12TextureD(q, width, height, fmt); D3D12TextureD* retval = new D3D12TextureD(q, m_ctx, width, height, fmt);
static_cast<D3D12Data*>(m_deferredData)->m_DTexs.emplace_back(retval); static_cast<D3D12Data*>(m_deferredData)->m_DTexs.emplace_back(retval);
return retval; return retval;
} }
ITextureR*
D3D12DataFactory::newRenderTexture(size_t width, size_t height, size_t samples)
{
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
D3D12TextureR* retval = new D3D12TextureR(m_ctx, width, height, samples);
static_cast<D3D12Data*>(m_deferredData)->m_RTexs.emplace_back(retval);
return retval;
}
IVertexFormat* D3D12DataFactory::newVertexFormat IVertexFormat* D3D12DataFactory::newVertexFormat
(size_t elementCount, const VertexElementDescriptor* elements) (size_t elementCount, const VertexElementDescriptor* elements)
{ {
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue()); D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
D3D12VertexFormat* retval = new struct D3D12VertexFormat(q, elementCount, elements); D3D12VertexFormat* retval = new struct D3D12VertexFormat(elementCount, elements);
static_cast<D3D12Data*>(m_deferredData)->m_VFmts.emplace_back(retval); static_cast<D3D12Data*>(m_deferredData)->m_VFmts.emplace_back(retval);
return retval; return retval;
} }
IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, IGraphicsContext* parent) IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent)
{ {
return new struct D3D12CommandQueue(ctx, parent); return new struct D3D12CommandQueue(ctx, windowCtx, parent);
} }
} }

View File

@ -4,10 +4,8 @@
#include <Usbiodef.h> #include <Usbiodef.h>
#if _DEBUG #if _DEBUG
#define DXGI_FACTORY2_FLAGS DXGI_CREATE_FACTORY_DEBUG
#define D3D11_CREATE_DEVICE_FLAGS D3D11_CREATE_DEVICE_DEBUG #define D3D11_CREATE_DEVICE_FLAGS D3D11_CREATE_DEVICE_DEBUG
#else #else
#define DXGI_FACTORY2_FLAGS 0
#define D3D11_CREATE_DEVICE_FLAGS 0 #define D3D11_CREATE_DEVICE_FLAGS 0
#endif #endif
@ -65,19 +63,27 @@ public:
if (!MyCreateDXGIFactory2) if (!MyCreateDXGIFactory2)
Log.report(LogVisor::FatalError, "unable to find CreateDXGIFactory2 in DXGI.dll\n" Log.report(LogVisor::FatalError, "unable to find CreateDXGIFactory2 in DXGI.dll\n"
"Windows 7 users should install \"Platform Update for Windows 7\" from Microsoft"); "Windows 7 users should install \"Platform Update for Windows 7\" from Microsoft");
if (FAILED(MyCreateDXGIFactory2(DXGI_FACTORY2_FLAGS, __uuidof(IDXGIFactory2), &m_d3dCtx.m_dxFactory)))
Log.report(LogVisor::FatalError, "unable to create DXGI factory");
#if WINVER >= _WIN32_WINNT_WIN10 #if WINVER >= _WIN32_WINNT_WIN10
HMODULE d3d12lib = LoadLibraryW(L"D3D12.dll"); HMODULE d3d12lib = LoadLibraryW(L"D3D12.dll");
if (d3d12lib) if (d3d12lib)
{ {
/* Create device */
PFN_D3D12_CREATE_DEVICE MyD3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(d3d12lib, "D3D12CreateDevice"); PFN_D3D12_CREATE_DEVICE MyD3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(d3d12lib, "D3D12CreateDevice");
if (!MyD3D12CreateDevice) if (!MyD3D12CreateDevice)
Log.report(LogVisor::FatalError, "unable to find D3D12CreateDevice in D3D12.dll"); Log.report(LogVisor::FatalError, "unable to find D3D12CreateDevice in D3D12.dll");
/* Create device */
if (FAILED(MyD3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_12_0, __uuidof(ID3D12Device), &m_d3dCtx.m_ctx12.m_dev))) if (FAILED(MyD3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_12_0, __uuidof(ID3D12Device), &m_d3dCtx.m_ctx12.m_dev)))
Log.report(LogVisor::FatalError, "unable to create D3D12 device"); Log.report(LogVisor::FatalError, "unable to create D3D12 device");
/* Obtain DXGI Factory */
ComPtr<IDXGIDevice2> device;
ComPtr<IDXGIAdapter> adapter;
m_d3dCtx.m_ctx12.m_dev.As<IDXGIDevice2>(&device);
device->GetParent(__uuidof(IDXGIAdapter), &adapter);
adapter->GetParent(__uuidof(IDXGIFactory2), &m_d3dCtx.m_dxFactory);
return; return;
} }
#endif #endif
@ -99,6 +105,13 @@ public:
tempDev.As<ID3D11Device1>(&m_d3dCtx.m_ctx11.m_dev); tempDev.As<ID3D11Device1>(&m_d3dCtx.m_ctx11.m_dev);
tempCtx.As<ID3D11DeviceContext1>(&m_d3dCtx.m_ctx11.m_devCtx); tempCtx.As<ID3D11DeviceContext1>(&m_d3dCtx.m_ctx11.m_devCtx);
/* Obtain DXGI Factory */
ComPtr<IDXGIDevice2> device;
ComPtr<IDXGIAdapter> adapter;
m_d3dCtx.m_ctx11.m_dev.As<IDXGIDevice2>(&device);
device->GetParent(__uuidof(IDXGIAdapter), &adapter);
adapter->GetParent(__uuidof(IDXGIFactory2), &m_d3dCtx.m_dxFactory);
return; return;
} }

View File

@ -8,6 +8,9 @@
#define WIN32_LEAN_AND_MEAN 1 #define WIN32_LEAN_AND_MEAN 1
#endif #endif
#include <windows.h> #include <windows.h>
#include <unordered_map>
namespace boo {class IWindow;}
#if _WIN32_WINNT_WIN10 #if _WIN32_WINNT_WIN10
#include <dxgi1_4.h> #include <dxgi1_4.h>
@ -17,12 +20,20 @@
struct D3D12Context struct D3D12Context
{ {
ComPtr<ID3D12Device> m_dev; ComPtr<ID3D12Device> m_dev;
ComPtr<ID3D12CommandAllocator> m_qalloc; ComPtr<ID3D12CommandAllocator> m_qalloc[2];
ComPtr<ID3D12CommandQueue> m_q; ComPtr<ID3D12CommandQueue> m_q;
ComPtr<ID3D12CommandAllocator> m_loadqalloc; ComPtr<ID3D12CommandAllocator> m_loadqalloc;
ComPtr<ID3D12CommandQueue> m_loadq; ComPtr<ID3D12CommandQueue> m_loadq;
ComPtr<ID3D12Fence> m_frameFence; ComPtr<ID3D12Fence> m_frameFence;
ComPtr<ID3D12RootSignature> m_rs; ComPtr<ID3D12RootSignature> m_rs;
struct Window
{
ComPtr<IDXGISwapChain3> m_swapChain;
ComPtr<ID3D12Resource> m_fb[2]; /* Double-buffered */
UINT m_backBuf = 0;
size_t width, height;
};
std::unordered_map<boo::IWindow*, Window> m_windows;
}; };
#elif _WIN32_WINNT_WIN7 #elif _WIN32_WINNT_WIN7
@ -36,6 +47,12 @@ struct D3D11Context
{ {
ComPtr<ID3D11Device1> m_dev; ComPtr<ID3D11Device1> m_dev;
ComPtr<ID3D11DeviceContext1> m_devCtx; ComPtr<ID3D11DeviceContext1> m_devCtx;
struct Window
{
IDXGISwapChain1* m_swapChain;
size_t width, height;
};
std::unordered_map<boo::IWindow*, Window> m_windows;
}; };
#include "boo/System.hpp" #include "boo/System.hpp"

View File

@ -11,8 +11,8 @@ namespace boo
{ {
static LogVisor::LogModule Log("WindowWin32"); static LogVisor::LogModule Log("WindowWin32");
class WindowWin32; class WindowWin32;
IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, IGraphicsContext* parent); IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent);
IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, IGraphicsContext* parent); IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent);
struct GraphicsContextWin32 : IGraphicsContext struct GraphicsContextWin32 : IGraphicsContext
{ {
@ -47,9 +47,14 @@ public:
scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
#if _WIN32_WINNT_WIN10 #if _WIN32_WINNT_WIN10
IUnknown* dev = d3dCtx.m_ctx12.m_dev ? IUnknown* dev;
static_cast<IUnknown*>(d3dCtx.m_ctx12.m_dev.Get()) : if (d3dCtx.m_ctx12.m_dev)
static_cast<IUnknown*>(d3dCtx.m_ctx11.m_dev.Get()); {
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
dev = static_cast<IUnknown*>(d3dCtx.m_ctx12.m_dev.Get());
}
else
dev = static_cast<IUnknown*>(d3dCtx.m_ctx11.m_dev.Get());
#else #else
IUnknown* dev = static_cast<IUnknown*>(d3dCtx.m_ctx11.m_dev.Get()); IUnknown* dev = static_cast<IUnknown*>(d3dCtx.m_ctx11.m_dev.Get());
#endif #endif
@ -63,20 +68,45 @@ public:
#if _WIN32_WINNT_WIN10 #if _WIN32_WINNT_WIN10
if (d3dCtx.m_ctx12.m_dev) if (d3dCtx.m_ctx12.m_dev)
{ {
auto insIt = d3dCtx.m_ctx12.m_windows.emplace(std::make_pair(parentWindow, D3D12Context::Window()));
D3D12Context::Window& w = insIt.first->second;
m_swapChain.As<IDXGISwapChain3>(&w.m_swapChain);
m_swapChain->GetBuffer(0, __uuidof(ID3D12Resource), &w.m_fb[0]);
m_swapChain->GetBuffer(1, __uuidof(ID3D12Resource), &w.m_fb[1]);
w.m_backBuf = w.m_swapChain->GetCurrentBackBufferIndex();
D3D12_RESOURCE_DESC resDesc = w.m_fb[0]->GetDesc();
w.width = resDesc.Width;
w.height = resDesc.Height;
m_dataFactory = new D3D12DataFactory(this, &d3dCtx.m_ctx12); m_dataFactory = new D3D12DataFactory(this, &d3dCtx.m_ctx12);
m_commandQueue = _NewD3D12CommandQueue(&d3dCtx.m_ctx12, this); m_commandQueue = _NewD3D12CommandQueue(&d3dCtx.m_ctx12, &w, this);
} }
else else
#endif #endif
{ {
auto insIt = d3dCtx.m_ctx11.m_windows.emplace(std::make_pair(parentWindow, D3D11Context::Window()));
D3D11Context::Window& w = insIt.first->second;
ComPtr<ID3D11Texture2D> fbRes;
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &fbRes);
D3D11_TEXTURE2D_DESC resDesc;
fbRes->GetDesc(&resDesc);
w.width = resDesc.Width;
w.height = resDesc.Height;
m_dataFactory = new D3D11DataFactory(this, &d3dCtx.m_ctx11); m_dataFactory = new D3D11DataFactory(this, &d3dCtx.m_ctx11);
m_commandQueue = _NewD3D11CommandQueue(&d3dCtx.m_ctx11, this); m_commandQueue = _NewD3D11CommandQueue(&d3dCtx.m_ctx11, &insIt.first->second, this);
} }
} }
~GraphicsContextWin32() ~GraphicsContextWin32()
{ {
#if _WIN32_WINNT_WIN10
if (m_d3dCtx.m_ctx12.m_dev)
{
m_d3dCtx.m_ctx12.m_windows.erase(m_parentWindow);
}
else
#endif
{
}
} }
void _setCallback(IWindowCallback* cb) void _setCallback(IWindowCallback* cb)