graphics device refactors

This commit is contained in:
Turanszki Janos
2021-09-15 16:51:22 +02:00
parent 64ef9aa26b
commit 359497497d
6 changed files with 161 additions and 195 deletions
+24 -10
View File
@@ -8,22 +8,36 @@
namespace wiGraphics
{
// CommandList can be used to record graphics commands from a CPU thread
// Use GraphicsDevice::BeginCommandList() to start a command list
// Use GraphicsDevice::SubmitCommandLists() to give all started command lists to the GPU for execution
// CommandList recording is not thread safe
typedef uint8_t CommandList;
static const CommandList COMMANDLIST_COUNT = 32;
static const CommandList COMMANDLIST_COUNT = 32; // If you increase command list count, more memory will be statically allocated for per-command list resources
static const CommandList INVALID_COMMANDLIST = COMMANDLIST_COUNT;
// Descriptor binding counts:
// It's OK increase these limits if not enough
// But it's better to refactor shaders to use bindless descriptors if they require more resources
static const uint32_t DESCRIPTORBINDER_CBV_COUNT = 15;
static const uint32_t DESCRIPTORBINDER_SRV_COUNT = 64;
static const uint32_t DESCRIPTORBINDER_UAV_COUNT = 16;
static const uint32_t DESCRIPTORBINDER_SAMPLER_COUNT = 16;
struct DescriptorBindingTable
{
GPUBuffer CBV[DESCRIPTORBINDER_CBV_COUNT];
uint64_t CBV_offset[DESCRIPTORBINDER_CBV_COUNT] = {};
GPUResource SRV[DESCRIPTORBINDER_SRV_COUNT];
int SRV_index[DESCRIPTORBINDER_SRV_COUNT] = {};
GPUResource UAV[DESCRIPTORBINDER_UAV_COUNT];
int UAV_index[DESCRIPTORBINDER_UAV_COUNT] = {};
Sampler SAM[DESCRIPTORBINDER_SAMPLER_COUNT];
};
constexpr uint32_t AlignTo(uint32_t value, uint32_t alignment)
{
return ((value + alignment - 1) / alignment) * alignment;
}
constexpr uint64_t AlignTo(uint64_t value, uint64_t alignment)
{
return ((value + alignment - 1) / alignment) * alignment;
@@ -67,8 +81,8 @@ namespace wiGraphics
virtual int CreateSubresource(Texture* texture, SUBRESOURCE_TYPE type, uint32_t firstSlice, uint32_t sliceCount, uint32_t firstMip, uint32_t mipCount) const = 0;
virtual int CreateSubresource(GPUBuffer* buffer, SUBRESOURCE_TYPE type, uint64_t offset, uint64_t size = ~0) const = 0;
virtual int GetDescriptorIndex(const GPUResource* resource, SUBRESOURCE_TYPE type, int subresource = -1) const { return -1; };
virtual int GetDescriptorIndex(const Sampler* sampler) const { return -1; };
virtual int GetDescriptorIndex(const GPUResource* resource, SUBRESOURCE_TYPE type, int subresource = -1) const = 0;
virtual int GetDescriptorIndex(const Sampler* sampler) const = 0;
virtual void WriteShadingRateValue(SHADING_RATE rate, void* dest) const {};
virtual void WriteTopLevelAccelerationStructureInstance(const RaytracingAccelerationStructureDesc::TopLevel::Instance* instance, void* dest) const {}
@@ -86,7 +100,7 @@ namespace wiGraphics
virtual void SubmitCommandLists() = 0;
virtual void WaitForGPU() const = 0;
virtual void ClearPipelineStateCache() {};
virtual void ClearPipelineStateCache() = 0;
constexpr uint64_t GetFrameCount() const { return FRAMECOUNT; }
@@ -107,13 +121,13 @@ namespace wiGraphics
constexpr uint32_t GetVariableRateShadingTileSize() const { return VARIABLE_RATE_SHADING_TILE_SIZE; }
constexpr uint64_t GetTimestampFrequency() const { return TIMESTAMP_FREQUENCY; }
virtual SHADERFORMAT GetShaderFormat() const { return SHADERFORMAT_NONE; }
virtual SHADERFORMAT GetShaderFormat() const = 0;
virtual Texture GetBackBuffer(const SwapChain* swapchain) const = 0;
///////////////Thread-sensitive////////////////////////
virtual void WaitCommandList(CommandList cmd, CommandList wait_for) {}
virtual void WaitCommandList(CommandList cmd, CommandList wait_for) = 0;
virtual void RenderPassBegin(const SwapChain* swapchain, CommandList cmd) = 0;
virtual void RenderPassBegin(const RenderPass* renderpass, CommandList cmd) = 0;
virtual void RenderPassEnd(CommandList cmd) = 0;
@@ -146,13 +160,13 @@ namespace wiGraphics
virtual void CopyBuffer(const GPUBuffer* pDst, uint64_t dst_offset, const GPUBuffer* pSrc, uint64_t src_offset, uint64_t size, CommandList cmd) = 0;
virtual void QueryBegin(const GPUQueryHeap *heap, uint32_t index, CommandList cmd) = 0;
virtual void QueryEnd(const GPUQueryHeap *heap, uint32_t index, CommandList cmd) = 0;
virtual void QueryResolve(const GPUQueryHeap* heap, uint32_t index, uint32_t count, const GPUBuffer* dest, uint64_t dest_offset, CommandList cmd) {}
virtual void QueryResolve(const GPUQueryHeap* heap, uint32_t index, uint32_t count, const GPUBuffer* dest, uint64_t dest_offset, CommandList cmd) = 0;
virtual void QueryReset(const GPUQueryHeap* heap, uint32_t index, uint32_t count, CommandList cmd) {}
virtual void Barrier(const GPUBarrier* barriers, uint32_t numBarriers, CommandList cmd) = 0;
virtual void BuildRaytracingAccelerationStructure(const RaytracingAccelerationStructure* dst, CommandList cmd, const RaytracingAccelerationStructure* src = nullptr) {}
virtual void BindRaytracingPipelineState(const RaytracingPipelineState* rtpso, CommandList cmd) {}
virtual void DispatchRays(const DispatchRaysDesc* desc, CommandList cmd) {}
virtual void PushConstants(const void* data, uint32_t size, CommandList cmd) {}
virtual void PushConstants(const void* data, uint32_t size, CommandList cmd) = 0;
virtual void EventBegin(const char* name, CommandList cmd) = 0;
virtual void EventEnd(CommandList cmd) = 0;
@@ -160,7 +174,6 @@ namespace wiGraphics
// Some useful helpers:
struct GPULinearAllocator
@@ -179,6 +192,7 @@ namespace wiGraphics
// Returns true if the allocation was successful
inline bool IsValid() const { return data != nullptr && buffer.IsValid(); }
};
// Allocates temporary memory that the CPU can write and GPU can read.
// It is only alive for one frame and automatically invalidated after that.
GPUAllocation AllocateGPU(uint64_t dataSize, CommandList cmd)
+40 -64
View File
@@ -1622,39 +1622,11 @@ using namespace DX12_Internal;
}
void GraphicsDevice_DX12::DescriptorBinder::reset()
{
table = {};
dirty_res = true;
dirty_sam = true;
ringOffset_res = 0;
ringOffset_sam = 0;
for (int i = 0; i < arraysize(CBV); ++i)
{
CBV[i] = {};
}
for (int i = 0; i < arraysize(CBV_offset); ++i)
{
CBV_offset[i] = {};
}
for (int i = 0; i < arraysize(SRV); ++i)
{
SRV[i] = {};
}
for (int i = 0; i < arraysize(SRV_index); ++i)
{
SRV_index[i] = {};
}
for (int i = 0; i < arraysize(UAV); ++i)
{
UAV[i] = {};
}
for (int i = 0; i < arraysize(UAV_index); ++i)
{
UAV_index[i] = {};
}
for (int i = 0; i < arraysize(SAM); ++i)
{
SAM[i] = {};
}
}
void GraphicsDevice_DX12::DescriptorBinder::flush(bool graphics, CommandList cmd)
{
@@ -1673,8 +1645,8 @@ using namespace DX12_Internal;
continue;
}
const GPUBuffer& buffer = CBV[x.ShaderRegister];
uint64_t offset = CBV_offset[x.ShaderRegister];
const GPUBuffer& buffer = table.CBV[x.ShaderRegister];
uint64_t offset = table.CBV_offset[x.ShaderRegister];
D3D12_GPU_VIRTUAL_ADDRESS address;
@@ -1774,8 +1746,8 @@ using namespace DX12_Internal;
default:
case D3D12_DESCRIPTOR_RANGE_TYPE_SRV:
{
const GPUResource& resource = SRV[ShaderRegister];
const int subresource = SRV_index[ShaderRegister];
const GPUResource& resource = table.SRV[ShaderRegister];
const int subresource = table.SRV_index[ShaderRegister];
if (!resource.IsValid())
{
switch (binding)
@@ -1839,8 +1811,8 @@ using namespace DX12_Internal;
case D3D12_DESCRIPTOR_RANGE_TYPE_UAV:
{
const GPUResource& resource = UAV[ShaderRegister];
const int subresource = UAV_index[ShaderRegister];
const GPUResource& resource = table.UAV[ShaderRegister];
const int subresource = table.UAV_index[ShaderRegister];
if (!resource.IsValid())
{
switch (binding)
@@ -1888,8 +1860,8 @@ using namespace DX12_Internal;
case D3D12_DESCRIPTOR_RANGE_TYPE_CBV:
{
const GPUBuffer& buffer = CBV[ShaderRegister];
uint64_t offset = CBV_offset[ShaderRegister];
const GPUBuffer& buffer = table.CBV[ShaderRegister];
uint64_t offset = table.CBV_offset[ShaderRegister];
if (!buffer.IsValid())
{
@@ -1964,7 +1936,7 @@ using namespace DX12_Internal;
UINT ShaderRegister = x.BaseShaderRegister + descriptor_index;
const Sampler& sampler = SAM[ShaderRegister];
const Sampler& sampler = table.SAM[ShaderRegister];
if (!sampler.IsValid())
{
device->device->CopyDescriptorsSimple(1, dst, device->nullSAM, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
@@ -2122,7 +2094,7 @@ using namespace DX12_Internal;
{
pso_validate(cmd);
descriptors[cmd].flush(true, cmd);
binders[cmd].flush(true, cmd);
auto pso_internal = to_internal(active_pso[cmd]);
if (pso_internal->rootconstants.Constants.Num32BitValues > 0)
@@ -2137,7 +2109,7 @@ using namespace DX12_Internal;
}
void GraphicsDevice_DX12::predispatch(CommandList cmd)
{
descriptors[cmd].flush(false, cmd);
binders[cmd].flush(false, cmd);
auto cs_internal = to_internal(active_cs[cmd]);
if (cs_internal->rootconstants.Constants.Num32BitValues > 0)
@@ -5354,7 +5326,7 @@ using namespace DX12_Internal;
wss << "cmd" << cmd;
commandLists[cmd][queue]->SetName(wss.str().c_str());
descriptors[cmd].init(this);
binders[cmd].init(this);
}
// Start the command list in a default state:
@@ -5369,7 +5341,7 @@ using namespace DX12_Internal;
};
GetCommandList(cmd)->SetDescriptorHeaps(arraysize(heaps), heaps);
descriptors[cmd].reset();
binders[cmd].reset();
if (queue == QUEUE_GRAPHICS)
{
@@ -5716,11 +5688,12 @@ using namespace DX12_Internal;
void GraphicsDevice_DX12::BindResource(const GPUResource* resource, uint32_t slot, CommandList cmd, int subresource)
{
assert(slot < DESCRIPTORBINDER_SRV_COUNT);
if (descriptors[cmd].SRV[slot].internal_state != resource->internal_state || descriptors[cmd].SRV_index[slot] != subresource)
auto& binder = binders[cmd];
if (binder.table.SRV[slot].internal_state != resource->internal_state || binder.table.SRV_index[slot] != subresource)
{
descriptors[cmd].SRV[slot] = *resource;
descriptors[cmd].SRV_index[slot] = subresource;
descriptors[cmd].dirty_res = true;
binder.table.SRV[slot] = *resource;
binder.table.SRV_index[slot] = subresource;
binder.dirty_res = true;
}
}
void GraphicsDevice_DX12::BindResources(const GPUResource* const* resources, uint32_t slot, uint32_t count, CommandList cmd)
@@ -5736,11 +5709,12 @@ using namespace DX12_Internal;
void GraphicsDevice_DX12::BindUAV(const GPUResource* resource, uint32_t slot, CommandList cmd, int subresource)
{
assert(slot < DESCRIPTORBINDER_UAV_COUNT);
if (descriptors[cmd].UAV[slot].internal_state != resource->internal_state || descriptors[cmd].UAV_index[slot] != subresource)
auto& binder = binders[cmd];
if (binder.table.UAV[slot].internal_state != resource->internal_state || binder.table.UAV_index[slot] != subresource)
{
descriptors[cmd].UAV[slot] = *resource;
descriptors[cmd].UAV_index[slot] = subresource;
descriptors[cmd].dirty_res = true;
binder.table.UAV[slot] = *resource;
binder.table.UAV_index[slot] = subresource;
binder.dirty_res = true;
}
}
void GraphicsDevice_DX12::BindUAVs(const GPUResource* const* resources, uint32_t slot, uint32_t count, CommandList cmd)
@@ -5756,20 +5730,22 @@ using namespace DX12_Internal;
void GraphicsDevice_DX12::BindSampler(const Sampler* sampler, uint32_t slot, CommandList cmd)
{
assert(slot < DESCRIPTORBINDER_SAMPLER_COUNT);
if (descriptors[cmd].SAM[slot].internal_state != sampler->internal_state)
auto& binder = binders[cmd];
if (binder.table.SAM[slot].internal_state != sampler->internal_state)
{
descriptors[cmd].SAM[slot] = *sampler;
descriptors[cmd].dirty_sam = true;
binder.table.SAM[slot] = *sampler;
binder.dirty_sam = true;
}
}
void GraphicsDevice_DX12::BindConstantBuffer(const GPUBuffer* buffer, uint32_t slot, CommandList cmd, uint64_t offset)
{
assert(slot < DESCRIPTORBINDER_CBV_COUNT);
if (descriptors[cmd].CBV[slot].internal_state != buffer->internal_state || descriptors[cmd].CBV_offset[slot] != offset)
auto& binder = binders[cmd];
if (binder.table.CBV[slot].internal_state != buffer->internal_state || binder.table.CBV_offset[slot] != offset)
{
descriptors[cmd].CBV[slot] = *buffer;
descriptors[cmd].CBV_offset[slot] = offset;
descriptors[cmd].dirty_res = true;
binder.table.CBV[slot] = *buffer;
binder.table.CBV_offset[slot] = offset;
binder.dirty_res = true;
// Root constant buffer root signature state tracking:
auto internal_state = to_internal(buffer);
@@ -5784,7 +5760,7 @@ using namespace DX12_Internal;
// CBV flag marked as bound for this slot:
// Also, the corresponding slot is marked dirty
internal_state->cbv_mask[cmd] |= 1 << slot;
descriptors[cmd].dirty_root_cbvs |= 1 << slot;
binder.dirty_root_cbvs |= 1 << slot;
}
}
void GraphicsDevice_DX12::BindVertexBuffers(const GPUBuffer* const* vertexBuffers, uint32_t slot, uint32_t count, const uint32_t* strides, const uint64_t* offsets, CommandList cmd)
@@ -5871,9 +5847,9 @@ using namespace DX12_Internal;
GetCommandList(cmd)->SetGraphicsRootSignature(internal_state->rootSignature.Get());
// Invalidate graphics root bindings:
descriptors[cmd].dirty_res = true;
descriptors[cmd].dirty_sam = true;
descriptors[cmd].dirty_root_cbvs = ~0;
binders[cmd].dirty_res = true;
binders[cmd].dirty_sam = true;
binders[cmd].dirty_root_cbvs = ~0;
// Set the bindless tables:
uint32_t bindpoint = internal_state->bindpoint_bindless;
@@ -5915,9 +5891,9 @@ using namespace DX12_Internal;
GetCommandList(cmd)->SetComputeRootSignature(internal_state->rootSignature.Get());
// Invalidate compute root bindings:
descriptors[cmd].dirty_res = true;
descriptors[cmd].dirty_sam = true;
descriptors[cmd].dirty_root_cbvs = ~0;
binders[cmd].dirty_res = true;
binders[cmd].dirty_sam = true;
binders[cmd].dirty_root_cbvs = ~0;
// Set the bindless tables:
uint32_t bindpoint = internal_state->bindpoint_bindless;
+2 -10
View File
@@ -119,20 +119,12 @@ namespace wiGraphics
struct DescriptorBinder
{
DescriptorBindingTable table;
GraphicsDevice_DX12* device = nullptr;
uint32_t ringOffset_res = 0;
uint32_t ringOffset_sam = 0;
bool dirty_res = false;
bool dirty_sam = false;
GPUBuffer CBV[DESCRIPTORBINDER_CBV_COUNT];
uint64_t CBV_offset[DESCRIPTORBINDER_CBV_COUNT];
GPUResource SRV[DESCRIPTORBINDER_SRV_COUNT];
int SRV_index[DESCRIPTORBINDER_SRV_COUNT];
GPUResource UAV[DESCRIPTORBINDER_UAV_COUNT];
int UAV_index[DESCRIPTORBINDER_UAV_COUNT];
Sampler SAM[DESCRIPTORBINDER_SAMPLER_COUNT];
uint32_t dirty_root_cbvs = 0; // bitmask
struct DescriptorHandles
@@ -145,7 +137,7 @@ namespace wiGraphics
void reset();
void flush(bool graphics, CommandList cmd);
};
DescriptorBinder descriptors[COMMANDLIST_COUNT];
DescriptorBinder binders[COMMANDLIST_COUNT];
std::vector<D3D12_RESOURCE_BARRIER> frame_barriers[COMMANDLIST_COUNT];
+74 -91
View File
@@ -1134,17 +1134,10 @@ using namespace Vulkan_Internal;
return value;
}
void GraphicsDevice_Vulkan::FrameResources::DescriptorBinder::init(GraphicsDevice_Vulkan* device)
void GraphicsDevice_Vulkan::FrameResources::DescriptorBinderPool::init(GraphicsDevice_Vulkan* device)
{
this->device = device;
// Important that these don't reallocate themselves during writing descriptors!
descriptorWrites.reserve(128);
bufferInfos.reserve(128);
imageInfos.reserve(128);
texelBufferViews.reserve(128);
accelerationStructureViews.reserve(128);
VkResult res;
// Create descriptor pool:
@@ -1204,7 +1197,7 @@ using namespace Vulkan_Internal;
// This is because init can be called mid-frame when there is allocation error, but the bindings must be retained!
}
void GraphicsDevice_Vulkan::FrameResources::DescriptorBinder::destroy()
void GraphicsDevice_Vulkan::FrameResources::DescriptorBinderPool::destroy()
{
if (descriptorPool != VK_NULL_HANDLE)
{
@@ -1214,51 +1207,38 @@ using namespace Vulkan_Internal;
device->allocationhandler->destroylocker.unlock();
}
}
void GraphicsDevice_Vulkan::FrameResources::DescriptorBinder::reset()
void GraphicsDevice_Vulkan::FrameResources::DescriptorBinderPool::reset()
{
dirty = true;
if (descriptorPool != VK_NULL_HANDLE)
{
VkResult res = vkResetDescriptorPool(device->device, descriptorPool, 0);
assert(res == VK_SUCCESS);
}
for (int i = 0; i < arraysize(CBV); ++i)
{
CBV[i] = {};
}
for (int i = 0; i < arraysize(CBV_offset); ++i)
{
CBV_offset[i] = {};
}
for (int i = 0; i < arraysize(SRV); ++i)
{
SRV[i] = {};
}
for (int i = 0; i < arraysize(SRV_index); ++i)
{
SRV_index[i] = {};
}
for (int i = 0; i < arraysize(UAV); ++i)
{
UAV[i] = {};
}
for (int i = 0; i < arraysize(UAV_index); ++i)
{
UAV_index[i] = {};
}
for (int i = 0; i < arraysize(SAM); ++i)
{
SAM[i] = {};
}
}
void GraphicsDevice_Vulkan::FrameResources::DescriptorBinder::flush(bool graphics, CommandList cmd)
void GraphicsDevice_Vulkan::DescriptorBinder::init(GraphicsDevice_Vulkan* device)
{
this->device = device;
// Important that these don't reallocate themselves during writing descriptors!
descriptorWrites.reserve(128);
bufferInfos.reserve(128);
imageInfos.reserve(128);
texelBufferViews.reserve(128);
accelerationStructureViews.reserve(128);
}
void GraphicsDevice_Vulkan::DescriptorBinder::reset()
{
table = {};
dirty = true;
}
void GraphicsDevice_Vulkan::DescriptorBinder::flush(bool graphics, CommandList cmd)
{
if (!dirty)
return;
dirty = false;
auto& binder_pool = device->GetFrameResources().binder_pools[cmd];
auto pso_internal = graphics ? to_internal(device->active_pso[cmd]) : nullptr;
auto cs_internal = graphics ? nullptr : to_internal(device->active_cs[cmd]);
@@ -1277,7 +1257,7 @@ using namespace Vulkan_Internal;
VkDescriptorSetAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = descriptorPool;
allocInfo.descriptorPool = binder_pool.descriptorPool;
allocInfo.descriptorSetCount = 1;
allocInfo.pSetLayouts = &descriptorSetLayout;
@@ -1285,10 +1265,10 @@ using namespace Vulkan_Internal;
VkResult res = vkAllocateDescriptorSets(device->device, &allocInfo, &descriptorSet);
while (res == VK_ERROR_OUT_OF_POOL_MEMORY)
{
poolSize *= 2;
destroy();
init(device);
allocInfo.descriptorPool = descriptorPool;
binder_pool.poolSize *= 2;
binder_pool.destroy();
binder_pool.init(device);
allocInfo.descriptorPool = binder_pool.descriptorPool;
res = vkAllocateDescriptorSets(device->device, &allocInfo, &descriptorSet);
}
assert(res == VK_SUCCESS);
@@ -1337,7 +1317,7 @@ using namespace Vulkan_Internal;
imageInfos.back() = {};
const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_S;
const Sampler& sampler = SAM[original_binding];
const Sampler& sampler = table.SAM[original_binding];
if (!sampler.IsValid())
{
imageInfos.back().sampler = device->nullSampler;
@@ -1356,7 +1336,7 @@ using namespace Vulkan_Internal;
imageInfos.back() = {};
const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_T;
const GPUResource& resource = SRV[original_binding];
const GPUResource& resource = table.SRV[original_binding];
if (!resource.IsValid() || !resource.IsTexture())
{
switch (viewtype)
@@ -1391,7 +1371,7 @@ using namespace Vulkan_Internal;
}
else
{
int subresource = SRV_index[original_binding];
int subresource = table.SRV_index[original_binding];
auto texture_internal = to_internal((const Texture*)&resource);
if (subresource >= 0)
{
@@ -1415,7 +1395,7 @@ using namespace Vulkan_Internal;
imageInfos.back().imageLayout = VK_IMAGE_LAYOUT_GENERAL;
const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_U;
const GPUResource& resource = UAV[original_binding];
const GPUResource& resource = table.UAV[original_binding];
if (!resource.IsValid() || !resource.IsTexture())
{
switch (viewtype)
@@ -1449,7 +1429,7 @@ using namespace Vulkan_Internal;
}
else
{
int subresource = UAV_index[original_binding];
int subresource = table.UAV_index[original_binding];
auto texture_internal = to_internal((const Texture*)&resource);
if (subresource >= 0)
{
@@ -1470,8 +1450,8 @@ using namespace Vulkan_Internal;
bufferInfos.back() = {};
const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_B;
const GPUBuffer& buffer = CBV[original_binding];
uint64_t offset = CBV_offset[original_binding];
const GPUBuffer& buffer = table.CBV[original_binding];
uint64_t offset = table.CBV_offset[original_binding];
if (!buffer.IsValid())
{
@@ -1495,14 +1475,14 @@ using namespace Vulkan_Internal;
texelBufferViews.back() = {};
const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_T;
const GPUResource& resource = SRV[original_binding];
const GPUResource& resource = table.SRV[original_binding];
if (!resource.IsValid() || !resource.IsBuffer())
{
texelBufferViews.back() = device->nullBufferView;
}
else
{
int subresource = SRV_index[original_binding];
int subresource = table.SRV_index[original_binding];
auto buffer_internal = to_internal((const GPUBuffer*)&resource);
if (subresource >= 0)
{
@@ -1523,14 +1503,14 @@ using namespace Vulkan_Internal;
texelBufferViews.back() = {};
const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_U;
const GPUResource& resource = UAV[original_binding];
const GPUResource& resource = table.UAV[original_binding];
if (!resource.IsValid() || !resource.IsBuffer())
{
texelBufferViews.back() = device->nullBufferView;
}
else
{
int subresource = UAV_index[original_binding];
int subresource = table.UAV_index[original_binding];
auto buffer_internal = to_internal((const GPUBuffer*)&resource);
if (subresource >= 0)
{
@@ -1554,7 +1534,7 @@ using namespace Vulkan_Internal;
{
// SRV
const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_T;
const GPUResource& resource = SRV[original_binding];
const GPUResource& resource = table.SRV[original_binding];
if (!resource.IsValid() || !resource.IsBuffer())
{
bufferInfos.back().buffer = device->nullBuffer;
@@ -1562,7 +1542,7 @@ using namespace Vulkan_Internal;
}
else
{
int subresource = SRV_index[original_binding];
int subresource = table.SRV_index[original_binding];
auto buffer_internal = to_internal((const GPUBuffer*)&resource);
bufferInfos.back().buffer = buffer_internal->resource;
bufferInfos.back().range = VK_WHOLE_SIZE;
@@ -1572,7 +1552,7 @@ using namespace Vulkan_Internal;
{
// UAV
const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_U;
const GPUResource& resource = UAV[original_binding];
const GPUResource& resource = table.UAV[original_binding];
if (!resource.IsValid() || !resource.IsBuffer())
{
bufferInfos.back().buffer = device->nullBuffer;
@@ -1580,7 +1560,7 @@ using namespace Vulkan_Internal;
}
else
{
int subresource = UAV_index[original_binding];
int subresource = table.UAV_index[original_binding];
auto buffer_internal = to_internal((const GPUBuffer*)&resource);
bufferInfos.back().buffer = buffer_internal->resource;
bufferInfos.back().range = VK_WHOLE_SIZE;
@@ -1598,7 +1578,7 @@ using namespace Vulkan_Internal;
accelerationStructureViews.back().accelerationStructureCount = 1;
const uint32_t original_binding = unrolled_binding - VULKAN_BINDING_SHIFT_T;
const GPUResource& resource = SRV[original_binding];
const GPUResource& resource = table.SRV[original_binding];
if (!resource.IsValid() || !resource.IsAccelerationStructure())
{
assert(0); // invalid acceleration structure!
@@ -1834,7 +1814,7 @@ using namespace Vulkan_Internal;
{
pso_validate(cmd);
GetFrameResources().descriptors[cmd].flush(true, cmd);
binders[cmd].flush(true, cmd);
auto pso_internal = to_internal(active_pso[cmd]);
if (pso_internal->pushconstants.size > 0)
@@ -1851,7 +1831,7 @@ using namespace Vulkan_Internal;
}
void GraphicsDevice_Vulkan::predispatch(CommandList cmd)
{
GetFrameResources().descriptors[cmd].flush(false, cmd);
binders[cmd].flush(false, cmd);
auto cs_internal = to_internal(active_cs[cmd]);
if (cs_internal->pushconstants.size > 0)
@@ -2591,7 +2571,7 @@ using namespace Vulkan_Internal;
}
vkDestroyCommandPool(device, frame.initCommandPool, nullptr);
for (auto& descriptormanager : frame.descriptors)
for (auto& descriptormanager : frame.binder_pools)
{
descriptormanager.destroy();
}
@@ -5657,8 +5637,10 @@ using namespace Vulkan_Internal;
res = vkAllocateCommandBuffers(device, &commandBufferInfo, &frame.commandBuffers[cmd][queue]);
assert(res == VK_SUCCESS);
frame.descriptors[cmd].init(this);
frame.binder_pools[cmd].init(this);
}
binders[cmd].init(this);
}
res = vkResetCommandPool(device, GetFrameResources().commandPools[cmd][queue], 0);
@@ -5673,7 +5655,8 @@ using namespace Vulkan_Internal;
assert(res == VK_SUCCESS);
// reset descriptor allocators:
GetFrameResources().descriptors[cmd].reset();
GetFrameResources().binder_pools[cmd].reset();
binders[cmd].reset();
if (queue == QUEUE_GRAPHICS)
{
@@ -5999,12 +5982,12 @@ using namespace Vulkan_Internal;
void GraphicsDevice_Vulkan::BindResource(const GPUResource* resource, uint32_t slot, CommandList cmd, int subresource)
{
assert(slot < DESCRIPTORBINDER_SRV_COUNT);
auto& descriptors = GetFrameResources().descriptors[cmd];
if (descriptors.SRV[slot].internal_state != resource->internal_state || descriptors.SRV_index[slot] != subresource)
auto& binder = binders[cmd];
if (binder.table.SRV[slot].internal_state != resource->internal_state || binder.table.SRV_index[slot] != subresource)
{
descriptors.SRV[slot] = *resource;
descriptors.SRV_index[slot] = subresource;
descriptors.dirty = true;
binder.table.SRV[slot] = *resource;
binder.table.SRV_index[slot] = subresource;
binder.dirty = true;
}
}
void GraphicsDevice_Vulkan::BindResources(const GPUResource *const* resources, uint32_t slot, uint32_t count, CommandList cmd)
@@ -6020,12 +6003,12 @@ using namespace Vulkan_Internal;
void GraphicsDevice_Vulkan::BindUAV(const GPUResource* resource, uint32_t slot, CommandList cmd, int subresource)
{
assert(slot < DESCRIPTORBINDER_UAV_COUNT);
auto& descriptors = GetFrameResources().descriptors[cmd];
if (descriptors.UAV[slot].internal_state != resource->internal_state || descriptors.UAV_index[slot] != subresource)
auto& binder = binders[cmd];
if (binder.table.UAV[slot].internal_state != resource->internal_state || binder.table.UAV_index[slot] != subresource)
{
descriptors.UAV[slot] = *resource;
descriptors.UAV_index[slot] = subresource;
descriptors.dirty = true;
binder.table.UAV[slot] = *resource;
binder.table.UAV_index[slot] = subresource;
binder.dirty = true;
}
}
void GraphicsDevice_Vulkan::BindUAVs(const GPUResource *const* resources, uint32_t slot, uint32_t count, CommandList cmd)
@@ -6041,22 +6024,22 @@ using namespace Vulkan_Internal;
void GraphicsDevice_Vulkan::BindSampler(const Sampler* sampler, uint32_t slot, CommandList cmd)
{
assert(slot < DESCRIPTORBINDER_SAMPLER_COUNT);
auto& descriptors = GetFrameResources().descriptors[cmd];
if (descriptors.SAM[slot].internal_state != sampler->internal_state)
auto& binder = binders[cmd];
if (binder.table.SAM[slot].internal_state != sampler->internal_state)
{
descriptors.SAM[slot] = *sampler;
descriptors.dirty = true;
binder.table.SAM[slot] = *sampler;
binder.dirty = true;
}
}
void GraphicsDevice_Vulkan::BindConstantBuffer(const GPUBuffer* buffer, uint32_t slot, CommandList cmd, uint64_t offset)
{
assert(slot < DESCRIPTORBINDER_CBV_COUNT);
auto& descriptors = GetFrameResources().descriptors[cmd];
if (descriptors.CBV[slot].internal_state != buffer->internal_state || descriptors.CBV_offset[slot] != offset)
auto& binder = binders[cmd];
if (binder.table.CBV[slot].internal_state != buffer->internal_state || binder.table.CBV_offset[slot] != offset)
{
descriptors.CBV[slot] = *buffer;
descriptors.CBV_offset[slot] = offset;
descriptors.dirty = true;
binder.table.CBV[slot] = *buffer;
binder.table.CBV_offset[slot] = offset;
binder.dirty = true;
}
}
void GraphicsDevice_Vulkan::BindVertexBuffers(const GPUBuffer *const* vertexBuffers, uint32_t slot, uint32_t count, const uint32_t* strides, const uint64_t* offsets, CommandList cmd)
@@ -6209,14 +6192,14 @@ using namespace Vulkan_Internal;
if (active_pso[cmd] == nullptr)
{
GetFrameResources().descriptors[cmd].dirty = true;
binders[cmd].dirty = true;
}
else
{
auto active_internal = to_internal(active_pso[cmd]);
if (internal_state->binding_hash != active_internal->binding_hash)
{
GetFrameResources().descriptors[cmd].dirty = true;
binders[cmd].dirty = true;
}
}
@@ -6244,7 +6227,7 @@ using namespace Vulkan_Internal;
{
if (active_cs[cmd] == nullptr)
{
GetFrameResources().descriptors[cmd].dirty = true;
binders[cmd].dirty = true;
}
else
{
@@ -6252,7 +6235,7 @@ using namespace Vulkan_Internal;
auto active_internal = to_internal(active_cs[cmd]);
if (internal_state->binding_hash != active_internal->binding_hash)
{
GetFrameResources().descriptors[cmd].dirty = true;
binders[cmd].dirty = true;
}
}
+20 -19
View File
@@ -187,33 +187,16 @@ namespace wiGraphics
VkCommandPool initCommandPool = VK_NULL_HANDLE;
VkCommandBuffer initCommandBuffer = VK_NULL_HANDLE;
struct DescriptorBinder
struct DescriptorBinderPool
{
GraphicsDevice_Vulkan* device;
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
uint32_t poolSize = 256;
std::vector<VkWriteDescriptorSet> descriptorWrites;
std::vector<VkDescriptorBufferInfo> bufferInfos;
std::vector<VkDescriptorImageInfo> imageInfos;
std::vector<VkBufferView> texelBufferViews;
std::vector<VkWriteDescriptorSetAccelerationStructureKHR> accelerationStructureViews;
bool dirty = false;
GPUBuffer CBV[DESCRIPTORBINDER_CBV_COUNT];
uint64_t CBV_offset[DESCRIPTORBINDER_CBV_COUNT];
GPUResource SRV[DESCRIPTORBINDER_SRV_COUNT];
int SRV_index[DESCRIPTORBINDER_SRV_COUNT];
GPUResource UAV[DESCRIPTORBINDER_UAV_COUNT];
int UAV_index[DESCRIPTORBINDER_UAV_COUNT];
Sampler SAM[DESCRIPTORBINDER_SAMPLER_COUNT];
void init(GraphicsDevice_Vulkan* device);
void destroy();
void reset();
void flush(bool graphics, CommandList cmd);
};
DescriptorBinder descriptors[COMMANDLIST_COUNT];
} binder_pools[COMMANDLIST_COUNT];
};
FrameResources frames[BUFFERCOUNT];
const FrameResources& GetFrameResources() const { return frames[GetBufferIndex()]; }
@@ -230,6 +213,24 @@ namespace wiGraphics
return GetFrameResources().commandBuffers[cmd][cmd_meta[cmd].queue];
}
struct DescriptorBinder
{
DescriptorBindingTable table;
GraphicsDevice_Vulkan* device;
std::vector<VkWriteDescriptorSet> descriptorWrites;
std::vector<VkDescriptorBufferInfo> bufferInfos;
std::vector<VkDescriptorImageInfo> imageInfos;
std::vector<VkBufferView> texelBufferViews;
std::vector<VkWriteDescriptorSetAccelerationStructureKHR> accelerationStructureViews;
bool dirty = false;
void init(GraphicsDevice_Vulkan* device);
void reset();
void flush(bool graphics, CommandList cmd);
};
DescriptorBinder binders[COMMANDLIST_COUNT];
std::vector<VkMemoryBarrier> frame_memoryBarriers[COMMANDLIST_COUNT];
std::vector<VkImageMemoryBarrier> frame_imageBarriers[COMMANDLIST_COUNT];
std::vector<VkBufferMemoryBarrier> frame_bufferBarriers[COMMANDLIST_COUNT];
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates, breaking compatibility changes
const int minor = 57;
// minor bug fixes, alterations, refactors, updates
const int revision = 13;
const int revision = 14;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);