Windows sync

This commit is contained in:
Jack Andersen 2017-03-17 13:31:51 -10:00
parent 05c26a535b
commit 5f903c09ee
5 changed files with 620 additions and 366 deletions

View File

@ -122,7 +122,7 @@ public:
TextureFormat fmt, const void* data, size_t sz); TextureFormat fmt, 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, ITextureR* newRenderTexture(size_t width, size_t height,
bool enableShaderColorBinding, bool enableShaderDepthBinding); size_t colorBindCount, size_t depthBindCount);
bool bindingNeedsVertexFormat() const {return false;} bool bindingNeedsVertexFormat() const {return false;}
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements, IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
@ -132,7 +132,8 @@ public:
std::vector<unsigned int>* vertBlobOut, std::vector<unsigned int>* fragBlobOut, std::vector<unsigned int>* vertBlobOut, std::vector<unsigned int>* fragBlobOut,
std::vector<unsigned char>* pipelineBlob, IVertexFormat* vtxFmt, std::vector<unsigned char>* pipelineBlob, IVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, CullMode culling); ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling);
IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, IVertexFormat* vtxFmt, IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, IVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
@ -140,7 +141,8 @@ public:
bool alphaWrite, CullMode culling) bool alphaWrite, CullMode culling)
{ {
return newShaderPipeline(vertSource, fragSource, nullptr, nullptr, nullptr, return newShaderPipeline(vertSource, fragSource, nullptr, nullptr, nullptr,
vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite, culling); vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite,
colorWrite, alphaWrite, culling);
} }
IShaderDataBinding* IShaderDataBinding*
@ -150,6 +152,7 @@ public:
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages, size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
const size_t* ubufOffs, const size_t* ubufSizes, const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, ITexture** texs, size_t texCount, ITexture** texs,
const int* bindIdxs, const bool* bindDepth,
size_t baseVert = 0, size_t baseInst = 0); size_t baseVert = 0, size_t baseInst = 0);
}; };
}; };

View File

@ -47,7 +47,7 @@ static inline void ThrowIfFailed(HRESULT hr)
} }
} }
struct D3D11Data : IGraphicsDataPriv<D3D11Data> struct D3D11Data : IGraphicsDataPriv
{ {
std::vector<std::unique_ptr<class D3D11ShaderPipeline>> m_SPs; std::vector<std::unique_ptr<class D3D11ShaderPipeline>> m_SPs;
std::vector<std::unique_ptr<struct D3D11ShaderDataBinding>> m_SBinds; std::vector<std::unique_ptr<struct D3D11ShaderDataBinding>> m_SBinds;
@ -60,10 +60,19 @@ struct D3D11Data : IGraphicsDataPriv<D3D11Data>
std::vector<std::unique_ptr<struct D3D11VertexFormat>> m_VFmts; std::vector<std::unique_ptr<struct D3D11VertexFormat>> m_VFmts;
}; };
class D3D11GraphicsBufferD; struct D3D11PoolItem : IGraphicsDataPriv
{
std::unique_ptr<class D3D11GraphicsBufferD> m_buf;
};
struct D3D11Pool : IGraphicsBufferPool struct D3D11Pool : IGraphicsBufferPool
{ {
std::unordered_map<D3D11GraphicsBufferD*, std::unique_ptr<D3D11GraphicsBufferD>> m_DBufs; std::unordered_set<D3D11PoolItem*> m_items;
~D3D11Pool()
{
for (auto& item : m_items)
item->decrement();
}
}; };
static const D3D11_BIND_FLAG USE_TABLE[] = static const D3D11_BIND_FLAG USE_TABLE[] =
@ -80,8 +89,9 @@ class D3D11GraphicsBufferS : public IGraphicsBufferS
friend struct D3D11CommandQueue; friend struct D3D11CommandQueue;
size_t m_sz; size_t m_sz;
D3D11GraphicsBufferS(BufferUse use, D3D11Context* ctx, const void* data, size_t stride, size_t count) D3D11GraphicsBufferS(IGraphicsData* parent, BufferUse use, D3D11Context* ctx,
: m_stride(stride), m_count(count), m_sz(stride * count) const void* data, size_t stride, size_t count)
: IGraphicsBufferS(parent), m_stride(stride), m_count(count), m_sz(stride * count)
{ {
D3D11_SUBRESOURCE_DATA iData = {data}; D3D11_SUBRESOURCE_DATA iData = {data};
ThrowIfFailed(ctx->m_dev->CreateBuffer(&CD3D11_BUFFER_DESC(m_sz, USE_TABLE[int(use)], D3D11_USAGE_IMMUTABLE), &iData, &m_buf)); ThrowIfFailed(ctx->m_dev->CreateBuffer(&CD3D11_BUFFER_DESC(m_sz, USE_TABLE[int(use)], D3D11_USAGE_IMMUTABLE), &iData, &m_buf));
@ -102,8 +112,9 @@ class D3D11GraphicsBufferD : public IGraphicsBufferD
std::unique_ptr<uint8_t[]> m_cpuBuf; std::unique_ptr<uint8_t[]> m_cpuBuf;
size_t m_cpuSz; size_t m_cpuSz;
int m_validSlots = 0; int m_validSlots = 0;
D3D11GraphicsBufferD(D3D11CommandQueue* q, BufferUse use, D3D11Context* ctx, size_t stride, size_t count) D3D11GraphicsBufferD(IGraphicsData* parent, D3D11CommandQueue* q, BufferUse use,
: m_q(q), m_stride(stride), m_count(count) D3D11Context* ctx, size_t stride, size_t count)
: IGraphicsBufferD(parent), m_q(q), m_stride(stride), m_count(count)
{ {
m_cpuSz = stride * count; m_cpuSz = stride * count;
m_cpuBuf.reset(new uint8_t[m_cpuSz]); m_cpuBuf.reset(new uint8_t[m_cpuSz]);
@ -128,9 +139,9 @@ class D3D11TextureS : public ITextureS
friend class D3D11DataFactory; friend class D3D11DataFactory;
size_t m_sz; size_t m_sz;
D3D11TextureS(D3D11Context* ctx, size_t width, size_t height, size_t mips, D3D11TextureS(IGraphicsData* parent, D3D11Context* ctx, size_t width, size_t height, size_t mips,
TextureFormat fmt, const void* data, size_t sz) TextureFormat fmt, const void* data, size_t sz)
: m_sz(sz) : ITextureS(parent), m_sz(sz)
{ {
DXGI_FORMAT pfmt; DXGI_FORMAT pfmt;
int pxPitchNum = 1; int pxPitchNum = 1;
@ -187,9 +198,9 @@ class D3D11TextureSA : public ITextureSA
friend class D3D11DataFactory; friend class D3D11DataFactory;
size_t m_sz; size_t m_sz;
D3D11TextureSA(D3D11Context* ctx, size_t width, size_t height, size_t layers, D3D11TextureSA(IGraphicsData* parent, D3D11Context* ctx, size_t width, size_t height, size_t layers,
size_t mips, TextureFormat fmt, const void* data, size_t sz) size_t mips, TextureFormat fmt, const void* data, size_t sz)
: m_sz(sz) : ITextureSA(parent), m_sz(sz)
{ {
size_t pixelPitch; size_t pixelPitch;
DXGI_FORMAT pixelFmt; DXGI_FORMAT pixelFmt;
@ -248,8 +259,9 @@ class D3D11TextureD : public ITextureD
size_t m_cpuSz; size_t m_cpuSz;
size_t m_pxPitch; size_t m_pxPitch;
int m_validSlots = 0; int m_validSlots = 0;
D3D11TextureD(D3D11CommandQueue* q, D3D11Context* ctx, size_t width, size_t height, TextureFormat fmt) D3D11TextureD(IGraphicsData* parent, D3D11CommandQueue* q, D3D11Context* ctx,
: m_width(width), m_height(height), m_q(q) size_t width, size_t height, TextureFormat fmt)
: ITextureD(parent), m_width(width), m_height(height), m_q(q)
{ {
DXGI_FORMAT pixelFmt; DXGI_FORMAT pixelFmt;
switch (fmt) switch (fmt)
@ -289,6 +301,8 @@ public:
void unmap(); void unmap();
}; };
#define MAX_BIND_TEXS 4
class D3D11TextureR : public ITextureR class D3D11TextureR : public ITextureR
{ {
friend class D3D11DataFactory; friend class D3D11DataFactory;
@ -297,11 +311,11 @@ class D3D11TextureR : public ITextureR
size_t m_width = 0; size_t m_width = 0;
size_t m_height = 0; size_t m_height = 0;
size_t m_samples = 0; size_t m_samples = 0;
bool m_enableShaderColorBind; size_t m_colorBindCount;
bool m_enableShaderDepthBind; size_t m_depthBindCount;
void Setup(D3D11Context* ctx, size_t width, size_t height, size_t samples, void Setup(D3D11Context* ctx, size_t width, size_t height, size_t samples,
bool enableShaderColorBind, bool enableShaderDepthBind) size_t colorBindCount, size_t depthBindCount)
{ {
ThrowIfFailed(ctx->m_dev->CreateTexture2D(&CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, ThrowIfFailed(ctx->m_dev->CreateTexture2D(&CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, width, height,
1, 1, D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, samples), nullptr, &m_colorTex)); 1, 1, D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, 0, samples), nullptr, &m_colorTex));
@ -330,30 +344,35 @@ class D3D11TextureR : public ITextureR
ThrowIfFailed(ctx->m_dev->CreateDepthStencilView(m_depthTex.Get(), ThrowIfFailed(ctx->m_dev->CreateDepthStencilView(m_depthTex.Get(),
&CD3D11_DEPTH_STENCIL_VIEW_DESC(m_depthTex.Get(), dsvDim), &m_dsv)); &CD3D11_DEPTH_STENCIL_VIEW_DESC(m_depthTex.Get(), dsvDim), &m_dsv));
if (enableShaderColorBind) for (size_t i=0 ; i<colorBindCount ; ++i)
{ {
ThrowIfFailed(ctx->m_dev->CreateTexture2D(&CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, ThrowIfFailed(ctx->m_dev->CreateTexture2D(&CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, width, height,
1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, samples), nullptr, &m_colorBindTex)); 1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, samples), nullptr, &m_colorBindTex[i]));
ThrowIfFailed(ctx->m_dev->CreateShaderResourceView(m_colorBindTex.Get(), ThrowIfFailed(ctx->m_dev->CreateShaderResourceView(m_colorBindTex[i].Get(),
&CD3D11_SHADER_RESOURCE_VIEW_DESC(m_colorBindTex.Get(), srvDim), &m_colorSrv)); &CD3D11_SHADER_RESOURCE_VIEW_DESC(m_colorBindTex[i].Get(), srvDim), &m_colorSrv[i]));
} }
if (enableShaderDepthBind) for (size_t i=0 ; i<depthBindCount ; ++i)
{ {
ThrowIfFailed(ctx->m_dev->CreateTexture2D(&CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, width, height, ThrowIfFailed(ctx->m_dev->CreateTexture2D(&CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, width, height,
1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, samples), nullptr, &m_depthBindTex)); 1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, samples), nullptr, &m_depthBindTex[i]));
ThrowIfFailed(ctx->m_dev->CreateShaderResourceView(m_depthBindTex.Get(), ThrowIfFailed(ctx->m_dev->CreateShaderResourceView(m_depthBindTex[i].Get(),
&CD3D11_SHADER_RESOURCE_VIEW_DESC(m_depthBindTex.Get(), srvDim, DXGI_FORMAT_R24G8_TYPELESS), &m_depthSrv)); &CD3D11_SHADER_RESOURCE_VIEW_DESC(m_depthBindTex[i].Get(), srvDim, DXGI_FORMAT_R24_UNORM_X8_TYPELESS), &m_depthSrv[i]));
} }
} }
D3D11TextureR(D3D11Context* ctx, size_t width, size_t height, size_t samples, D3D11TextureR(IGraphicsData* parent, D3D11Context* ctx, size_t width, size_t height, size_t samples,
bool enableShaderColorBind, bool enableShaderDepthBind) size_t colorBindCount, size_t depthBindCount)
: m_width(width), m_height(height), m_samples(samples), : ITextureR(parent), m_width(width), m_height(height), m_samples(samples),
m_enableShaderColorBind(enableShaderColorBind), m_enableShaderDepthBind(enableShaderDepthBind) m_colorBindCount(colorBindCount), m_depthBindCount(depthBindCount)
{ {
if (colorBindCount > MAX_BIND_TEXS)
Log.report(logvisor::Fatal, "too many color bindings for render texture");
if (depthBindCount > MAX_BIND_TEXS)
Log.report(logvisor::Fatal, "too many depth bindings for render texture");
if (samples == 0) m_samples = 1; if (samples == 0) m_samples = 1;
Setup(ctx, width, height, samples, enableShaderColorBind, enableShaderDepthBind); Setup(ctx, width, height, samples, colorBindCount, depthBindCount);
} }
public: public:
size_t samples() const {return m_samples;} size_t samples() const {return m_samples;}
@ -363,11 +382,11 @@ public:
ComPtr<ID3D11Texture2D> m_depthTex; ComPtr<ID3D11Texture2D> m_depthTex;
ComPtr<ID3D11DepthStencilView> m_dsv; ComPtr<ID3D11DepthStencilView> m_dsv;
ComPtr<ID3D11Texture2D> m_colorBindTex; ComPtr<ID3D11Texture2D> m_colorBindTex[MAX_BIND_TEXS];
ComPtr<ID3D11ShaderResourceView> m_colorSrv; ComPtr<ID3D11ShaderResourceView> m_colorSrv[MAX_BIND_TEXS];
ComPtr<ID3D11Texture2D> m_depthBindTex; ComPtr<ID3D11Texture2D> m_depthBindTex[MAX_BIND_TEXS];
ComPtr<ID3D11ShaderResourceView> m_depthSrv; ComPtr<ID3D11ShaderResourceView> m_depthSrv[MAX_BIND_TEXS];
~D3D11TextureR() = default; ~D3D11TextureR() = default;
@ -379,7 +398,7 @@ public:
height = 1; height = 1;
m_width = width; m_width = width;
m_height = height; m_height = height;
Setup(ctx, width, height, m_samples, m_enableShaderColorBind, m_enableShaderDepthBind); Setup(ctx, width, height, m_samples, m_colorBindCount, m_depthBindCount);
} }
}; };
@ -435,9 +454,9 @@ struct D3D11VertexFormat : IVertexFormat
size_t m_stride = 0; size_t m_stride = 0;
size_t m_instStride = 0; size_t m_instStride = 0;
D3D11VertexFormat(size_t elementCount, const VertexElementDescriptor* elements) D3D11VertexFormat(IGraphicsData* parent, size_t elementCount, const VertexElementDescriptor* elements)
: m_elementCount(elementCount), : IVertexFormat(parent), m_elementCount(elementCount),
m_elements(new D3D11_INPUT_ELEMENT_DESC[elementCount]) m_elements(new D3D11_INPUT_ELEMENT_DESC[elementCount])
{ {
memset(m_elements.get(), 0, elementCount * sizeof(D3D11_INPUT_ELEMENT_DESC)); memset(m_elements.get(), 0, elementCount * sizeof(D3D11_INPUT_ELEMENT_DESC));
for (size_t i=0 ; i<elementCount ; ++i) for (size_t i=0 ; i<elementCount ; ++i)
@ -496,13 +515,15 @@ class D3D11ShaderPipeline : public IShaderPipeline
D3D11ShareableShader::Token m_vert; D3D11ShareableShader::Token m_vert;
D3D11ShareableShader::Token m_pixel; D3D11ShareableShader::Token m_pixel;
D3D11ShaderPipeline(D3D11Context* ctx, D3D11ShaderPipeline(IGraphicsData* parent, D3D11Context* ctx,
D3D11ShareableShader::Token&& vert, D3D11ShareableShader::Token&& vert,
D3D11ShareableShader::Token&& pixel, D3D11ShareableShader::Token&& pixel,
const D3D11VertexFormat* vtxFmt, const D3D11VertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, CullMode culling) ZTest depthTest, bool depthWrite, bool colorWrite,
: m_vtxFmt(vtxFmt), m_vert(std::move(vert)), m_pixel(std::move(pixel)), bool alphaWrite, CullMode culling)
: IShaderPipeline(parent), m_vtxFmt(vtxFmt),
m_vert(std::move(vert)), m_pixel(std::move(pixel)),
m_topology(PRIMITIVE_TABLE[int(prim)]) m_topology(PRIMITIVE_TABLE[int(prim)])
{ {
m_vert.get().m_shader.As<ID3D11VertexShader>(&m_vShader); m_vert.get().m_shader.As<ID3D11VertexShader>(&m_vShader);
@ -529,9 +550,24 @@ class D3D11ShaderPipeline : public IShaderPipeline
ThrowIfFailed(ctx->m_dev->CreateRasterizerState(&rasDesc, &m_rasState)); ThrowIfFailed(ctx->m_dev->CreateRasterizerState(&rasDesc, &m_rasState));
CD3D11_DEPTH_STENCIL_DESC dsDesc(D3D11_DEFAULT); CD3D11_DEPTH_STENCIL_DESC dsDesc(D3D11_DEFAULT);
dsDesc.DepthEnable = depthTest; dsDesc.DepthEnable = depthTest != ZTest::None;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK(depthWrite); dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK(depthWrite);
dsDesc.DepthFunc = D3D11_COMPARISON_GREATER_EQUAL; switch (depthTest)
{
case ZTest::None:
default:
dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
break;
case ZTest::LEqual:
dsDesc.DepthFunc = D3D11_COMPARISON_GREATER_EQUAL;
break;
case ZTest::Greater:
dsDesc.DepthFunc = D3D11_COMPARISON_LESS;
break;
case ZTest::Equal:
dsDesc.DepthFunc = D3D11_COMPARISON_EQUAL;
break;
}
ThrowIfFailed(ctx->m_dev->CreateDepthStencilState(&dsDesc, &m_dsState)); ThrowIfFailed(ctx->m_dev->CreateDepthStencilState(&dsDesc, &m_dsState));
CD3D11_BLEND_DESC blDesc(D3D11_DEFAULT); CD3D11_BLEND_DESC blDesc(D3D11_DEFAULT);
@ -540,6 +576,11 @@ class D3D11ShaderPipeline : public IShaderPipeline
blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)]; blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blDesc.RenderTarget[0].RenderTargetWriteMask =
(colorWrite ? (D3D11_COLOR_WRITE_ENABLE_RED |
D3D11_COLOR_WRITE_ENABLE_GREEN |
D3D11_COLOR_WRITE_ENABLE_BLUE) : 0) |
(alphaWrite ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0);
ThrowIfFailed(ctx->m_dev->CreateBlendState(&blDesc, &m_blState)); ThrowIfFailed(ctx->m_dev->CreateBlendState(&blDesc, &m_blState));
const auto& vertBuf = m_vert.get().m_vtxBlob; const auto& vertBuf = m_vert.get().m_vtxBlob;
@ -570,7 +611,7 @@ public:
} }
}; };
struct D3D11ShaderDataBinding : IShaderDataBindingPriv<D3D11Data> struct D3D11ShaderDataBinding : IShaderDataBindingPriv
{ {
D3D11ShaderPipeline* m_pipeline; D3D11ShaderPipeline* m_pipeline;
IGraphicsBuffer* m_vbuf; IGraphicsBuffer* m_vbuf;
@ -580,7 +621,13 @@ struct D3D11ShaderDataBinding : IShaderDataBindingPriv<D3D11Data>
std::unique_ptr<UINT[]> m_ubufFirstConsts; std::unique_ptr<UINT[]> m_ubufFirstConsts;
std::unique_ptr<UINT[]> m_ubufNumConsts; std::unique_ptr<UINT[]> m_ubufNumConsts;
std::unique_ptr<bool[]> m_pubufs; std::unique_ptr<bool[]> m_pubufs;
std::vector<ITexture*> m_texs; struct BoundTex
{
ITexture* tex;
int idx;
bool depth;
};
std::vector<BoundTex> m_texs;
UINT m_baseOffsets[2]; UINT m_baseOffsets[2];
D3D11ShaderDataBinding(D3D11Data* d, D3D11ShaderDataBinding(D3D11Data* d,
@ -589,7 +636,8 @@ struct D3D11ShaderDataBinding : IShaderDataBindingPriv<D3D11Data>
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbuf, IGraphicsBuffer* ibuf, IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbuf, IGraphicsBuffer* ibuf,
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages, size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
const size_t* ubufOffs, const size_t* ubufSizes, const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, ITexture** texs, size_t baseVert, size_t baseInst) size_t texCount, ITexture** texs, const int* texBindIdx, const bool* depthBind,
size_t baseVert, size_t baseInst)
: IShaderDataBindingPriv(d), : IShaderDataBindingPriv(d),
m_pipeline(static_cast<D3D11ShaderPipeline*>(pipeline)), m_pipeline(static_cast<D3D11ShaderPipeline*>(pipeline)),
m_vbuf(vbuf), m_vbuf(vbuf),
@ -632,7 +680,7 @@ struct D3D11ShaderDataBinding : IShaderDataBindingPriv<D3D11Data>
} }
for (size_t i=0 ; i<texCount ; ++i) for (size_t i=0 ; i<texCount ; ++i)
{ {
m_texs.push_back(texs[i]); m_texs.push_back({texs[i], texBindIdx ? texBindIdx[i] : 0, depthBind ? depthBind[i] : false});
} }
} }
@ -784,32 +832,33 @@ struct D3D11ShaderDataBinding : IShaderDataBindingPriv<D3D11Data>
ID3D11ShaderResourceView* srvs[8] = {}; ID3D11ShaderResourceView* srvs[8] = {};
for (int i=0 ; i<8 && i<m_texs.size() ; ++i) for (int i=0 ; i<8 && i<m_texs.size() ; ++i)
{ {
if (m_texs[i]) if (m_texs[i].tex)
{ {
switch (m_texs[i]->type()) switch (m_texs[i].tex->type())
{ {
case TextureType::Dynamic: case TextureType::Dynamic:
{ {
D3D11TextureD* ctex = static_cast<D3D11TextureD*>(m_texs[i]); D3D11TextureD* ctex = static_cast<D3D11TextureD*>(m_texs[i].tex);
srvs[i] = ctex->m_srvs[b].Get(); srvs[i] = ctex->m_srvs[b].Get();
break; break;
} }
case TextureType::Static: case TextureType::Static:
{ {
D3D11TextureS* ctex = static_cast<D3D11TextureS*>(m_texs[i]); D3D11TextureS* ctex = static_cast<D3D11TextureS*>(m_texs[i].tex);
srvs[i] = ctex->m_srv.Get(); srvs[i] = ctex->m_srv.Get();
break; break;
} }
case TextureType::StaticArray: case TextureType::StaticArray:
{ {
D3D11TextureSA* ctex = static_cast<D3D11TextureSA*>(m_texs[i]); D3D11TextureSA* ctex = static_cast<D3D11TextureSA*>(m_texs[i].tex);
srvs[i] = ctex->m_srv.Get(); srvs[i] = ctex->m_srv.Get();
break; break;
} }
case TextureType::Render: case TextureType::Render:
{ {
D3D11TextureR* ctex = static_cast<D3D11TextureR*>(m_texs[i]); D3D11TextureR* ctex = static_cast<D3D11TextureR*>(m_texs[i].tex);
srvs[i] = ctex->m_colorSrv.Get(); srvs[i] = m_texs[i].depth ? ctex->m_depthSrv[m_texs[i].idx].Get() :
ctex->m_colorSrv[m_texs[i].idx].Get();
break; break;
} }
} }
@ -844,7 +893,7 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
struct CommandList struct CommandList
{ {
ComPtr<ID3D11CommandList> list; ComPtr<ID3D11CommandList> list;
std::vector<IShaderDataBindingPriv<D3D11Data>::Token> resTokens; std::vector<IShaderDataBindingPriv::Token> resTokens;
D3D11TextureR* workDoPresent = nullptr; D3D11TextureR* workDoPresent = nullptr;
void reset() void reset()
@ -1049,14 +1098,14 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
m_deferredCtx->DrawIndexedInstanced(count, instCount, start, 0, 0); m_deferredCtx->DrawIndexedInstanced(count, instCount, start, 0, 0);
} }
void resolveBindTexture(ITextureR* texture, const SWindowRect& rect, bool tlOrigin, bool color, bool depth) void resolveBindTexture(ITextureR* texture, const SWindowRect& rect, bool tlOrigin, int bindIdx, bool color, bool depth)
{ {
const D3D11TextureR* tex = static_cast<const D3D11TextureR*>(texture); const D3D11TextureR* tex = static_cast<const D3D11TextureR*>(texture);
if (color && tex->m_enableShaderColorBind) if (color && tex->m_colorBindCount)
{ {
if (tex->m_samples > 1) if (tex->m_samples > 1)
{ {
m_deferredCtx->CopyResource(tex->m_colorBindTex.Get(), tex->m_colorTex.Get()); m_deferredCtx->CopyResource(tex->m_colorBindTex[bindIdx].Get(), tex->m_colorTex.Get());
} }
else else
{ {
@ -1064,13 +1113,13 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
int y = tlOrigin ? intersectRect.location[1] : (tex->m_height - intersectRect.size[1] - intersectRect.location[1]); int y = tlOrigin ? intersectRect.location[1] : (tex->m_height - intersectRect.size[1] - intersectRect.location[1]);
D3D11_BOX box = {UINT(intersectRect.location[0]), UINT(y), 0, D3D11_BOX box = {UINT(intersectRect.location[0]), UINT(y), 0,
UINT(intersectRect.location[0] + intersectRect.size[0]), UINT(y + intersectRect.size[1]), 1}; UINT(intersectRect.location[0] + intersectRect.size[0]), UINT(y + intersectRect.size[1]), 1};
m_deferredCtx->CopySubresourceRegion1(tex->m_colorBindTex.Get(), 0, box.left, box.top, 0, m_deferredCtx->CopySubresourceRegion1(tex->m_colorBindTex[bindIdx].Get(), 0, box.left, box.top, 0,
tex->m_colorTex.Get(), 0, &box, D3D11_COPY_DISCARD); tex->m_colorTex.Get(), 0, &box, D3D11_COPY_DISCARD);
} }
} }
if (depth && tex->m_enableShaderDepthBind) if (depth && tex->m_depthBindCount)
{ {
m_deferredCtx->CopyResource(tex->m_depthBindTex.Get(), tex->m_depthTex.Get()); m_deferredCtx->CopyResource(tex->m_depthBindTex[bindIdx].Get(), tex->m_depthTex.Get());
} }
} }
@ -1179,8 +1228,8 @@ class D3D11DataFactory : public ID3DDataFactory
std::unique_lock<std::mutex> lk(m_committedMutex); std::unique_lock<std::mutex> lk(m_committedMutex);
for (D3D11Data* data : m_committedData) for (D3D11Data* data : m_committedData)
data->decrement(); data->decrement();
for (IGraphicsBufferPool* pool : m_committedPools) for (D3D11Pool* pool : m_committedPools)
delete static_cast<D3D11Pool*>(pool); delete pool;
m_committedData.clear(); m_committedData.clear();
m_committedPools.clear(); m_committedPools.clear();
} }
@ -1198,15 +1247,22 @@ class D3D11DataFactory : public ID3DDataFactory
{ {
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue()); D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue());
D3D11Pool* pool = static_cast<D3D11Pool*>(p); D3D11Pool* pool = static_cast<D3D11Pool*>(p);
D3D11GraphicsBufferD* retval = new D3D11GraphicsBufferD(q, use, m_ctx, stride, count); D3D11PoolItem* item = new D3D11PoolItem;
pool->m_DBufs.emplace(std::make_pair(retval, retval)); D3D11GraphicsBufferD* retval = new D3D11GraphicsBufferD(item, q, use, m_ctx, stride, count);
item->m_buf.reset(retval);
pool->m_items.emplace(item);
return retval; return retval;
} }
void deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf) void deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf)
{ {
D3D11Pool* pool = static_cast<D3D11Pool*>(p); D3D11Pool* pool = static_cast<D3D11Pool*>(p);
pool->m_DBufs.erase(static_cast<D3D11GraphicsBufferD*>(buf)); auto search = pool->m_items.find(static_cast<D3D11PoolItem*>(buf->m_parentData));
if (search != pool->m_items.end())
{
(*search)->decrement();
pool->m_items.erase(search);
}
} }
public: public:
@ -1230,7 +1286,7 @@ public:
IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
{ {
D3D11Data* d = static_cast<D3D11Data*>(m_deferredData); D3D11Data* d = static_cast<D3D11Data*>(m_deferredData);
D3D11GraphicsBufferS* retval = new D3D11GraphicsBufferS(use, m_parent.m_ctx, data, stride, count); D3D11GraphicsBufferS* retval = new D3D11GraphicsBufferS(d, use, m_parent.m_ctx, data, stride, count);
d->m_SBufs.emplace_back(retval); d->m_SBufs.emplace_back(retval);
return retval; return retval;
} }
@ -1239,7 +1295,7 @@ public:
{ {
D3D11Data* d = static_cast<D3D11Data*>(m_deferredData); D3D11Data* d = static_cast<D3D11Data*>(m_deferredData);
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent.m_parent->getCommandQueue()); D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent.m_parent->getCommandQueue());
D3D11GraphicsBufferD* retval = new D3D11GraphicsBufferD(q, use, m_parent.m_ctx, stride, count); D3D11GraphicsBufferD* retval = new D3D11GraphicsBufferD(d, q, use, m_parent.m_ctx, stride, count);
d->m_DBufs.emplace_back(retval); d->m_DBufs.emplace_back(retval);
return retval; return retval;
} }
@ -1248,7 +1304,7 @@ public:
const void* data, size_t sz) const void* data, size_t sz)
{ {
D3D11Data* d = static_cast<D3D11Data*>(m_deferredData); D3D11Data* d = static_cast<D3D11Data*>(m_deferredData);
D3D11TextureS* retval = new D3D11TextureS(m_parent.m_ctx, width, height, mips, fmt, data, sz); D3D11TextureS* retval = new D3D11TextureS(d, m_parent.m_ctx, width, height, mips, fmt, data, sz);
d->m_STexs.emplace_back(retval); d->m_STexs.emplace_back(retval);
return retval; return retval;
} }
@ -1257,7 +1313,7 @@ public:
TextureFormat fmt, const void* data, size_t sz) TextureFormat fmt, const void* data, size_t sz)
{ {
D3D11Data* d = static_cast<D3D11Data*>(m_deferredData); D3D11Data* d = static_cast<D3D11Data*>(m_deferredData);
D3D11TextureSA* retval = new D3D11TextureSA(m_parent.m_ctx, width, height, layers, mips, fmt, data, sz); D3D11TextureSA* retval = new D3D11TextureSA(d, m_parent.m_ctx, width, height, layers, mips, fmt, data, sz);
d->m_SATexs.emplace_back(retval); d->m_SATexs.emplace_back(retval);
return retval; return retval;
} }
@ -1266,17 +1322,17 @@ public:
{ {
D3D11Data* d = static_cast<D3D11Data*>(m_deferredData); D3D11Data* d = static_cast<D3D11Data*>(m_deferredData);
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent.m_parent->getCommandQueue()); D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent.m_parent->getCommandQueue());
D3D11TextureD* retval = new D3D11TextureD(q, m_parent.m_ctx, width, height, fmt); D3D11TextureD* retval = new D3D11TextureD(d, q, m_parent.m_ctx, width, height, fmt);
d->m_DTexs.emplace_back(retval); d->m_DTexs.emplace_back(retval);
return retval; return retval;
} }
ITextureR* newRenderTexture(size_t width, size_t height, ITextureR* newRenderTexture(size_t width, size_t height,
bool enableShaderColorBind, bool enableShaderDepthBind) size_t colorBindCount, size_t depthBindCount)
{ {
D3D11Data* d = static_cast<D3D11Data*>(m_deferredData); D3D11Data* d = static_cast<D3D11Data*>(m_deferredData);
D3D11TextureR* retval = new D3D11TextureR(m_parent.m_ctx, width, height, m_parent.m_sampleCount, D3D11TextureR* retval = new D3D11TextureR(d, m_parent.m_ctx, width, height, m_parent.m_sampleCount,
enableShaderColorBind, enableShaderDepthBind); colorBindCount, depthBindCount);
d->m_RTexs.emplace_back(retval); d->m_RTexs.emplace_back(retval);
return retval; return retval;
} }
@ -1285,8 +1341,7 @@ public:
size_t baseVert, size_t baseInst) size_t baseVert, size_t baseInst)
{ {
D3D11Data* d = static_cast<D3D11Data*>(m_deferredData); D3D11Data* d = static_cast<D3D11Data*>(m_deferredData);
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent.m_parent->getCommandQueue()); D3D11VertexFormat* retval = new struct D3D11VertexFormat(d, elementCount, elements);
D3D11VertexFormat* retval = new struct D3D11VertexFormat(elementCount, elements);
d->m_VFmts.emplace_back(retval); d->m_VFmts.emplace_back(retval);
return retval; return retval;
} }
@ -1338,7 +1393,8 @@ public:
ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut, ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut,
ComPtr<ID3DBlob>* pipelineBlob, IVertexFormat* vtxFmt, ComPtr<ID3DBlob>* pipelineBlob, IVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, CullMode culling) ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling)
{ {
XXH64_state_t hashState; XXH64_state_t hashState;
uint64_t srcHashes[2] = {}; uint64_t srcHashes[2] = {};
@ -1438,10 +1494,10 @@ public:
} }
D3D11Data* d = static_cast<D3D11Data*>(m_deferredData); D3D11Data* d = static_cast<D3D11Data*>(m_deferredData);
D3D11ShaderPipeline* retval = new D3D11ShaderPipeline(ctx, D3D11ShaderPipeline* retval = new D3D11ShaderPipeline(d, ctx,
std::move(vertShader), std::move(fragShader), std::move(vertShader), std::move(fragShader),
static_cast<const D3D11VertexFormat*>(vtxFmt), static_cast<const D3D11VertexFormat*>(vtxFmt),
srcFac, dstFac, prim, depthTest, depthWrite, culling); srcFac, dstFac, prim, depthTest, depthWrite, colorWrite, alphaWrite, culling);
d->m_SPs.emplace_back(retval); d->m_SPs.emplace_back(retval);
return retval; return retval;
} }
@ -1452,13 +1508,14 @@ public:
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages, size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
const size_t* ubufOffs, const size_t* ubufSizes, const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, ITexture** texs, size_t texCount, ITexture** texs,
const int* texBindIdx, const bool* depthBind,
size_t baseVert, size_t baseInst) size_t baseVert, size_t baseInst)
{ {
D3D11Data* d = static_cast<D3D11Data*>(m_deferredData); D3D11Data* d = static_cast<D3D11Data*>(m_deferredData);
D3D11ShaderDataBinding* retval = D3D11ShaderDataBinding* retval =
new D3D11ShaderDataBinding(d, m_parent.m_ctx, pipeline, vbuf, instVbo, ibuf, new D3D11ShaderDataBinding(d, m_parent.m_ctx, pipeline, vbuf, instVbo, ibuf,
ubufCount, ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs, ubufCount, ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs,
baseVert, baseInst); texBindIdx, depthBind, baseVert, baseInst);
d->m_SBinds.emplace_back(retval); d->m_SBinds.emplace_back(retval);
return retval; return retval;
} }
@ -1545,8 +1602,8 @@ void D3D11CommandQueue::ProcessDynamicLoads(ID3D11DeviceContext* ctx)
} }
for (D3D11Pool* p : gfxF->m_committedPools) for (D3D11Pool* p : gfxF->m_committedPools)
{ {
for (auto& b : p->m_DBufs) for (auto& b : p->m_items)
b.second->update(ctx, m_drawBuf); b->m_buf->update(ctx, m_drawBuf);
} }
} }

View File

@ -50,7 +50,7 @@ static inline UINT64 NextHeapOffset(UINT64 offset, const D3D12_RESOURCE_ALLOCATI
return (offset + info.Alignment - 1) & ~(info.Alignment - 1); return (offset + info.Alignment - 1) & ~(info.Alignment - 1);
} }
struct D3D12Data : IGraphicsDataPriv<D3D12Data> struct D3D12Data : IGraphicsDataPriv
{ {
std::vector<std::unique_ptr<class D3D12ShaderPipeline>> m_SPs; std::vector<std::unique_ptr<class D3D12ShaderPipeline>> m_SPs;
std::vector<std::unique_ptr<struct D3D12ShaderDataBinding>> m_SBinds; std::vector<std::unique_ptr<struct D3D12ShaderDataBinding>> m_SBinds;
@ -65,16 +65,20 @@ struct D3D12Data : IGraphicsDataPriv<D3D12Data>
ComPtr<ID3D12Heap> m_texHeap; ComPtr<ID3D12Heap> m_texHeap;
}; };
struct D3D12PoolItem : IGraphicsDataPriv
{
ComPtr<ID3D12Heap> m_bufHeap;
std::unique_ptr<class D3D12GraphicsBufferD> m_buf;
};
struct D3D12Pool : IGraphicsBufferPool struct D3D12Pool : IGraphicsBufferPool
{ {
struct Buffer std::unordered_set<D3D12PoolItem*> m_items;
~D3D12Pool()
{ {
ComPtr<ID3D12Heap> m_bufHeap; for (auto& item : m_items)
std::unique_ptr<class D3D12GraphicsBufferD> m_buf; item->decrement();
Buffer(ComPtr<ID3D12Heap>&& heap, class D3D12GraphicsBufferD* buf) }
: m_bufHeap(std::move(heap)), m_buf(buf) {}
};
std::unordered_map<class D3D12GraphicsBufferD*, Buffer> m_DBufs;
}; };
static const D3D12_RESOURCE_STATES USE_TABLE[] = static const D3D12_RESOURCE_STATES USE_TABLE[] =
@ -92,8 +96,10 @@ class D3D12GraphicsBufferS : public IGraphicsBufferS
D3D12_RESOURCE_STATES m_state; D3D12_RESOURCE_STATES m_state;
size_t m_sz; size_t m_sz;
D3D12_RESOURCE_DESC m_gpuDesc; D3D12_RESOURCE_DESC m_gpuDesc;
D3D12GraphicsBufferS(BufferUse use, D3D12Context* ctx, const void* data, size_t stride, size_t count) D3D12GraphicsBufferS(IGraphicsData* parent, BufferUse use, D3D12Context* ctx,
: m_state(USE_TABLE[int(use)]), m_stride(stride), m_count(count), m_sz(stride * count) const void* data, size_t stride, size_t count)
: IGraphicsBufferS(parent), m_state(USE_TABLE[int(use)]),
m_stride(stride), m_count(count), m_sz(stride * count)
{ {
size_t gpuSz = use == BufferUse::Uniform ? ((m_sz + 255) & ~255) : m_sz; size_t gpuSz = use == BufferUse::Uniform ? ((m_sz + 255) & ~255) : m_sz;
m_gpuDesc = CD3DX12_RESOURCE_DESC::Buffer(gpuSz); m_gpuDesc = CD3DX12_RESOURCE_DESC::Buffer(gpuSz);
@ -140,12 +146,13 @@ class D3D12GraphicsBufferD : public IGraphicsBufferD
std::unique_ptr<uint8_t[]> m_cpuBuf; std::unique_ptr<uint8_t[]> m_cpuBuf;
size_t m_cpuSz; size_t m_cpuSz;
int m_validSlots = 0; int m_validSlots = 0;
D3D12GraphicsBufferD(D3D12CommandQueue* q, BufferUse use, D3D12Context* ctx, size_t stride, size_t count) D3D12GraphicsBufferD(IGraphicsData* parent, D3D12CommandQueue* q, BufferUse use,
: m_state(USE_TABLE[int(use)]), m_q(q), m_stride(stride), m_count(count) D3D12Context* ctx, size_t stride, size_t count)
: IGraphicsBufferD(parent), m_state(USE_TABLE[int(use)]), m_q(q), m_stride(stride), m_count(count)
{ {
m_cpuSz = stride * count; m_cpuSz = stride * count;
m_cpuBuf.reset(new uint8_t[m_cpuSz]); size_t gpuSz = ((m_cpuSz + 255) & ~255);
size_t gpuSz = use == BufferUse::Uniform ? ((m_cpuSz + 255) & ~255) : m_cpuSz; m_cpuBuf.reset(new uint8_t[gpuSz]);
D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Buffer(gpuSz); D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Buffer(gpuSz);
size_t reqSz = GetRequiredIntermediateSize(ctx->m_dev.Get(), &desc, 0, 1); size_t reqSz = GetRequiredIntermediateSize(ctx->m_dev.Get(), &desc, 0, 1);
desc = CD3DX12_RESOURCE_DESC::Buffer(reqSz); desc = CD3DX12_RESOURCE_DESC::Buffer(reqSz);
@ -188,9 +195,9 @@ class D3D12TextureS : public ITextureS
TextureFormat m_fmt; TextureFormat m_fmt;
size_t m_sz; size_t m_sz;
D3D12_RESOURCE_DESC m_gpuDesc; D3D12_RESOURCE_DESC m_gpuDesc;
D3D12TextureS(D3D12Context* ctx, size_t width, size_t height, size_t mips, D3D12TextureS(IGraphicsData* parent, D3D12Context* ctx, size_t width, size_t height, size_t mips,
TextureFormat fmt, const void* data, size_t sz) TextureFormat fmt, const void* data, size_t sz)
: m_fmt(fmt), m_sz(sz), m_mipCount(mips) : ITextureS(parent), m_fmt(fmt), m_sz(sz), m_mipCount(mips)
{ {
DXGI_FORMAT pfmt; DXGI_FORMAT pfmt;
int pxPitchNum = 1; int pxPitchNum = 1;
@ -270,9 +277,10 @@ class D3D12TextureSA : public ITextureSA
size_t m_layers; size_t m_layers;
size_t m_sz; size_t m_sz;
D3D12_RESOURCE_DESC m_gpuDesc; D3D12_RESOURCE_DESC m_gpuDesc;
D3D12TextureSA(D3D12Context* ctx, size_t width, size_t height, size_t layers, D3D12TextureSA(IGraphicsData* parent, D3D12Context* ctx,
size_t width, size_t height, size_t layers,
size_t mips, TextureFormat fmt, const void* data, size_t sz) size_t mips, TextureFormat fmt, const void* data, size_t sz)
: m_fmt(fmt), m_layers(layers), m_sz(sz) : ITextureSA(parent), m_fmt(fmt), m_layers(layers), m_sz(sz)
{ {
size_t pxPitch; size_t pxPitch;
DXGI_FORMAT pixelFmt; DXGI_FORMAT pixelFmt;
@ -354,8 +362,9 @@ class D3D12TextureD : public ITextureD
size_t m_rowPitch; size_t m_rowPitch;
size_t m_cpuSz; size_t m_cpuSz;
int m_validSlots = 0; int m_validSlots = 0;
D3D12TextureD(D3D12CommandQueue* q, D3D12Context* ctx, size_t width, size_t height, TextureFormat fmt) D3D12TextureD(IGraphicsData* parent, D3D12CommandQueue* q, D3D12Context* ctx,
: m_width(width), m_height(height), m_fmt(fmt), m_q(q) size_t width, size_t height, TextureFormat fmt)
: ITextureD(parent), m_width(width), m_height(height), m_fmt(fmt), m_q(q)
{ {
DXGI_FORMAT pixelFmt; DXGI_FORMAT pixelFmt;
size_t pxPitch; size_t pxPitch;
@ -414,6 +423,7 @@ public:
}; };
static const float BLACK_COLOR[] = {0.0,0.0,0.0,1.0}; static const float BLACK_COLOR[] = {0.0,0.0,0.0,1.0};
#define MAX_BIND_TEXS 4
class D3D12TextureR : public ITextureR class D3D12TextureR : public ITextureR
{ {
@ -422,11 +432,11 @@ class D3D12TextureR : public ITextureR
size_t m_width = 0; size_t m_width = 0;
size_t m_height = 0; size_t m_height = 0;
size_t m_samples = 0; size_t m_samples = 0;
bool m_enableShaderColorBind; size_t m_colorBindCount;
bool m_enableShaderDepthBind; size_t m_depthBindCount;
void Setup(D3D12Context* ctx, size_t width, size_t height, size_t samples, void Setup(D3D12Context* ctx, size_t width, size_t height, size_t samples,
bool enableShaderColorBind, bool enableShaderDepthBind) size_t colorBindCount, size_t depthBindCount)
{ {
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));
@ -439,7 +449,6 @@ class D3D12TextureR : public ITextureR
CD3DX12_RESOURCE_DESC rtvresdesc; CD3DX12_RESOURCE_DESC rtvresdesc;
CD3DX12_RESOURCE_DESC dsvresdesc; CD3DX12_RESOURCE_DESC dsvresdesc;
CD3DX12_RESOURCE_DESC cbindresdesc; CD3DX12_RESOURCE_DESC cbindresdesc;
CD3DX12_RESOURCE_DESC dbindresdesc;
if (samples > 1) if (samples > 1)
{ {
@ -447,12 +456,10 @@ class D3D12TextureR : public ITextureR
dsvDim = D3D12_DSV_DIMENSION_TEXTURE2DMS; dsvDim = D3D12_DSV_DIMENSION_TEXTURE2DMS;
rtvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1, samples, rtvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1, samples,
0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT); 0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT);
dsvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D24_UNORM_S8_UINT, width, height, 1, 1, samples, dsvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R24G8_TYPELESS, width, height, 1, 1, samples,
0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT); 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT);
cbindresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1, samples, cbindresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1, samples,
0, D3D12_RESOURCE_FLAG_NONE, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT); 0, D3D12_RESOURCE_FLAG_NONE, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT);
dbindresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D24_UNORM_S8_UINT, width, height, 1, 1, samples,
0, D3D12_RESOURCE_FLAG_NONE, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT);
} }
else else
{ {
@ -460,12 +467,10 @@ class D3D12TextureR : public ITextureR
dsvDim = D3D12_DSV_DIMENSION_TEXTURE2D; dsvDim = D3D12_DSV_DIMENSION_TEXTURE2D;
rtvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1, 1, rtvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1, 1,
0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET); 0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET);
dsvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D24_UNORM_S8_UINT, width, height, 1, 1, 1, dsvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R24G8_TYPELESS, width, height, 1, 1, 1,
0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
cbindresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1, 1, cbindresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1, 1,
0, D3D12_RESOURCE_FLAG_NONE); 0, D3D12_RESOURCE_FLAG_NONE);
dbindresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D24_UNORM_S8_UINT, width, height, 1, 1, 1,
0, D3D12_RESOURCE_FLAG_NONE);
} }
D3D12_CLEAR_VALUE colorClear = {}; D3D12_CLEAR_VALUE colorClear = {};
@ -486,29 +491,35 @@ class D3D12TextureR : public ITextureR
D3D12_DEPTH_STENCIL_VIEW_DESC dsvvdesc = {DXGI_FORMAT_D24_UNORM_S8_UINT, dsvDim}; D3D12_DEPTH_STENCIL_VIEW_DESC dsvvdesc = {DXGI_FORMAT_D24_UNORM_S8_UINT, dsvDim};
ctx->m_dev->CreateDepthStencilView(m_depthTex.Get(), &dsvvdesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); ctx->m_dev->CreateDepthStencilView(m_depthTex.Get(), &dsvvdesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
if (enableShaderColorBind) for (size_t i=0 ; i<colorBindCount ; ++i)
{ {
ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE,
&cbindresdesc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, nullptr, &cbindresdesc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, nullptr,
__uuidof(ID3D12Resource), &m_colorBindTex)); __uuidof(ID3D12Resource), &m_colorBindTex[i]));
} }
if (enableShaderDepthBind) for (size_t i=0 ; i<depthBindCount ; ++i)
{ {
ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE,
&dbindresdesc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, nullptr, &dsvresdesc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, nullptr,
__uuidof(ID3D12Resource), &m_depthBindTex)); __uuidof(ID3D12Resource), &m_depthBindTex[i]));
} }
} }
D3D12CommandQueue* m_q; D3D12CommandQueue* m_q;
D3D12TextureR(D3D12Context* ctx, D3D12CommandQueue* q, size_t width, size_t height, size_t samples, D3D12TextureR(IGraphicsData* parent, D3D12Context* ctx, D3D12CommandQueue* q,
bool enableShaderColorBind, bool enableShaderDepthBind) size_t width, size_t height, size_t samples,
: m_q(q), m_width(width), m_height(height), m_samples(samples), size_t colorBindCount, size_t depthBindCount)
m_enableShaderColorBind(enableShaderColorBind), m_enableShaderDepthBind(enableShaderDepthBind) : ITextureR(parent), m_q(q), m_width(width), m_height(height), m_samples(samples),
m_colorBindCount(colorBindCount), m_depthBindCount(depthBindCount)
{ {
if (colorBindCount > MAX_BIND_TEXS)
Log.report(logvisor::Fatal, "too many color bindings for render texture");
if (depthBindCount > MAX_BIND_TEXS)
Log.report(logvisor::Fatal, "too many depth bindings for render texture");
if (samples == 0) m_samples = 1; if (samples == 0) m_samples = 1;
Setup(ctx, width, height, samples, enableShaderColorBind, enableShaderDepthBind); Setup(ctx, width, height, samples, colorBindCount, depthBindCount);
} }
public: public:
size_t samples() const {return m_samples;} size_t samples() const {return m_samples;}
@ -518,9 +529,9 @@ public:
ComPtr<ID3D12Resource> m_depthTex; ComPtr<ID3D12Resource> m_depthTex;
ComPtr<ID3D12DescriptorHeap> m_dsvHeap; ComPtr<ID3D12DescriptorHeap> m_dsvHeap;
ComPtr<ID3D12Resource> m_colorBindTex; ComPtr<ID3D12Resource> m_colorBindTex[MAX_BIND_TEXS];
ComPtr<ID3D12Resource> m_depthBindTex; ComPtr<ID3D12Resource> m_depthBindTex[MAX_BIND_TEXS];
~D3D12TextureR(); ~D3D12TextureR();
@ -532,7 +543,7 @@ public:
height = 1; height = 1;
m_width = width; m_width = width;
m_height = height; m_height = height;
Setup(ctx, width, height, m_samples, m_enableShaderColorBind, m_enableShaderDepthBind); Setup(ctx, width, height, m_samples, m_colorBindCount, m_depthBindCount);
} }
}; };
@ -588,8 +599,8 @@ struct D3D12VertexFormat : IVertexFormat
size_t m_stride = 0; size_t m_stride = 0;
size_t m_instStride = 0; size_t m_instStride = 0;
D3D12VertexFormat(size_t elementCount, const VertexElementDescriptor* elements) D3D12VertexFormat(IGraphicsData* parent, size_t elementCount, const VertexElementDescriptor* elements)
: m_elementCount(elementCount), : IVertexFormat(parent), m_elementCount(elementCount),
m_elements(new D3D12_INPUT_ELEMENT_DESC[elementCount]) m_elements(new D3D12_INPUT_ELEMENT_DESC[elementCount])
{ {
memset(m_elements.get(), 0, elementCount * sizeof(D3D12_INPUT_ELEMENT_DESC)); memset(m_elements.get(), 0, elementCount * sizeof(D3D12_INPUT_ELEMENT_DESC));
@ -649,12 +660,13 @@ class D3D12ShaderPipeline : public IShaderPipeline
D3D12ShareableShader::Token m_vert; D3D12ShareableShader::Token m_vert;
D3D12ShareableShader::Token m_pixel; D3D12ShareableShader::Token m_pixel;
D3D12ShaderPipeline(D3D12Context* ctx, D3D12ShareableShader::Token&& vert, D3D12ShaderPipeline(IGraphicsData* parent, D3D12Context* ctx, D3D12ShareableShader::Token&& vert,
D3D12ShareableShader::Token&& pixel, ID3DBlob* pipeline, D3D12ShareableShader::Token&& pixel, ID3DBlob* pipeline,
const D3D12VertexFormat* vtxFmt, const D3D12VertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, CullMode culling) ZTest depthTest, bool depthWrite, bool colorWrite,
: m_vtxFmt(vtxFmt), m_vert(std::move(vert)), m_pixel(std::move(pixel)), bool alphaWrite, CullMode culling)
: IShaderPipeline(parent), m_vtxFmt(vtxFmt), m_vert(std::move(vert)), m_pixel(std::move(pixel)),
m_topology(PRIMITIVE_TABLE[int(prim)]) m_topology(PRIMITIVE_TABLE[int(prim)])
{ {
D3D12_CULL_MODE cullMode; D3D12_CULL_MODE cullMode;
@ -687,13 +699,32 @@ class D3D12ShaderPipeline : public IShaderPipeline
desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE; desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO; desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
} }
desc.BlendState.RenderTarget[0].RenderTargetWriteMask =
(colorWrite ? (D3D12_COLOR_WRITE_ENABLE_RED |
D3D12_COLOR_WRITE_ENABLE_GREEN |
D3D12_COLOR_WRITE_ENABLE_BLUE) : 0) |
(alphaWrite ? D3D12_COLOR_WRITE_ENABLE_ALPHA : 0);
desc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); desc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
desc.RasterizerState.FrontCounterClockwise = TRUE; desc.RasterizerState.FrontCounterClockwise = TRUE;
desc.RasterizerState.CullMode = cullMode; desc.RasterizerState.CullMode = cullMode;
desc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); desc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER_EQUAL; switch (depthTest)
if (!depthTest) {
desc.DepthStencilState.DepthEnable = false; case ZTest::None:
default:
desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
break;
case ZTest::LEqual:
desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER_EQUAL;
break;
case ZTest::Greater:
desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
break;
case ZTest::Equal:
desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_EQUAL;
break;
}
desc.DepthStencilState.DepthEnable = depthTest != ZTest::None;
if (!depthWrite) if (!depthWrite)
desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO; desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
desc.InputLayout.NumElements = vtxFmt->m_elementCount; desc.InputLayout.NumElements = vtxFmt->m_elementCount;
@ -813,6 +844,17 @@ static const struct RGBATex2DNoMipViewDesc : D3D12_SHADER_RESOURCE_VIEW_DESC
} }
} RGBATex2DNoMipViewDesc; } RGBATex2DNoMipViewDesc;
static const struct RGBATex2DDepthViewDesc : D3D12_SHADER_RESOURCE_VIEW_DESC
{
RGBATex2DDepthViewDesc()
{
Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
Texture2D = {UINT(0), UINT(1), UINT(0), 0.0f};
}
} RGBATex2DDepthViewDesc;
static const struct RGBATex2DViewDesc : D3D12_SHADER_RESOURCE_VIEW_DESC static const struct RGBATex2DViewDesc : D3D12_SHADER_RESOURCE_VIEW_DESC
{ {
RGBATex2DViewDesc() RGBATex2DViewDesc()
@ -868,7 +910,7 @@ static const struct GreyTex2DArrayViewDesc : D3D12_SHADER_RESOURCE_VIEW_DESC
} }
} GreyTex2DArrayViewDesc; } GreyTex2DArrayViewDesc;
static ID3D12Resource* GetTextureGPUResource(const ITexture* tex, int idx, static ID3D12Resource* GetTextureGPUResource(const ITexture* tex, int idx, int bindIdx, bool depth,
D3D12_SHADER_RESOURCE_VIEW_DESC& descOut) D3D12_SHADER_RESOURCE_VIEW_DESC& descOut)
{ {
switch (tex->type()) switch (tex->type())
@ -927,15 +969,23 @@ static ID3D12Resource* GetTextureGPUResource(const ITexture* tex, int idx,
case TextureType::Render: case TextureType::Render:
{ {
const D3D12TextureR* ctex = static_cast<const D3D12TextureR*>(tex); const D3D12TextureR* ctex = static_cast<const D3D12TextureR*>(tex);
descOut = RGBATex2DNoMipViewDesc; if (depth)
return ctex->m_colorBindTex.Get(); {
descOut = RGBATex2DDepthViewDesc;
return ctex->m_depthBindTex[bindIdx].Get();
}
else
{
descOut = RGBATex2DNoMipViewDesc;
return ctex->m_colorBindTex[bindIdx].Get();
}
} }
default: break; default: break;
} }
return nullptr; return nullptr;
} }
struct D3D12ShaderDataBinding : IShaderDataBindingPriv<D3D12Data> struct D3D12ShaderDataBinding : IShaderDataBindingPriv
{ {
D3D12ShaderPipeline* m_pipeline; D3D12ShaderPipeline* m_pipeline;
ComPtr<ID3D12Heap> m_gpuHeap; ComPtr<ID3D12Heap> m_gpuHeap;
@ -948,7 +998,13 @@ struct D3D12ShaderDataBinding : IShaderDataBindingPriv<D3D12Data>
std::vector<std::pair<size_t,size_t>> m_ubufOffs; std::vector<std::pair<size_t,size_t>> m_ubufOffs;
size_t m_texCount; size_t m_texCount;
ID3D12Resource* m_knownViewHandles[2][8] = {}; ID3D12Resource* m_knownViewHandles[2][8] = {};
std::unique_ptr<ITexture*[]> m_texs; struct BindTex
{
ITexture* tex;
int idx;
bool depth;
};
std::unique_ptr<BindTex[]> m_texs;
D3D12_VERTEX_BUFFER_VIEW m_vboView[2][2] = {{},{}}; D3D12_VERTEX_BUFFER_VIEW m_vboView[2][2] = {{},{}};
D3D12_INDEX_BUFFER_VIEW m_iboView[2]; D3D12_INDEX_BUFFER_VIEW m_iboView[2];
size_t m_vertOffset, m_instOffset; size_t m_vertOffset, m_instOffset;
@ -960,6 +1016,7 @@ struct D3D12ShaderDataBinding : IShaderDataBindingPriv<D3D12Data>
size_t ubufCount, IGraphicsBuffer** ubufs, size_t ubufCount, IGraphicsBuffer** ubufs,
const size_t* ubufOffs, const size_t* ubufSizes, const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, ITexture** texs, size_t texCount, ITexture** texs,
const int* bindIdxs, const bool* bindDepth,
size_t baseVert, size_t baseInst) size_t baseVert, size_t baseInst)
: IShaderDataBindingPriv(d), : IShaderDataBindingPriv(d),
m_pipeline(static_cast<D3D12ShaderPipeline*>(pipeline)), m_pipeline(static_cast<D3D12ShaderPipeline*>(pipeline)),
@ -969,7 +1026,7 @@ struct D3D12ShaderDataBinding : IShaderDataBindingPriv<D3D12Data>
m_ubufCount(ubufCount), m_ubufCount(ubufCount),
m_ubufs(new IGraphicsBuffer*[ubufCount]), m_ubufs(new IGraphicsBuffer*[ubufCount]),
m_texCount(texCount), m_texCount(texCount),
m_texs(new ITexture*[texCount]) m_texs(new BindTex[texCount])
{ {
m_vertOffset = baseVert * m_pipeline->m_vtxFmt->m_stride; m_vertOffset = baseVert * m_pipeline->m_vtxFmt->m_stride;
m_instOffset = baseInst * m_pipeline->m_vtxFmt->m_instStride; m_instOffset = baseInst * m_pipeline->m_vtxFmt->m_instStride;
@ -996,7 +1053,9 @@ struct D3D12ShaderDataBinding : IShaderDataBindingPriv<D3D12Data>
} }
for (size_t i=0 ; i<texCount ; ++i) for (size_t i=0 ; i<texCount ; ++i)
{ {
m_texs[i] = texs[i]; m_texs[i].tex = texs[i];
m_texs[i].idx = bindIdxs ? bindIdxs[i] : 0;
m_texs[i].depth = bindDepth ? bindDepth[i] : false;
} }
} }
@ -1053,10 +1112,10 @@ struct D3D12ShaderDataBinding : IShaderDataBindingPriv<D3D12Data>
} }
for (size_t i=0 ; i<MAX_TEXTURE_COUNT ; ++i) for (size_t i=0 ; i<MAX_TEXTURE_COUNT ; ++i)
{ {
if (i<m_texCount && m_texs[i]) if (i<m_texCount && m_texs[i].tex)
{ {
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc; D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
ID3D12Resource* res = GetTextureGPUResource(m_texs[i], b, srvDesc); ID3D12Resource* res = GetTextureGPUResource(m_texs[i].tex, b, m_texs[i].idx, m_texs[i].depth, srvDesc);
m_knownViewHandles[b][i] = res; m_knownViewHandles[b][i] = res;
ctx->m_dev->CreateShaderResourceView(res, &srvDesc, handle); ctx->m_dev->CreateShaderResourceView(res, &srvDesc, handle);
} }
@ -1071,22 +1130,40 @@ struct D3D12ShaderDataBinding : IShaderDataBindingPriv<D3D12Data>
CD3DX12_CPU_DESCRIPTOR_HANDLE heapStart; CD3DX12_CPU_DESCRIPTOR_HANDLE heapStart;
for (size_t i=0 ; i<MAX_TEXTURE_COUNT ; ++i) for (size_t i=0 ; i<MAX_TEXTURE_COUNT ; ++i)
{ {
if (i<m_texCount && m_texs[i]) if (i<m_texCount && m_texs[i].tex)
{ {
if (m_texs[i]->type() == TextureType::Render) if (m_texs[i].tex->type() == TextureType::Render)
{ {
const D3D12TextureR* ctex = static_cast<const D3D12TextureR*>(m_texs[i]); const D3D12TextureR* ctex = static_cast<const D3D12TextureR*>(m_texs[i].tex);
ID3D12Resource* res = ctex->m_colorBindTex.Get(); if (m_texs[i].depth)
if (res != m_knownViewHandles[b][i])
{ {
if (incSz == UINT(-1)) ID3D12Resource* res = ctex->m_depthBindTex[m_texs[i].idx].Get();
if (res != m_knownViewHandles[b][i])
{ {
incSz = ctx->m_dev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); if (incSz == UINT(-1))
heapStart = m_descHeap[b]->GetCPUDescriptorHandleForHeapStart(); {
incSz = ctx->m_dev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
heapStart = m_descHeap[b]->GetCPUDescriptorHandleForHeapStart();
}
m_knownViewHandles[b][i] = res;
ctx->m_dev->CreateShaderResourceView(res, &RGBATex2DDepthViewDesc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(heapStart, MAX_UNIFORM_COUNT + i, incSz));
}
}
else
{
ID3D12Resource* res = ctex->m_colorBindTex[m_texs[i].idx].Get();
if (res != m_knownViewHandles[b][i])
{
if (incSz == UINT(-1))
{
incSz = ctx->m_dev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
heapStart = m_descHeap[b]->GetCPUDescriptorHandleForHeapStart();
}
m_knownViewHandles[b][i] = res;
ctx->m_dev->CreateShaderResourceView(res, &RGBATex2DNoMipViewDesc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(heapStart, MAX_UNIFORM_COUNT + i, incSz));
} }
m_knownViewHandles[b][i] = res;
ctx->m_dev->CreateShaderResourceView(res, &RGBATex2DNoMipViewDesc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(heapStart, MAX_UNIFORM_COUNT + i, incSz));
} }
} }
} }
@ -1306,23 +1383,25 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
m_cmdList->DrawIndexedInstanced(count, instCount, start, 0, 0); m_cmdList->DrawIndexedInstanced(count, instCount, start, 0, 0);
} }
void resolveBindTexture(ITextureR* texture, const SWindowRect& rect, bool tlOrigin, bool color, bool depth) void resolveBindTexture(ITextureR* texture, const SWindowRect& rect, bool tlOrigin,
int bindIdx, bool color, bool depth)
{ {
const D3D12TextureR* tex = static_cast<const D3D12TextureR*>(texture); const D3D12TextureR* tex = static_cast<const D3D12TextureR*>(texture);
if (color && tex->m_enableShaderColorBind)
if (color && tex->m_colorBindCount)
{ {
D3D12_RESOURCE_BARRIER copySetup[] = D3D12_RESOURCE_BARRIER copySetup[] =
{ {
CD3DX12_RESOURCE_BARRIER::Transition(tex->m_colorTex.Get(), CD3DX12_RESOURCE_BARRIER::Transition(tex->m_colorTex.Get(),
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE),
CD3DX12_RESOURCE_BARRIER::Transition(tex->m_colorBindTex.Get(), CD3DX12_RESOURCE_BARRIER::Transition(tex->m_colorBindTex[bindIdx].Get(),
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST) D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST)
}; };
m_cmdList->ResourceBarrier(2, copySetup); m_cmdList->ResourceBarrier(2, copySetup);
if (tex->m_samples > 1) if (tex->m_samples > 1)
{ {
m_cmdList->CopyResource(tex->m_colorBindTex.Get(), tex->m_colorTex.Get()); m_cmdList->CopyResource(tex->m_colorBindTex[bindIdx].Get(), tex->m_colorTex.Get());
} }
else else
{ {
@ -1330,7 +1409,8 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
int y = tlOrigin ? intersectRect.location[1] : (tex->m_height - intersectRect.size[1] - intersectRect.location[1]); int y = tlOrigin ? intersectRect.location[1] : (tex->m_height - intersectRect.size[1] - intersectRect.location[1]);
D3D12_BOX box = {UINT(intersectRect.location[0]), UINT(y), 0, D3D12_BOX box = {UINT(intersectRect.location[0]), UINT(y), 0,
UINT(intersectRect.location[0] + intersectRect.size[0]), UINT(y + intersectRect.size[1]), 1}; UINT(intersectRect.location[0] + intersectRect.size[0]), UINT(y + intersectRect.size[1]), 1};
D3D12_TEXTURE_COPY_LOCATION dst = {tex->m_colorBindTex.Get(), D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX};
D3D12_TEXTURE_COPY_LOCATION dst = {tex->m_colorBindTex[bindIdx].Get(), D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX};
dst.SubresourceIndex = 0; dst.SubresourceIndex = 0;
D3D12_TEXTURE_COPY_LOCATION src = {tex->m_colorTex.Get(), D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX}; D3D12_TEXTURE_COPY_LOCATION src = {tex->m_colorTex.Get(), D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX};
src.SubresourceIndex = 0; src.SubresourceIndex = 0;
@ -1341,29 +1421,29 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
{ {
CD3DX12_RESOURCE_BARRIER::Transition(tex->m_colorTex.Get(), CD3DX12_RESOURCE_BARRIER::Transition(tex->m_colorTex.Get(),
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET), D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET),
CD3DX12_RESOURCE_BARRIER::Transition(tex->m_colorBindTex.Get(), CD3DX12_RESOURCE_BARRIER::Transition(tex->m_colorBindTex[bindIdx].Get(),
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
}; };
m_cmdList->ResourceBarrier(2, copyTeardown); m_cmdList->ResourceBarrier(2, copyTeardown);
} }
if (depth && tex->m_enableShaderDepthBind) if (depth && tex->m_depthBindCount)
{ {
D3D12_RESOURCE_BARRIER copySetup[] = D3D12_RESOURCE_BARRIER copySetup[] =
{ {
CD3DX12_RESOURCE_BARRIER::Transition(tex->m_depthTex.Get(), CD3DX12_RESOURCE_BARRIER::Transition(tex->m_depthTex.Get(),
D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE),
CD3DX12_RESOURCE_BARRIER::Transition(tex->m_depthBindTex.Get(), CD3DX12_RESOURCE_BARRIER::Transition(tex->m_depthBindTex[bindIdx].Get(),
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST) D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST)
}; };
m_cmdList->ResourceBarrier(2, copySetup); m_cmdList->ResourceBarrier(2, copySetup);
m_cmdList->CopyResource(tex->m_depthBindTex.Get(), tex->m_depthTex.Get()); m_cmdList->CopyResource(tex->m_depthBindTex[bindIdx].Get(), tex->m_depthTex.Get());
D3D12_RESOURCE_BARRIER copyTeardown[] = D3D12_RESOURCE_BARRIER copyTeardown[] =
{ {
CD3DX12_RESOURCE_BARRIER::Transition(tex->m_depthTex.Get(), CD3DX12_RESOURCE_BARRIER::Transition(tex->m_depthTex.Get(),
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE), D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE),
CD3DX12_RESOURCE_BARRIER::Transition(tex->m_depthBindTex.Get(), CD3DX12_RESOURCE_BARRIER::Transition(tex->m_depthBindTex[bindIdx].Get(),
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
}; };
m_cmdList->ResourceBarrier(2, copyTeardown); m_cmdList->ResourceBarrier(2, copyTeardown);
@ -1598,7 +1678,9 @@ class D3D12DataFactory : public ID3DDataFactory
{ {
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue()); D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
D3D12Pool* pool = static_cast<D3D12Pool*>(p); D3D12Pool* pool = static_cast<D3D12Pool*>(p);
D3D12GraphicsBufferD* retval = new D3D12GraphicsBufferD(q, use, m_ctx, stride, count); D3D12PoolItem* item = new D3D12PoolItem;
D3D12GraphicsBufferD* retval = new D3D12GraphicsBufferD(item, q, use, m_ctx, stride, count);
item->m_buf.reset(retval);
/* Gather resource descriptions */ /* Gather resource descriptions */
D3D12_RESOURCE_DESC bufDescs[2]; D3D12_RESOURCE_DESC bufDescs[2];
@ -1606,24 +1688,28 @@ class D3D12DataFactory : public ID3DDataFactory
bufDescs[1] = retval->m_bufs[1]->GetDesc(); bufDescs[1] = retval->m_bufs[1]->GetDesc();
/* Create heap */ /* Create heap */
ComPtr<ID3D12Heap> bufHeap;
D3D12_RESOURCE_ALLOCATION_INFO bufAllocInfo = D3D12_RESOURCE_ALLOCATION_INFO bufAllocInfo =
m_ctx->m_dev->GetResourceAllocationInfo(0, 2, bufDescs); m_ctx->m_dev->GetResourceAllocationInfo(0, 2, bufDescs);
ThrowIfFailed(m_ctx->m_dev->CreateHeap(&CD3DX12_HEAP_DESC(bufAllocInfo, ThrowIfFailed(m_ctx->m_dev->CreateHeap(&CD3DX12_HEAP_DESC(bufAllocInfo,
D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS), D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS),
__uuidof(ID3D12Heap), &bufHeap)); __uuidof(ID3D12Heap), &item->m_bufHeap));
/* Place resources */ /* Place resources */
PlaceBufferForGPU(retval, m_ctx, bufHeap.Get(), 0); PlaceBufferForGPU(retval, m_ctx, item->m_bufHeap.Get(), 0);
pool->m_DBufs.emplace(std::make_pair(retval, D3D12Pool::Buffer{std::move(bufHeap), retval})); pool->m_items.emplace(item);
return retval; return retval;
} }
void deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf) void deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf)
{ {
D3D12Pool* pool = static_cast<D3D12Pool*>(p); D3D12Pool* pool = static_cast<D3D12Pool*>(p);
pool->m_DBufs.erase(static_cast<D3D12GraphicsBufferD*>(buf)); auto search = pool->m_items.find(static_cast<D3D12PoolItem*>(buf->m_parentData));
if (search != pool->m_items.end())
{
(*search)->decrement();
pool->m_items.erase(search);
}
} }
public: public:
@ -1664,58 +1750,65 @@ public:
IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) 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); D3D12Data* d = D3D12DataFactory::m_deferredData;
static_cast<D3D12Data*>(m_deferredData)->m_SBufs.emplace_back(retval); D3D12GraphicsBufferS* retval = new D3D12GraphicsBufferS(d, use, m_parent.m_ctx, data, stride, count);
d->m_SBufs.emplace_back(retval);
return retval; return retval;
} }
IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count) IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count)
{ {
D3D12Data* d = D3D12DataFactory::m_deferredData;
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent.m_parent->getCommandQueue()); D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent.m_parent->getCommandQueue());
D3D12GraphicsBufferD* retval = new D3D12GraphicsBufferD(q, use, m_parent.m_ctx, stride, count); D3D12GraphicsBufferD* retval = new D3D12GraphicsBufferD(d, q, use, m_parent.m_ctx, stride, count);
static_cast<D3D12Data*>(m_deferredData)->m_DBufs.emplace_back(retval); d->m_DBufs.emplace_back(retval);
return retval; return retval;
} }
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)
{ {
D3D12TextureS* retval = new D3D12TextureS(m_parent.m_ctx, width, height, mips, fmt, data, sz); D3D12Data* d = D3D12DataFactory::m_deferredData;
static_cast<D3D12Data*>(m_deferredData)->m_STexs.emplace_back(retval); D3D12TextureS* retval = new D3D12TextureS(d, m_parent.m_ctx, width, height, mips, fmt, data, sz);
d->m_STexs.emplace_back(retval);
return retval; return retval;
} }
ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips, ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, const void* data, size_t sz) TextureFormat fmt, const void* data, size_t sz)
{ {
D3D12TextureSA* retval = new D3D12TextureSA(m_parent.m_ctx, width, height, layers, mips, fmt, data, sz); D3D12Data* d = D3D12DataFactory::m_deferredData;
static_cast<D3D12Data*>(m_deferredData)->m_SATexs.emplace_back(retval); D3D12TextureSA* retval = new D3D12TextureSA(d, m_parent.m_ctx, width, height, layers, mips, fmt, data, sz);
d->m_SATexs.emplace_back(retval);
return retval; return retval;
} }
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt) ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
{ {
D3D12Data* d = D3D12DataFactory::m_deferredData;
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent.m_parent->getCommandQueue()); D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent.m_parent->getCommandQueue());
D3D12TextureD* retval = new D3D12TextureD(q, m_parent.m_ctx, width, height, fmt); D3D12TextureD* retval = new D3D12TextureD(d, q, m_parent.m_ctx, width, height, fmt);
static_cast<D3D12Data*>(m_deferredData)->m_DTexs.emplace_back(retval); d->m_DTexs.emplace_back(retval);
return retval; return retval;
} }
ITextureR* newRenderTexture(size_t width, size_t height, ITextureR* newRenderTexture(size_t width, size_t height,
bool enableShaderColorBind, bool enableShaderDepthBind) size_t colorBindCount, size_t depthBindCount)
{ {
D3D12Data* d = D3D12DataFactory::m_deferredData;
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent.m_parent->getCommandQueue()); 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, D3D12TextureR* retval = new D3D12TextureR(d, m_parent.m_ctx, q, width, height, m_parent.m_sampleCount,
enableShaderColorBind, enableShaderDepthBind); colorBindCount, depthBindCount);
static_cast<D3D12Data*>(m_deferredData)->m_RTexs.emplace_back(retval); d->m_RTexs.emplace_back(retval);
return retval; return retval;
} }
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements, IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
size_t baseVert, size_t baseInst) size_t baseVert, size_t baseInst)
{ {
D3D12VertexFormat* retval = new struct D3D12VertexFormat(elementCount, elements); D3D12Data* d = D3D12DataFactory::m_deferredData;
static_cast<D3D12Data*>(m_deferredData)->m_VFmts.emplace_back(retval); D3D12VertexFormat* retval = new struct D3D12VertexFormat(d, elementCount, elements);
d->m_VFmts.emplace_back(retval);
return retval; return retval;
} }
@ -1768,8 +1861,10 @@ public:
ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut, ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut,
ComPtr<ID3DBlob>* pipelineBlob, IVertexFormat* vtxFmt, ComPtr<ID3DBlob>* pipelineBlob, IVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, CullMode culling) ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling)
{ {
D3D12Data* d = D3D12DataFactory::m_deferredData;
XXH64_state_t hashState; XXH64_state_t hashState;
uint64_t srcHashes[2] = {}; uint64_t srcHashes[2] = {};
uint64_t binHashes[2] = {}; uint64_t binHashes[2] = {};
@ -1846,18 +1941,19 @@ public:
auto it = auto it =
m_parent.m_sharedShaders.emplace(std::make_pair(binHashes[1], m_parent.m_sharedShaders.emplace(std::make_pair(binHashes[1],
std::make_unique<D3D12ShareableShader>(m_parent, srcHashes[0], binHashes[1], std::make_unique<D3D12ShareableShader>(m_parent, srcHashes[1], binHashes[1],
std::move(fragBlob)))).first; std::move(fragBlob)))).first;
fragShader = it->second->lock(); fragShader = it->second->lock();
} }
ID3DBlob* pipeline = pipelineBlob ? pipelineBlob->Get() : nullptr; ID3DBlob* pipeline = pipelineBlob ? pipelineBlob->Get() : nullptr;
D3D12ShaderPipeline* retval = new D3D12ShaderPipeline(m_parent.m_ctx, std::move(vertShader), std::move(fragShader), D3D12ShaderPipeline* retval = new D3D12ShaderPipeline(d, m_parent.m_ctx, std::move(vertShader), std::move(fragShader),
pipeline, static_cast<const D3D12VertexFormat*>(vtxFmt), pipeline, static_cast<const D3D12VertexFormat*>(vtxFmt),
srcFac, dstFac, prim, depthTest, depthWrite, culling); srcFac, dstFac, prim, depthTest, depthWrite, colorWrite,
alphaWrite, culling);
if (pipelineBlob && !*pipelineBlob) if (pipelineBlob && !*pipelineBlob)
retval->m_state->GetCachedBlob(&*pipelineBlob); retval->m_state->GetCachedBlob(&*pipelineBlob);
static_cast<D3D12Data*>(m_deferredData)->m_SPs.emplace_back(retval); d->m_SPs.emplace_back(retval);
return retval; return retval;
} }
@ -1867,13 +1963,14 @@ public:
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages, size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
const size_t* ubufOffs, const size_t* ubufSizes, const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, ITexture** texs, size_t texCount, ITexture** texs,
const int* bindIdxs, const bool* bindDepth,
size_t baseVert, size_t baseInst) size_t baseVert, size_t baseInst)
{ {
D3D12Data* d = static_cast<D3D12Data*>(m_deferredData); D3D12Data* d = static_cast<D3D12Data*>(m_deferredData);
D3D12ShaderDataBinding* retval = D3D12ShaderDataBinding* retval =
new D3D12ShaderDataBinding(d, m_parent.m_ctx, pipeline, vbuf, instVbuf, ibuf, new D3D12ShaderDataBinding(d, m_parent.m_ctx, pipeline, vbuf, instVbuf, ibuf,
ubufCount, ubufs, ubufOffs, ubufSizes, texCount, texs, ubufCount, ubufs, ubufOffs, ubufSizes, texCount, texs,
baseVert, baseInst); bindIdxs, bindDepth, baseVert, baseInst);
d->m_SBinds.emplace_back(retval); d->m_SBinds.emplace_back(retval);
return retval; return retval;
} }
@ -2032,8 +2129,8 @@ void D3D12CommandQueue::execute()
} }
for (D3D12Pool* p : gfxF->m_committedPools) for (D3D12Pool* p : gfxF->m_committedPools)
{ {
for (auto& b : p->m_DBufs) for (auto& b : p->m_items)
b.second.m_buf->update(m_fillBuf); b->m_buf->update(m_fillBuf);
} }
datalk.unlock(); datalk.unlock();

View File

@ -150,27 +150,37 @@ static void SetImageLayout(VkCommandBuffer cmd, VkImage image,
imageMemoryBarrier.subresourceRange.baseMipLevel = 0; imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.levelCount = mipCount; imageMemoryBarrier.subresourceRange.levelCount = mipCount;
imageMemoryBarrier.subresourceRange.layerCount = layerCount; imageMemoryBarrier.subresourceRange.layerCount = layerCount;
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
switch (old_image_layout) switch (old_image_layout)
{ {
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
imageMemoryBarrier.srcAccessMask = imageMemoryBarrier.srcAccessMask =
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
src_stages = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
break; break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
imageMemoryBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; imageMemoryBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
src_stages = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
break; break;
case VK_IMAGE_LAYOUT_PREINITIALIZED: case VK_IMAGE_LAYOUT_PREINITIALIZED:
imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
break; break;
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
src_stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
break; break;
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
src_stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
break; break;
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
src_stages = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
break; break;
default: break; default: break;
} }
@ -179,30 +189,33 @@ static void SetImageLayout(VkCommandBuffer cmd, VkImage image,
{ {
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
dest_stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
break; break;
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dest_stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
break; break;
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dest_stages = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
break; break;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
imageMemoryBarrier.dstAccessMask = imageMemoryBarrier.dstAccessMask =
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
dest_stages = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
break; break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
imageMemoryBarrier.dstAccessMask = imageMemoryBarrier.dstAccessMask =
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
dest_stages = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
break; break;
case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dest_stages = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
break; break;
default: break; default: break;
} }
VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
vk::CmdPipelineBarrier(cmd, src_stages, dest_stages, 0, 0, NULL, 0, NULL, vk::CmdPipelineBarrier(cmd, src_stages, dest_stages, 0, 0, NULL, 0, NULL,
1, &imageMemoryBarrier); 1, &imageMemoryBarrier);
} }
@ -325,7 +338,6 @@ void VulkanContext::initVulkan(const char* appName)
#ifndef NDEBUG #ifndef NDEBUG
m_layerNames.push_back("VK_LAYER_LUNARG_core_validation"); m_layerNames.push_back("VK_LAYER_LUNARG_core_validation");
m_layerNames.push_back("VK_LAYER_LUNARG_object_tracker"); m_layerNames.push_back("VK_LAYER_LUNARG_object_tracker");
m_layerNames.push_back("VK_LAYER_LUNARG_image");
m_layerNames.push_back("VK_LAYER_LUNARG_parameter_validation"); m_layerNames.push_back("VK_LAYER_LUNARG_parameter_validation");
m_layerNames.push_back("VK_LAYER_LUNARG_swapchain"); m_layerNames.push_back("VK_LAYER_LUNARG_swapchain");
m_layerNames.push_back("VK_LAYER_GOOGLE_threading"); m_layerNames.push_back("VK_LAYER_GOOGLE_threading");
@ -720,7 +732,7 @@ bool VulkanContext::_resizeSwapChains()
return true; return true;
} }
struct VulkanData : IGraphicsDataPriv<VulkanData> struct VulkanData : IGraphicsDataPriv
{ {
VulkanContext* m_ctx; VulkanContext* m_ctx;
VkDeviceMemory m_bufMem = VK_NULL_HANDLE; VkDeviceMemory m_bufMem = VK_NULL_HANDLE;
@ -745,36 +757,38 @@ struct VulkanData : IGraphicsDataPriv<VulkanData>
} }
}; };
struct VulkanPool : IGraphicsBufferPool struct VulkanPoolItem : IGraphicsDataPriv
{ {
VulkanContext* m_ctx; VulkanContext* m_ctx;
struct Buffer VkDeviceMemory m_bufMem = VK_NULL_HANDLE;
{ std::unique_ptr<class VulkanGraphicsBufferD> m_buf;
VkDeviceMemory m_bufMem = VK_NULL_HANDLE; bool m_dead = false;
std::unique_ptr<class VulkanGraphicsBufferD> m_buffer; VulkanPoolItem(VulkanContext* ctx) : m_ctx(ctx) {}
bool m_dead = false; ~VulkanPoolItem()
Buffer(VkDeviceMemory mem, class VulkanGraphicsBufferD* buf) {
: m_bufMem(mem), m_buffer(buf) {} if (m_bufMem)
}; vk::FreeMemory(m_ctx->m_dev, m_bufMem, nullptr);
std::unordered_map<class VulkanGraphicsBufferD*, Buffer> m_DBufs; }
};
struct VulkanPool : IGraphicsBufferPool
{
std::unordered_set<VulkanPoolItem*> m_items;
bool m_dead = false; bool m_dead = false;
VulkanPool(VulkanContext* ctx) : m_ctx(ctx) {}
~VulkanPool() ~VulkanPool()
{ {
for (auto& buf : m_DBufs) for (auto& item : m_items)
if (buf.second.m_bufMem) item->decrement();
vk::FreeMemory(m_ctx->m_dev, buf.second.m_bufMem, nullptr);
} }
void clearDeadBuffers() void clearDeadBuffers()
{ {
for (auto it = m_DBufs.begin() ; it != m_DBufs.end() ;) for (auto it = m_items.begin() ; it != m_items.end() ;)
{ {
if (it->second.m_dead) if ((*it)->m_dead)
{ {
if (it->second.m_bufMem) (*it)->decrement();
vk::FreeMemory(m_ctx->m_dev, it->second.m_bufMem, nullptr); it = m_items.erase(it);
it = m_DBufs.erase(it);
continue; continue;
} }
++it; ++it;
@ -797,8 +811,9 @@ class VulkanGraphicsBufferS : public IGraphicsBufferS
VulkanContext* m_ctx; VulkanContext* m_ctx;
size_t m_sz; size_t m_sz;
std::unique_ptr<uint8_t[]> m_stagingBuf; std::unique_ptr<uint8_t[]> m_stagingBuf;
VulkanGraphicsBufferS(BufferUse use, VulkanContext* ctx, const void* data, size_t stride, size_t count) VulkanGraphicsBufferS(IGraphicsData* parent, BufferUse use, VulkanContext* ctx,
: m_ctx(ctx), m_stride(stride), m_count(count), m_sz(stride * count), const void* data, size_t stride, size_t count)
: IGraphicsBufferS(parent), m_ctx(ctx), m_stride(stride), m_count(count), m_sz(stride * count),
m_stagingBuf(new uint8_t[m_sz]), m_uniform(use == BufferUse::Uniform) m_stagingBuf(new uint8_t[m_sz]), m_uniform(use == BufferUse::Uniform)
{ {
memmove(m_stagingBuf.get(), data, m_sz); memmove(m_stagingBuf.get(), data, m_sz);
@ -865,8 +880,10 @@ class VulkanGraphicsBufferD : public IGraphicsBufferD
size_t m_cpuSz; size_t m_cpuSz;
std::unique_ptr<uint8_t[]> m_cpuBuf; std::unique_ptr<uint8_t[]> m_cpuBuf;
int m_validSlots = 0; int m_validSlots = 0;
VulkanGraphicsBufferD(VulkanCommandQueue* q, BufferUse use, VulkanContext* ctx, size_t stride, size_t count) VulkanGraphicsBufferD(IGraphicsData* parent, VulkanCommandQueue* q, BufferUse use,
: m_q(q), m_stride(stride), m_count(count), m_cpuSz(stride * count), m_cpuBuf(new uint8_t[m_cpuSz]), VulkanContext* ctx, size_t stride, size_t count)
: IGraphicsBufferD(parent), m_q(q), m_stride(stride), m_count(count),
m_cpuSz(stride * count), m_cpuBuf(new uint8_t[m_cpuSz]),
m_uniform(use == BufferUse::Uniform) m_uniform(use == BufferUse::Uniform)
{ {
VkBufferCreateInfo bufInfo = {}; VkBufferCreateInfo bufInfo = {};
@ -941,9 +958,10 @@ class VulkanTextureS : public ITextureS
int m_pixelPitchNum = 1; int m_pixelPitchNum = 1;
int m_pixelPitchDenom = 1; int m_pixelPitchDenom = 1;
VulkanTextureS(VulkanContext* ctx, size_t width, size_t height, size_t mips, VulkanTextureS(IGraphicsData* parent, VulkanContext* ctx,
size_t width, size_t height, size_t mips,
TextureFormat fmt, const void* data, size_t sz) TextureFormat fmt, const void* data, size_t sz)
: m_ctx(ctx), m_fmt(fmt), m_sz(sz), m_width(width), m_height(height), m_mips(mips) : ITextureS(parent), m_ctx(ctx), m_fmt(fmt), m_sz(sz), m_width(width), m_height(height), m_mips(mips)
{ {
VkFormat pfmt; VkFormat pfmt;
switch (fmt) switch (fmt)
@ -1139,9 +1157,11 @@ class VulkanTextureSA : public ITextureSA
int m_pixelPitchNum = 1; int m_pixelPitchNum = 1;
int m_pixelPitchDenom = 1; int m_pixelPitchDenom = 1;
VulkanTextureSA(VulkanContext* ctx, size_t width, size_t height, size_t layers, VulkanTextureSA(IGraphicsData* parent, VulkanContext* ctx,
size_t width, size_t height, size_t layers,
size_t mips, TextureFormat fmt, const void* data, size_t sz) size_t mips, TextureFormat fmt, const void* data, size_t sz)
: m_ctx(ctx), m_fmt(fmt), m_width(width), m_height(height), m_layers(layers), m_mips(mips), m_sz(sz) : ITextureSA(parent), m_ctx(ctx), m_fmt(fmt), m_width(width),
m_height(height), m_layers(layers), m_mips(mips), m_sz(sz)
{ {
VkFormat pfmt; VkFormat pfmt;
switch (fmt) switch (fmt)
@ -1336,8 +1356,9 @@ class VulkanTextureD : public ITextureD
VkDeviceSize m_cpuOffsets[2]; VkDeviceSize m_cpuOffsets[2];
VkFormat m_vkFmt; VkFormat m_vkFmt;
int m_validSlots = 0; int m_validSlots = 0;
VulkanTextureD(VulkanCommandQueue* q, VulkanContext* ctx, size_t width, size_t height, TextureFormat fmt) VulkanTextureD(IGraphicsData* parent, VulkanCommandQueue* q, VulkanContext* ctx,
: m_width(width), m_height(height), m_fmt(fmt), m_q(q) size_t width, size_t height, TextureFormat fmt)
: ITextureD(parent), m_width(width), m_height(height), m_fmt(fmt), m_q(q)
{ {
VkFormat pfmt; VkFormat pfmt;
switch (fmt) switch (fmt)
@ -1488,6 +1509,8 @@ public:
TextureFormat format() const {return m_fmt;} TextureFormat format() const {return m_fmt;}
}; };
#define MAX_BIND_TEXS 4
class VulkanTextureR : public ITextureR class VulkanTextureR : public ITextureR
{ {
friend class VulkanDataFactory; friend class VulkanDataFactory;
@ -1496,11 +1519,11 @@ class VulkanTextureR : public ITextureR
size_t m_height = 0; size_t m_height = 0;
size_t m_samples = 0; size_t m_samples = 0;
bool m_enableShaderColorBinding; size_t m_colorBindCount;
bool m_enableShaderDepthBinding; size_t m_depthBindCount;
void Setup(VulkanContext* ctx, size_t width, size_t height, size_t samples, void Setup(VulkanContext* ctx, size_t width, size_t height, size_t samples,
bool enableShaderColorBinding, bool enableShaderDepthBinding) size_t colorBindCount, size_t depthBindCount)
{ {
/* no-ops on first call */ /* no-ops on first call */
doDestroy(); doDestroy();
@ -1529,7 +1552,7 @@ class VulkanTextureR : public ITextureR
/* depth target */ /* depth target */
texCreateInfo.format = VK_FORMAT_D24_UNORM_S8_UINT; texCreateInfo.format = VK_FORMAT_D24_UNORM_S8_UINT;
texCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; texCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_depthTex)); ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_depthTex));
/* tally total memory requirements */ /* tally total memory requirements */
@ -1541,7 +1564,9 @@ class VulkanTextureR : public ITextureR
memAlloc.allocationSize = 0; memAlloc.allocationSize = 0;
uint32_t memTypeBits = ~0; uint32_t memTypeBits = ~0;
VkDeviceSize gpuOffsets[4]; VkDeviceSize gpuOffsets[2];
VkDeviceSize colorOffsets[MAX_BIND_TEXS];
VkDeviceSize depthOffsets[MAX_BIND_TEXS];
vk::GetImageMemoryRequirements(ctx->m_dev, m_colorTex, &memReqs); vk::GetImageMemoryRequirements(ctx->m_dev, m_colorTex, &memReqs);
gpuOffsets[0] = memAlloc.allocationSize; gpuOffsets[0] = memAlloc.allocationSize;
@ -1555,36 +1580,38 @@ class VulkanTextureR : public ITextureR
memAlloc.allocationSize = (memAlloc.allocationSize + memReqs.alignment - 1) & ~(memReqs.alignment - 1); memAlloc.allocationSize = (memAlloc.allocationSize + memReqs.alignment - 1) & ~(memReqs.alignment - 1);
memTypeBits &= memReqs.memoryTypeBits; memTypeBits &= memReqs.memoryTypeBits;
if (enableShaderColorBinding) for (size_t i=0 ; i<colorBindCount ; ++i)
{ {
m_colorBindLayout[i] = VK_IMAGE_LAYOUT_UNDEFINED;
texCreateInfo.format = ctx->m_displayFormat; texCreateInfo.format = ctx->m_displayFormat;
texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_colorBindTex)); ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_colorBindTex[i]));
vk::GetImageMemoryRequirements(ctx->m_dev, m_colorBindTex, &memReqs); vk::GetImageMemoryRequirements(ctx->m_dev, m_colorBindTex[i], &memReqs);
gpuOffsets[2] = memAlloc.allocationSize; colorOffsets[i] = memAlloc.allocationSize;
memAlloc.allocationSize += memReqs.size; memAlloc.allocationSize += memReqs.size;
memAlloc.allocationSize = (memAlloc.allocationSize + memReqs.alignment - 1) & ~(memReqs.alignment - 1); memAlloc.allocationSize = (memAlloc.allocationSize + memReqs.alignment - 1) & ~(memReqs.alignment - 1);
memTypeBits &= memReqs.memoryTypeBits; memTypeBits &= memReqs.memoryTypeBits;
m_colorBindDescInfo.sampler = ctx->m_linearSampler; m_colorBindDescInfo[i].sampler = ctx->m_linearSampler;
m_colorBindDescInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; m_colorBindDescInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
} }
if (enableShaderDepthBinding) for (size_t i=0 ; i<depthBindCount ; ++i)
{ {
m_depthBindLayout[i] = VK_IMAGE_LAYOUT_UNDEFINED;
texCreateInfo.format = VK_FORMAT_D24_UNORM_S8_UINT; texCreateInfo.format = VK_FORMAT_D24_UNORM_S8_UINT;
texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_depthBindTex)); ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_depthBindTex[i]));
vk::GetImageMemoryRequirements(ctx->m_dev, m_depthBindTex, &memReqs); vk::GetImageMemoryRequirements(ctx->m_dev, m_depthBindTex[i], &memReqs);
gpuOffsets[3] = memAlloc.allocationSize; depthOffsets[i] = memAlloc.allocationSize;
memAlloc.allocationSize += memReqs.size; memAlloc.allocationSize += memReqs.size;
memAlloc.allocationSize = (memAlloc.allocationSize + memReqs.alignment - 1) & ~(memReqs.alignment - 1); memAlloc.allocationSize = (memAlloc.allocationSize + memReqs.alignment - 1) & ~(memReqs.alignment - 1);
memTypeBits &= memReqs.memoryTypeBits; memTypeBits &= memReqs.memoryTypeBits;
m_depthBindDescInfo.sampler = ctx->m_linearSampler; m_depthBindDescInfo[i].sampler = ctx->m_linearSampler;
m_depthBindDescInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; m_depthBindDescInfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
} }
ThrowIfFalse(MemoryTypeFromProperties(ctx, memTypeBits, 0, &memAlloc.memoryTypeIndex)); ThrowIfFalse(MemoryTypeFromProperties(ctx, memTypeBits, 0, &memAlloc.memoryTypeIndex));
@ -1624,24 +1651,24 @@ class VulkanTextureR : public ITextureR
viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
ThrowIfFailed(vk::CreateImageView(ctx->m_dev, &viewCreateInfo, nullptr, &m_depthView)); ThrowIfFailed(vk::CreateImageView(ctx->m_dev, &viewCreateInfo, nullptr, &m_depthView));
if (enableShaderColorBinding) for (size_t i=0 ; i<colorBindCount ; ++i)
{ {
ThrowIfFailed(vk::BindImageMemory(ctx->m_dev, m_colorBindTex, m_gpuMem, gpuOffsets[2])); ThrowIfFailed(vk::BindImageMemory(ctx->m_dev, m_colorBindTex[i], m_gpuMem, colorOffsets[i]));
viewCreateInfo.image = m_colorBindTex; viewCreateInfo.image = m_colorBindTex[i];
viewCreateInfo.format = ctx->m_displayFormat; viewCreateInfo.format = ctx->m_displayFormat;
viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
ThrowIfFailed(vk::CreateImageView(ctx->m_dev, &viewCreateInfo, nullptr, &m_colorBindView)); ThrowIfFailed(vk::CreateImageView(ctx->m_dev, &viewCreateInfo, nullptr, &m_colorBindView[i]));
m_colorBindDescInfo.imageView = m_colorBindView; m_colorBindDescInfo[i].imageView = m_colorBindView[i];
} }
if (enableShaderDepthBinding) for (size_t i=0 ; i<depthBindCount ; ++i)
{ {
ThrowIfFailed(vk::BindImageMemory(ctx->m_dev, m_depthBindTex, m_gpuMem, gpuOffsets[3])); ThrowIfFailed(vk::BindImageMemory(ctx->m_dev, m_depthBindTex[i], m_gpuMem, depthOffsets[i]));
viewCreateInfo.image = m_depthBindTex; viewCreateInfo.image = m_depthBindTex[i];
viewCreateInfo.format = VK_FORMAT_D24_UNORM_S8_UINT; viewCreateInfo.format = VK_FORMAT_D24_UNORM_S8_UINT;
viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
ThrowIfFailed(vk::CreateImageView(ctx->m_dev, &viewCreateInfo, nullptr, &m_depthBindView)); ThrowIfFailed(vk::CreateImageView(ctx->m_dev, &viewCreateInfo, nullptr, &m_depthBindView[i]));
m_depthBindDescInfo.imageView = m_depthBindView; m_depthBindDescInfo[i].imageView = m_depthBindView[i];
} }
/* framebuffer */ /* framebuffer */
@ -1670,14 +1697,20 @@ class VulkanTextureR : public ITextureR
} }
VulkanCommandQueue* m_q; VulkanCommandQueue* m_q;
VulkanTextureR(VulkanContext* ctx, VulkanCommandQueue* q, size_t width, size_t height, size_t samples, VulkanTextureR(IGraphicsData* parent, VulkanContext* ctx, VulkanCommandQueue* q,
bool enableShaderColorBinding, bool enableShaderDepthBinding) size_t width, size_t height, size_t samples,
: m_q(q), m_width(width), m_height(height), m_samples(samples), size_t colorBindCount, size_t depthBindCount)
m_enableShaderColorBinding(enableShaderColorBinding), : ITextureR(parent), m_q(q), m_width(width), m_height(height), m_samples(samples),
m_enableShaderDepthBinding(enableShaderDepthBinding) m_colorBindCount(colorBindCount),
m_depthBindCount(depthBindCount)
{ {
if (colorBindCount > MAX_BIND_TEXS)
Log.report(logvisor::Fatal, "too many color bindings for render texture");
if (depthBindCount > MAX_BIND_TEXS)
Log.report(logvisor::Fatal, "too many depth bindings for render texture");
if (samples == 0) m_samples = 1; if (samples == 0) m_samples = 1;
Setup(ctx, width, height, samples, enableShaderColorBinding, enableShaderDepthBinding); Setup(ctx, width, height, samples, colorBindCount, depthBindCount);
} }
public: public:
size_t samples() const {return m_samples;} size_t samples() const {return m_samples;}
@ -1689,18 +1722,20 @@ public:
VkImage m_depthTex = VK_NULL_HANDLE; VkImage m_depthTex = VK_NULL_HANDLE;
VkImageView m_depthView = VK_NULL_HANDLE; VkImageView m_depthView = VK_NULL_HANDLE;
VkImage m_colorBindTex = VK_NULL_HANDLE; VkImage m_colorBindTex[MAX_BIND_TEXS] = {};
VkImageView m_colorBindView = VK_NULL_HANDLE; VkImageView m_colorBindView[MAX_BIND_TEXS] = {};
VkDescriptorImageInfo m_colorBindDescInfo = {}; VkDescriptorImageInfo m_colorBindDescInfo[MAX_BIND_TEXS] = {};
VkImage m_depthBindTex = VK_NULL_HANDLE; VkImage m_depthBindTex[MAX_BIND_TEXS] = {};
VkImageView m_depthBindView = VK_NULL_HANDLE; VkImageView m_depthBindView[MAX_BIND_TEXS] = {};
VkDescriptorImageInfo m_depthBindDescInfo = {}; VkDescriptorImageInfo m_depthBindDescInfo[MAX_BIND_TEXS] = {};
VkFramebuffer m_framebuffer = VK_NULL_HANDLE; VkFramebuffer m_framebuffer = VK_NULL_HANDLE;
VkRenderPassBeginInfo m_passBeginInfo = {}; VkRenderPassBeginInfo m_passBeginInfo = {};
VkImageLayout m_layout = VK_IMAGE_LAYOUT_UNDEFINED; VkImageLayout m_layout = VK_IMAGE_LAYOUT_UNDEFINED;
VkImageLayout m_colorBindLayout[MAX_BIND_TEXS] = {};
VkImageLayout m_depthBindLayout[MAX_BIND_TEXS] = {};
void doDestroy(); void doDestroy();
~VulkanTextureR(); ~VulkanTextureR();
@ -1713,7 +1748,7 @@ public:
height = 1; height = 1;
m_width = width; m_width = width;
m_height = height; m_height = height;
Setup(ctx, width, height, m_samples, m_enableShaderColorBinding, m_enableShaderDepthBinding); Setup(ctx, width, height, m_samples, m_colorBindCount, m_depthBindCount);
} }
}; };
@ -1755,8 +1790,9 @@ struct VulkanVertexFormat : IVertexFormat
size_t m_stride = 0; size_t m_stride = 0;
size_t m_instStride = 0; size_t m_instStride = 0;
VulkanVertexFormat(size_t elementCount, const VertexElementDescriptor* elements) VulkanVertexFormat(IGraphicsData* parent, size_t elementCount,
: m_attributes(new VkVertexInputAttributeDescription[elementCount]) const VertexElementDescriptor* elements)
: IVertexFormat(parent), m_attributes(new VkVertexInputAttributeDescription[elementCount])
{ {
m_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; m_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
m_info.pNext = nullptr; m_info.pNext = nullptr;
@ -1835,14 +1871,16 @@ class VulkanShaderPipeline : public IShaderPipeline
const VulkanVertexFormat* m_vtxFmt; const VulkanVertexFormat* m_vtxFmt;
VulkanShareableShader::Token m_vert; VulkanShareableShader::Token m_vert;
VulkanShareableShader::Token m_frag; VulkanShareableShader::Token m_frag;
VulkanShaderPipeline(VulkanContext* ctx, VulkanShaderPipeline(IGraphicsData* parent,
VulkanContext* ctx,
VulkanShareableShader::Token&& vert, VulkanShareableShader::Token&& vert,
VulkanShareableShader::Token&& frag, VulkanShareableShader::Token&& frag,
VkPipelineCache pipelineCache, VkPipelineCache pipelineCache,
const VulkanVertexFormat* vtxFmt, const VulkanVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, CullMode culling) ZTest depthTest, bool depthWrite, bool colorWrite,
: m_ctx(ctx), m_pipelineCache(pipelineCache), m_vtxFmt(vtxFmt), bool alphaWrite, CullMode culling)
: IShaderPipeline(parent), m_ctx(ctx), m_pipelineCache(pipelineCache), m_vtxFmt(vtxFmt),
m_vert(std::move(vert)), m_frag(std::move(frag)) m_vert(std::move(vert)), m_frag(std::move(frag))
{ {
VkCullModeFlagBits cullMode; VkCullModeFlagBits cullMode;
@ -1925,12 +1963,28 @@ class VulkanShaderPipeline : public IShaderPipeline
depthStencilInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; depthStencilInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencilInfo.pNext = nullptr; depthStencilInfo.pNext = nullptr;
depthStencilInfo.flags = 0; depthStencilInfo.flags = 0;
depthStencilInfo.depthTestEnable = depthTest; depthStencilInfo.depthTestEnable = depthTest != ZTest::None;
depthStencilInfo.depthWriteEnable = depthWrite; depthStencilInfo.depthWriteEnable = depthWrite;
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
depthStencilInfo.front.compareOp = VK_COMPARE_OP_ALWAYS; depthStencilInfo.front.compareOp = VK_COMPARE_OP_ALWAYS;
depthStencilInfo.back.compareOp = VK_COMPARE_OP_ALWAYS; depthStencilInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
switch (depthTest)
{
case ZTest::None:
default:
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_ALWAYS;
break;
case ZTest::LEqual:
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
break;
case ZTest::Greater:
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_GREATER;
break;
case ZTest::Equal:
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_EQUAL;
break;
}
VkPipelineColorBlendAttachmentState colorAttachment = {}; VkPipelineColorBlendAttachmentState colorAttachment = {};
colorAttachment.blendEnable = dstFac != BlendFactor::Zero; colorAttachment.blendEnable = dstFac != BlendFactor::Zero;
colorAttachment.srcColorBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)]; colorAttachment.srcColorBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
@ -1939,7 +1993,11 @@ class VulkanShaderPipeline : public IShaderPipeline
colorAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; colorAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; colorAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
colorAttachment.alphaBlendOp = VK_BLEND_OP_ADD; colorAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
colorAttachment.colorWriteMask = 0xf; colorAttachment.colorWriteMask =
(colorWrite ? (VK_COLOR_COMPONENT_R_BIT |
VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT) : 0) |
(alphaWrite ? VK_COLOR_COMPONENT_A_BIT : 0);
VkPipelineColorBlendStateCreateInfo colorBlendInfo = {}; VkPipelineColorBlendStateCreateInfo colorBlendInfo = {};
colorBlendInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; colorBlendInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
@ -2037,7 +2095,7 @@ static const VkDescriptorBufferInfo* GetBufferGPUResource(const IGraphicsBuffer*
} }
} }
static const VkDescriptorImageInfo* GetTextureGPUResource(const ITexture* tex, int idx) static const VkDescriptorImageInfo* GetTextureGPUResource(const ITexture* tex, int idx, int bindIdx, bool depth)
{ {
switch (tex->type()) switch (tex->type())
{ {
@ -2059,14 +2117,14 @@ static const VkDescriptorImageInfo* GetTextureGPUResource(const ITexture* tex, i
case TextureType::Render: case TextureType::Render:
{ {
const VulkanTextureR* ctex = static_cast<const VulkanTextureR*>(tex); const VulkanTextureR* ctex = static_cast<const VulkanTextureR*>(tex);
return &ctex->m_colorBindDescInfo; return depth ? &ctex->m_depthBindDescInfo[bindIdx] : &ctex->m_colorBindDescInfo[bindIdx];
} }
default: break; default: break;
} }
return nullptr; return nullptr;
} }
struct VulkanShaderDataBinding : IShaderDataBindingPriv<VulkanData> struct VulkanShaderDataBinding : IShaderDataBindingPriv
{ {
VulkanContext* m_ctx; VulkanContext* m_ctx;
VulkanShaderPipeline* m_pipeline; VulkanShaderPipeline* m_pipeline;
@ -2078,7 +2136,13 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv<VulkanData>
std::vector<std::array<VkDescriptorBufferInfo, 2>> m_ubufOffs; std::vector<std::array<VkDescriptorBufferInfo, 2>> m_ubufOffs;
size_t m_texCount; size_t m_texCount;
VkImageView m_knownViewHandles[2][8] = {}; VkImageView m_knownViewHandles[2][8] = {};
std::unique_ptr<ITexture*[]> m_texs; struct BindTex
{
ITexture* tex;
int idx;
bool depth;
};
std::unique_ptr<BindTex[]> m_texs;
VkBuffer m_vboBufs[2][2] = {{},{}}; VkBuffer m_vboBufs[2][2] = {{},{}};
VkDeviceSize m_vboOffs[2][2] = {{},{}}; VkDeviceSize m_vboOffs[2][2] = {{},{}};
@ -2086,7 +2150,7 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv<VulkanData>
VkDeviceSize m_iboOffs[2] = {}; VkDeviceSize m_iboOffs[2] = {};
VkDescriptorPool m_descPool = VK_NULL_HANDLE; VkDescriptorPool m_descPool = VK_NULL_HANDLE;
VkDescriptorSet m_descSets[2]; VkDescriptorSet m_descSets[2] = {};
size_t m_vertOffset; size_t m_vertOffset;
size_t m_instOffset; size_t m_instOffset;
@ -2103,6 +2167,7 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv<VulkanData>
size_t ubufCount, IGraphicsBuffer** ubufs, size_t ubufCount, IGraphicsBuffer** ubufs,
const size_t* ubufOffs, const size_t* ubufSizes, const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, ITexture** texs, size_t texCount, ITexture** texs,
const int* bindIdxs, const bool* depthBinds,
size_t baseVert, size_t baseInst) size_t baseVert, size_t baseInst)
: IShaderDataBindingPriv(d), : IShaderDataBindingPriv(d),
m_ctx(ctx), m_ctx(ctx),
@ -2113,7 +2178,7 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv<VulkanData>
m_ubufCount(ubufCount), m_ubufCount(ubufCount),
m_ubufs(new IGraphicsBuffer*[ubufCount]), m_ubufs(new IGraphicsBuffer*[ubufCount]),
m_texCount(texCount), m_texCount(texCount),
m_texs(new ITexture*[texCount]) m_texs(new BindTex[texCount])
{ {
m_vertOffset = baseVert * m_pipeline->m_vtxFmt->m_stride; m_vertOffset = baseVert * m_pipeline->m_vtxFmt->m_stride;
m_instOffset = baseInst * m_pipeline->m_vtxFmt->m_instStride; m_instOffset = baseInst * m_pipeline->m_vtxFmt->m_instStride;
@ -2141,7 +2206,11 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv<VulkanData>
m_ubufs[i] = ubufs[i]; m_ubufs[i] = ubufs[i];
} }
for (size_t i=0 ; i<texCount ; ++i) for (size_t i=0 ; i<texCount ; ++i)
m_texs[i] = texs[i]; {
m_texs[i].tex = texs[i];
m_texs[i].idx = bindIdxs ? bindIdxs[i] : 0;
m_texs[i].depth = depthBinds ? depthBinds[i] : 0;
}
size_t totalDescs = ubufCount + texCount; size_t totalDescs = ubufCount + texCount;
if (totalDescs > 0) if (totalDescs > 0)
@ -2252,14 +2321,14 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv<VulkanData>
for (size_t i=0 ; i<BOO_GLSL_MAX_TEXTURE_COUNT ; ++i) for (size_t i=0 ; i<BOO_GLSL_MAX_TEXTURE_COUNT ; ++i)
{ {
if (i<m_texCount && m_texs[i]) if (i<m_texCount && m_texs[i].tex)
{ {
writes[totalWrites].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writes[totalWrites].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[totalWrites].pNext = nullptr; writes[totalWrites].pNext = nullptr;
writes[totalWrites].dstSet = m_descSets[b]; writes[totalWrites].dstSet = m_descSets[b];
writes[totalWrites].descriptorCount = 1; writes[totalWrites].descriptorCount = 1;
writes[totalWrites].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; writes[totalWrites].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
writes[totalWrites].pImageInfo = GetTextureGPUResource(m_texs[i], b); writes[totalWrites].pImageInfo = GetTextureGPUResource(m_texs[i].tex, b, m_texs[i].idx, m_texs[i].depth);
writes[totalWrites].dstArrayElement = 0; writes[totalWrites].dstArrayElement = 0;
writes[totalWrites].dstBinding = binding; writes[totalWrites].dstBinding = binding;
m_knownViewHandles[b][i] = writes[totalWrites].pImageInfo->imageView; m_knownViewHandles[b][i] = writes[totalWrites].pImageInfo->imageView;
@ -2290,9 +2359,9 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv<VulkanData>
size_t totalWrites = 0; size_t totalWrites = 0;
for (size_t i=0 ; i<BOO_GLSL_MAX_TEXTURE_COUNT ; ++i) for (size_t i=0 ; i<BOO_GLSL_MAX_TEXTURE_COUNT ; ++i)
{ {
if (i<m_texCount && m_texs[i]) if (i<m_texCount && m_texs[i].tex)
{ {
const VkDescriptorImageInfo* resComp = GetTextureGPUResource(m_texs[i], b); const VkDescriptorImageInfo* resComp = GetTextureGPUResource(m_texs[i].tex, b, m_texs[i].idx, m_texs[i].depth);
if (resComp->imageView != m_knownViewHandles[b][i]) if (resComp->imageView != m_knownViewHandles[b][i])
{ {
writes[totalWrites].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writes[totalWrites].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
@ -2313,7 +2382,9 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv<VulkanData>
vk::UpdateDescriptorSets(m_ctx->m_dev, totalWrites, writes, 0, nullptr); vk::UpdateDescriptorSets(m_ctx->m_dev, totalWrites, writes, 0, nullptr);
vk::CmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->m_pipeline); vk::CmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->m_pipeline);
vk::CmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_ctx->m_pipelinelayout, 0, 1, &m_descSets[b], 0, nullptr); if (m_descSets[b])
vk::CmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_ctx->m_pipelinelayout,
0, 1, &m_descSets[b], 0, nullptr);
if (m_vbuf && m_instVbuf) if (m_vbuf && m_instVbuf)
vk::CmdBindVertexBuffers(cmdBuf, 0, 2, m_vboBufs[b], m_vboOffs[b]); vk::CmdBindVertexBuffers(cmdBuf, 0, 2, m_vboBufs[b], m_vboOffs[b]);
@ -2654,7 +2725,8 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
return true; return true;
} }
void resolveBindTexture(ITextureR* texture, const SWindowRect& rect, bool tlOrigin, bool color, bool depth) void resolveBindTexture(ITextureR* texture, const SWindowRect& rect, bool tlOrigin,
int bindIdx, bool color, bool depth)
{ {
VkCommandBuffer cmdBuf = m_cmdBufs[m_fillBuf]; VkCommandBuffer cmdBuf = m_cmdBufs[m_fillBuf];
VulkanTextureR* ctexture = static_cast<VulkanTextureR*>(texture); VulkanTextureR* ctexture = static_cast<VulkanTextureR*>(texture);
@ -2677,54 +2749,56 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
copyInfo.srcSubresource.baseArrayLayer = 0; copyInfo.srcSubresource.baseArrayLayer = 0;
copyInfo.srcSubresource.layerCount = 1; copyInfo.srcSubresource.layerCount = 1;
if (color && ctexture->m_enableShaderColorBinding) if (color && ctexture->m_colorBindCount)
{ {
if (ctexture == m_boundTarget) if (ctexture == m_boundTarget)
SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT, SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1); VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1);
SetImageLayout(cmdBuf, ctexture->m_colorBindTex, VK_IMAGE_ASPECT_COLOR_BIT, SetImageLayout(cmdBuf, ctexture->m_colorBindTex[bindIdx], VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1); ctexture->m_colorBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
copyInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; copyInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
vk::CmdCopyImage(cmdBuf, vk::CmdCopyImage(cmdBuf,
ctexture->m_colorTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, ctexture->m_colorTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
ctexture->m_colorBindTex, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, ctexture->m_colorBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &copyInfo); 1, &copyInfo);
if (ctexture == m_boundTarget) if (ctexture == m_boundTarget)
SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT, SetImageLayout(cmdBuf, ctexture->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, 1); VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, 1);
SetImageLayout(cmdBuf, ctexture->m_colorBindTex, VK_IMAGE_ASPECT_COLOR_BIT, SetImageLayout(cmdBuf, ctexture->m_colorBindTex[bindIdx], VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1); VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1);
ctexture->m_colorBindLayout[bindIdx] = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
} }
if (depth && ctexture->m_enableShaderDepthBinding) if (depth && ctexture->m_depthBindCount)
{ {
if (ctexture == m_boundTarget) if (ctexture == m_boundTarget)
SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1); VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1);
SetImageLayout(cmdBuf, ctexture->m_depthBindTex, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, SetImageLayout(cmdBuf, ctexture->m_depthBindTex[bindIdx], VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1); ctexture->m_depthBindLayout[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
copyInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; copyInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
vk::CmdCopyImage(cmdBuf, vk::CmdCopyImage(cmdBuf,
ctexture->m_depthTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, ctexture->m_depthTex, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
ctexture->m_depthBindTex, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, ctexture->m_depthBindTex[bindIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &copyInfo); 1, &copyInfo);
if (ctexture == m_boundTarget) if (ctexture == m_boundTarget)
SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, SetImageLayout(cmdBuf, ctexture->m_depthTex, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, 1); VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, 1);
SetImageLayout(cmdBuf, ctexture->m_depthBindTex, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, SetImageLayout(cmdBuf, ctexture->m_depthBindTex[bindIdx], VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1); VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1);
ctexture->m_depthBindLayout[bindIdx] = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
} }
vk::CmdBeginRenderPass(cmdBuf, &m_boundTarget->m_passBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vk::CmdBeginRenderPass(cmdBuf, &m_boundTarget->m_passBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
@ -2777,26 +2851,30 @@ void VulkanTextureR::doDestroy()
vk::DestroyImage(m_q->m_ctx->m_dev, m_depthTex, nullptr); vk::DestroyImage(m_q->m_ctx->m_dev, m_depthTex, nullptr);
m_depthTex = VK_NULL_HANDLE; m_depthTex = VK_NULL_HANDLE;
} }
if (m_colorBindView) for (size_t i=0 ; i<MAX_BIND_TEXS ; ++i)
{ if (m_colorBindView[i])
vk::DestroyImageView(m_q->m_ctx->m_dev, m_colorBindView, nullptr); {
m_colorBindView = VK_NULL_HANDLE; vk::DestroyImageView(m_q->m_ctx->m_dev, m_colorBindView[i], nullptr);
} m_colorBindView[i] = VK_NULL_HANDLE;
if (m_colorBindTex) }
{ for (size_t i=0 ; i<MAX_BIND_TEXS ; ++i)
vk::DestroyImage(m_q->m_ctx->m_dev, m_colorBindTex, nullptr); if (m_colorBindTex[i])
m_colorBindTex = VK_NULL_HANDLE; {
} vk::DestroyImage(m_q->m_ctx->m_dev, m_colorBindTex[i], nullptr);
if (m_depthBindView) m_colorBindTex[i] = VK_NULL_HANDLE;
{ }
vk::DestroyImageView(m_q->m_ctx->m_dev, m_depthBindView, nullptr); for (size_t i=0 ; i<MAX_BIND_TEXS ; ++i)
m_depthBindView = VK_NULL_HANDLE; if (m_depthBindView[i])
} {
if (m_depthBindTex) vk::DestroyImageView(m_q->m_ctx->m_dev, m_depthBindView[i], nullptr);
{ m_depthBindView[i] = VK_NULL_HANDLE;
vk::DestroyImage(m_q->m_ctx->m_dev, m_depthBindTex, nullptr); }
m_depthBindTex = VK_NULL_HANDLE; for (size_t i=0 ; i<MAX_BIND_TEXS ; ++i)
} if (m_depthBindTex[i])
{
vk::DestroyImage(m_q->m_ctx->m_dev, m_depthBindTex[i], nullptr);
m_depthBindTex[i] = VK_NULL_HANDLE;
}
if (m_gpuMem) if (m_gpuMem)
{ {
vk::FreeMemory(m_q->m_ctx->m_dev, m_gpuMem, nullptr); vk::FreeMemory(m_q->m_ctx->m_dev, m_gpuMem, nullptr);
@ -2811,14 +2889,18 @@ VulkanTextureR::~VulkanTextureR()
vk::DestroyImage(m_q->m_ctx->m_dev, m_colorTex, nullptr); vk::DestroyImage(m_q->m_ctx->m_dev, m_colorTex, nullptr);
vk::DestroyImageView(m_q->m_ctx->m_dev, m_depthView, nullptr); vk::DestroyImageView(m_q->m_ctx->m_dev, m_depthView, nullptr);
vk::DestroyImage(m_q->m_ctx->m_dev, m_depthTex, nullptr); vk::DestroyImage(m_q->m_ctx->m_dev, m_depthTex, nullptr);
if (m_colorBindView) for (size_t i=0 ; i<MAX_BIND_TEXS ; ++i)
vk::DestroyImageView(m_q->m_ctx->m_dev, m_colorBindView, nullptr); if (m_colorBindView[i])
if (m_colorBindTex) vk::DestroyImageView(m_q->m_ctx->m_dev, m_colorBindView[i], nullptr);
vk::DestroyImage(m_q->m_ctx->m_dev, m_colorBindTex, nullptr); for (size_t i=0 ; i<MAX_BIND_TEXS ; ++i)
if (m_depthBindView) if (m_colorBindTex[i])
vk::DestroyImageView(m_q->m_ctx->m_dev, m_depthBindView, nullptr); vk::DestroyImage(m_q->m_ctx->m_dev, m_colorBindTex[i], nullptr);
if (m_depthBindTex) for (size_t i=0 ; i<MAX_BIND_TEXS ; ++i)
vk::DestroyImage(m_q->m_ctx->m_dev, m_depthBindTex, nullptr); if (m_depthBindView[i])
vk::DestroyImageView(m_q->m_ctx->m_dev, m_depthBindView[i], nullptr);
for (size_t i=0 ; i<MAX_BIND_TEXS ; ++i)
if (m_depthBindTex[i])
vk::DestroyImage(m_q->m_ctx->m_dev, m_depthBindTex[i], nullptr);
vk::FreeMemory(m_q->m_ctx->m_dev, m_gpuMem, nullptr); vk::FreeMemory(m_q->m_ctx->m_dev, m_gpuMem, nullptr);
if (m_q->m_boundTarget == this) if (m_q->m_boundTarget == this)
m_q->m_boundTarget = nullptr; m_q->m_boundTarget = nullptr;
@ -3081,8 +3163,10 @@ IShaderPipeline* VulkanDataFactory::Context::newShaderPipeline
std::vector<unsigned int>* vertBlobOut, std::vector<unsigned int>* fragBlobOut, std::vector<unsigned int>* vertBlobOut, std::vector<unsigned int>* fragBlobOut,
std::vector<unsigned char>* pipelineBlob, IVertexFormat* vtxFmt, std::vector<unsigned char>* pipelineBlob, IVertexFormat* vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, CullMode culling) ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling)
{ {
VulkanData* d = static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get());
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent); VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
XXH64_state_t hashState; XXH64_state_t hashState;
@ -3208,9 +3292,10 @@ IShaderPipeline* VulkanDataFactory::Context::newShaderPipeline
ThrowIfFailed(vk::CreatePipelineCache(factory.m_ctx->m_dev, &cacheDataInfo, nullptr, &pipelineCache)); ThrowIfFailed(vk::CreatePipelineCache(factory.m_ctx->m_dev, &cacheDataInfo, nullptr, &pipelineCache));
} }
VulkanShaderPipeline* retval = new VulkanShaderPipeline(factory.m_ctx, std::move(vertShader), std::move(fragShader), VulkanShaderPipeline* retval = new VulkanShaderPipeline(d, factory.m_ctx, std::move(vertShader), std::move(fragShader),
pipelineCache, static_cast<const VulkanVertexFormat*>(vtxFmt), pipelineCache, static_cast<const VulkanVertexFormat*>(vtxFmt),
srcFac, dstFac, prim, depthTest, depthWrite, culling); srcFac, dstFac, prim, depthTest, depthWrite, colorWrite,
alphaWrite, culling);
if (pipelineBlob && pipelineBlob->empty()) if (pipelineBlob && pipelineBlob->empty())
{ {
@ -3224,62 +3309,68 @@ IShaderPipeline* VulkanDataFactory::Context::newShaderPipeline
} }
} }
static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get())->m_SPs.emplace_back(retval); d->m_SPs.emplace_back(retval);
return retval; return retval;
} }
IGraphicsBufferS* VulkanDataFactory::Context::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) IGraphicsBufferS* VulkanDataFactory::Context::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
{ {
VulkanData* d = static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get());
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent); VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
VulkanGraphicsBufferS* retval = new VulkanGraphicsBufferS(use, factory.m_ctx, data, stride, count); VulkanGraphicsBufferS* retval = new VulkanGraphicsBufferS(d, use, factory.m_ctx, data, stride, count);
static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get())->m_SBufs.emplace_back(retval); d->m_SBufs.emplace_back(retval);
return retval; return retval;
} }
IGraphicsBufferD* VulkanDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count) IGraphicsBufferD* VulkanDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
{ {
VulkanData* d = static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get());
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent); VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
VulkanCommandQueue* q = static_cast<VulkanCommandQueue*>(factory.m_parent->getCommandQueue()); VulkanCommandQueue* q = static_cast<VulkanCommandQueue*>(factory.m_parent->getCommandQueue());
VulkanGraphicsBufferD* retval = new VulkanGraphicsBufferD(q, use, factory.m_ctx, stride, count); VulkanGraphicsBufferD* retval = new VulkanGraphicsBufferD(d, q, use, factory.m_ctx, stride, count);
static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get())->m_DBufs.emplace_back(retval); d->m_DBufs.emplace_back(retval);
return retval; return retval;
} }
ITextureS* VulkanDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mips, ITextureS* VulkanDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mips,
TextureFormat fmt, const void* data, size_t sz) TextureFormat fmt, const void* data, size_t sz)
{ {
VulkanData* d = static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get());
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent); VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
VulkanTextureS* retval = new VulkanTextureS(factory.m_ctx, width, height, mips, fmt, data, sz); VulkanTextureS* retval = new VulkanTextureS(d, factory.m_ctx, width, height, mips, fmt, data, sz);
static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get())->m_STexs.emplace_back(retval); d->m_STexs.emplace_back(retval);
return retval; return retval;
} }
ITextureSA* VulkanDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips, ITextureSA* VulkanDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
TextureFormat fmt, const void* data, size_t sz) TextureFormat fmt, const void* data, size_t sz)
{ {
VulkanData* d = static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get());
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent); VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
VulkanTextureSA* retval = new VulkanTextureSA(factory.m_ctx, width, height, layers, mips, fmt, data, sz); VulkanTextureSA* retval = new VulkanTextureSA(d, factory.m_ctx, width, height, layers, mips, fmt, data, sz);
static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get())->m_SATexs.emplace_back(retval); d->m_SATexs.emplace_back(retval);
return retval; return retval;
} }
ITextureD* VulkanDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt) ITextureD* VulkanDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
{ {
VulkanData* d = static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get());
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent); VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
VulkanCommandQueue* q = static_cast<VulkanCommandQueue*>(factory.m_parent->getCommandQueue()); VulkanCommandQueue* q = static_cast<VulkanCommandQueue*>(factory.m_parent->getCommandQueue());
VulkanTextureD* retval = new VulkanTextureD(q, factory.m_ctx, width, height, fmt); VulkanTextureD* retval = new VulkanTextureD(d, q, factory.m_ctx, width, height, fmt);
static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get())->m_DTexs.emplace_back(retval); d->m_DTexs.emplace_back(retval);
return retval; return retval;
} }
ITextureR* VulkanDataFactory::Context::newRenderTexture(size_t width, size_t height, ITextureR* VulkanDataFactory::Context::newRenderTexture(size_t width, size_t height,
bool enableShaderColorBinding, bool enableShaderDepthBinding) size_t colorBindCount, size_t depthBindCount)
{ {
VulkanData* d = static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get());
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent); VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
VulkanCommandQueue* q = static_cast<VulkanCommandQueue*>(factory.m_parent->getCommandQueue()); VulkanCommandQueue* q = static_cast<VulkanCommandQueue*>(factory.m_parent->getCommandQueue());
VulkanTextureR* retval = new VulkanTextureR(factory.m_ctx, q, width, height, factory.m_drawSamples, VulkanTextureR* retval = new VulkanTextureR(d, factory.m_ctx, q, width, height, factory.m_drawSamples,
enableShaderColorBinding, enableShaderDepthBinding); colorBindCount, depthBindCount);
static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get())->m_RTexs.emplace_back(retval); d->m_RTexs.emplace_back(retval);
return retval; return retval;
} }
@ -3287,8 +3378,9 @@ IVertexFormat* VulkanDataFactory::Context::newVertexFormat(size_t elementCount,
const VertexElementDescriptor* elements, const VertexElementDescriptor* elements,
size_t baseVert, size_t baseInst) size_t baseVert, size_t baseInst)
{ {
VulkanVertexFormat* retval = new struct VulkanVertexFormat(elementCount, elements); VulkanData* d = static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get());
static_cast<VulkanData*>(VulkanDataFactoryImpl::m_deferredData.get())->m_VFmts.emplace_back(retval); VulkanVertexFormat* retval = new struct VulkanVertexFormat(d, elementCount, elements);
d->m_VFmts.emplace_back(retval);
return retval; return retval;
} }
@ -3298,6 +3390,7 @@ IShaderDataBinding* VulkanDataFactory::Context::newShaderDataBinding(IShaderPipe
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* /*ubufStages*/, size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* /*ubufStages*/,
const size_t* ubufOffs, const size_t* ubufSizes, const size_t* ubufOffs, const size_t* ubufSizes,
size_t texCount, ITexture** texs, size_t texCount, ITexture** texs,
const int* bindIdxs, const bool* bindDepth,
size_t baseVert, size_t baseInst) size_t baseVert, size_t baseInst)
{ {
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent); VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
@ -3305,7 +3398,7 @@ IShaderDataBinding* VulkanDataFactory::Context::newShaderDataBinding(IShaderPipe
VulkanShaderDataBinding* retval = VulkanShaderDataBinding* retval =
new VulkanShaderDataBinding(d, factory.m_ctx, pipeline, vbuf, instVbuf, ibuf, new VulkanShaderDataBinding(d, factory.m_ctx, pipeline, vbuf, instVbuf, ibuf,
ubufCount, ubufs, ubufOffs, ubufSizes, texCount, texs, ubufCount, ubufs, ubufOffs, ubufSizes, texCount, texs,
baseVert, baseInst); bindIdxs, bindDepth, baseVert, baseInst);
d->m_SBinds.emplace_back(retval); d->m_SBinds.emplace_back(retval);
return retval; return retval;
} }
@ -3436,16 +3529,17 @@ GraphicsDataToken VulkanDataFactoryImpl::commitTransaction
IGraphicsBufferD* VulkanDataFactoryImpl::newPoolBuffer(IGraphicsBufferPool* p, BufferUse use, IGraphicsBufferD* VulkanDataFactoryImpl::newPoolBuffer(IGraphicsBufferPool* p, BufferUse use,
size_t stride, size_t count) size_t stride, size_t count)
{ {
VulkanPool* pool = static_cast<VulkanPool*>(p);
VulkanCommandQueue* q = static_cast<VulkanCommandQueue*>(m_parent->getCommandQueue()); VulkanCommandQueue* q = static_cast<VulkanCommandQueue*>(m_parent->getCommandQueue());
VulkanGraphicsBufferD* retval = new VulkanGraphicsBufferD(q, use, m_ctx, stride, count); VulkanPool* pool = static_cast<VulkanPool*>(p);
VulkanPoolItem* item = new VulkanPoolItem(m_ctx);
VulkanGraphicsBufferD* retval = new VulkanGraphicsBufferD(item, q, use, m_ctx, stride, count);
item->m_buf.reset(retval);
/* size up resources */ /* size up resources */
uint32_t bufMemTypeBits = ~0; uint32_t bufMemTypeBits = ~0;
VkDeviceSize bufMemSize = retval->sizeForGPU(m_ctx, bufMemTypeBits, 0); VkDeviceSize bufMemSize = retval->sizeForGPU(m_ctx, bufMemTypeBits, 0);
/* allocate memory */ /* allocate memory */
VkDeviceMemory bufMem = VK_NULL_HANDLE;
if (bufMemSize) if (bufMemSize)
{ {
VkMemoryAllocateInfo memAlloc = {}; VkMemoryAllocateInfo memAlloc = {};
@ -3455,28 +3549,28 @@ IGraphicsBufferD* VulkanDataFactoryImpl::newPoolBuffer(IGraphicsBufferPool* p, B
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
&memAlloc.memoryTypeIndex)); &memAlloc.memoryTypeIndex));
ThrowIfFailed(vk::AllocateMemory(m_ctx->m_dev, &memAlloc, nullptr, &bufMem)); ThrowIfFailed(vk::AllocateMemory(m_ctx->m_dev, &memAlloc, nullptr, &item->m_bufMem));
/* place resources */ /* place resources */
retval->placeForGPU(m_ctx, bufMem); retval->placeForGPU(m_ctx, item->m_bufMem);
} }
pool->m_DBufs.emplace(std::make_pair(retval, VulkanPool::Buffer{bufMem, retval})); pool->m_items.emplace(item);
return retval; return retval;
} }
void VulkanDataFactoryImpl::deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf) void VulkanDataFactoryImpl::deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf)
{ {
VulkanPool* pool = static_cast<VulkanPool*>(p); VulkanPool* pool = static_cast<VulkanPool*>(p);
auto search = pool->m_DBufs.find(static_cast<VulkanGraphicsBufferD*>(buf)); auto search = pool->m_items.find(static_cast<VulkanPoolItem*>(buf->m_parentData));
if (search != pool->m_DBufs.end()) if (search != pool->m_items.end())
search->second.m_dead = true; (*search)->m_dead = true;
} }
GraphicsBufferPoolToken VulkanDataFactoryImpl::newBufferPool() GraphicsBufferPoolToken VulkanDataFactoryImpl::newBufferPool()
{ {
std::unique_lock<std::mutex> lk(m_committedMutex); std::unique_lock<std::mutex> lk(m_committedMutex);
VulkanPool* retval = new VulkanPool(m_ctx); VulkanPool* retval = new VulkanPool;
m_committedPools.insert(retval); m_committedPools.insert(retval);
return GraphicsBufferPoolToken(this, retval); return GraphicsBufferPoolToken(this, retval);
} }
@ -3500,8 +3594,8 @@ void VulkanCommandQueue::execute()
} }
for (VulkanPool* p : gfxF->m_committedPools) for (VulkanPool* p : gfxF->m_committedPools)
{ {
for (auto& b : p->m_DBufs) for (auto& b : p->m_items)
b.second.m_buffer->update(m_fillBuf); b->m_buf->update(m_fillBuf);
} }
datalk.unlock(); datalk.unlock();

View File

@ -308,7 +308,8 @@ struct TestApplicationCallback : IApplicationCallback
pipeline = glF.newShaderPipeline(VS, FS, 1, &texName, 0, nullptr, pipeline = glF.newShaderPipeline(VS, FS, 1, &texName, 0, nullptr,
BlendFactor::One, BlendFactor::Zero, BlendFactor::One, BlendFactor::Zero,
Primitive::TriStrips, boo::ZTest::LEqual, true, true, false, CullMode::None); Primitive::TriStrips, boo::ZTest::LEqual,
true, true, false, CullMode::None);
} }
#if BOO_HAS_VULKAN #if BOO_HAS_VULKAN
else if (plat == IGraphicsDataFactory::Platform::Vulkan) else if (plat == IGraphicsDataFactory::Platform::Vulkan)
@ -340,7 +341,8 @@ struct TestApplicationCallback : IApplicationCallback
"}\n"; "}\n";
pipeline = vkF.newShaderPipeline(VS, FS, vfmt, BlendFactor::One, BlendFactor::Zero, pipeline = vkF.newShaderPipeline(VS, FS, vfmt, BlendFactor::One, BlendFactor::Zero,
Primitive::TriStrips, true, true, CullMode::None); Primitive::TriStrips, boo::ZTest::LEqual,
true, true, false, CullMode::None);
} }
#endif #endif
#if _WIN32 #if _WIN32
@ -370,8 +372,9 @@ struct TestApplicationCallback : IApplicationCallback
"}\n"; "}\n";
pipeline = d3dF.newShaderPipeline(VS, PS, nullptr, nullptr, nullptr, vfmt, pipeline = d3dF.newShaderPipeline(VS, PS, nullptr, nullptr, nullptr, vfmt,
BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips, BlendFactor::One, BlendFactor::Zero,
true, true, CullMode::None); Primitive::TriStrips, boo::ZTest::LEqual,
true, true, false, CullMode::None);
} }
#elif BOO_HAS_METAL #elif BOO_HAS_METAL
else if (plat == IGraphicsDataFactory::Platform::Metal) else if (plat == IGraphicsDataFactory::Platform::Metal)