vk_buffer_cache: Use emulated null buffers for transform feedback

Vulkan does not support null buffers on transform feedback bindings.
Emulate these using the same null buffer we were using for index
buffers.
This commit is contained in:
ReinUsesLisp 2021-07-09 01:27:47 -03:00
parent 975a7b3a78
commit 5a45d295da
2 changed files with 19 additions and 11 deletions

View File

@ -152,8 +152,8 @@ void BufferCacheRuntime::BindIndexBuffer(PrimitiveTopology topology, IndexFormat
} }
if (vk_buffer == VK_NULL_HANDLE) { if (vk_buffer == VK_NULL_HANDLE) {
// Vulkan doesn't support null index buffers. Replace it with our own null buffer. // Vulkan doesn't support null index buffers. Replace it with our own null buffer.
ReserveNullIndexBuffer(); ReserveNullBuffer();
vk_buffer = *null_index_buffer; vk_buffer = *null_buffer;
} }
scheduler.Record([vk_buffer, vk_offset, vk_index_type](vk::CommandBuffer cmdbuf) { scheduler.Record([vk_buffer, vk_offset, vk_index_type](vk::CommandBuffer cmdbuf) {
cmdbuf.BindIndexBuffer(vk_buffer, vk_offset, vk_index_type); cmdbuf.BindIndexBuffer(vk_buffer, vk_offset, vk_index_type);
@ -195,6 +195,14 @@ void BufferCacheRuntime::BindTransformFeedbackBuffer(u32 index, VkBuffer buffer,
// Already logged in the rasterizer // Already logged in the rasterizer
return; return;
} }
if (buffer == VK_NULL_HANDLE) {
// Vulkan doesn't support null transform feedback buffers.
// Replace it with our own null buffer.
ReserveNullBuffer();
buffer = *null_buffer;
offset = 0;
size = 0;
}
scheduler.Record([index, buffer, offset, size](vk::CommandBuffer cmdbuf) { scheduler.Record([index, buffer, offset, size](vk::CommandBuffer cmdbuf) {
const VkDeviceSize vk_offset = offset; const VkDeviceSize vk_offset = offset;
const VkDeviceSize vk_size = size; const VkDeviceSize vk_size = size;
@ -279,11 +287,11 @@ void BufferCacheRuntime::ReserveQuadArrayLUT(u32 num_indices, bool wait_for_idle
}); });
} }
void BufferCacheRuntime::ReserveNullIndexBuffer() { void BufferCacheRuntime::ReserveNullBuffer() {
if (null_index_buffer) { if (null_buffer) {
return; return;
} }
null_index_buffer = device.GetLogical().CreateBuffer(VkBufferCreateInfo{ null_buffer = device.GetLogical().CreateBuffer(VkBufferCreateInfo{
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
@ -294,12 +302,12 @@ void BufferCacheRuntime::ReserveNullIndexBuffer() {
.pQueueFamilyIndices = nullptr, .pQueueFamilyIndices = nullptr,
}); });
if (device.HasDebuggingToolAttached()) { if (device.HasDebuggingToolAttached()) {
null_index_buffer.SetObjectNameEXT("Null index buffer"); null_buffer.SetObjectNameEXT("Null index buffer");
} }
null_index_buffer_commit = memory_allocator.Commit(null_index_buffer, MemoryUsage::DeviceLocal); null_buffer_commit = memory_allocator.Commit(null_buffer, MemoryUsage::DeviceLocal);
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([buffer = *null_index_buffer](vk::CommandBuffer cmdbuf) { scheduler.Record([buffer = *null_buffer](vk::CommandBuffer cmdbuf) {
cmdbuf.FillBuffer(buffer, 0, VK_WHOLE_SIZE, 0); cmdbuf.FillBuffer(buffer, 0, VK_WHOLE_SIZE, 0);
}); });
} }

View File

@ -92,7 +92,7 @@ private:
void ReserveQuadArrayLUT(u32 num_indices, bool wait_for_idle); void ReserveQuadArrayLUT(u32 num_indices, bool wait_for_idle);
void ReserveNullIndexBuffer(); void ReserveNullBuffer();
const Device& device; const Device& device;
MemoryAllocator& memory_allocator; MemoryAllocator& memory_allocator;
@ -105,8 +105,8 @@ private:
VkIndexType quad_array_lut_index_type{}; VkIndexType quad_array_lut_index_type{};
u32 current_num_indices = 0; u32 current_num_indices = 0;
vk::Buffer null_index_buffer; vk::Buffer null_buffer;
MemoryCommit null_index_buffer_commit; MemoryCommit null_buffer_commit;
Uint8Pass uint8_pass; Uint8Pass uint8_pass;
QuadIndexedPass quad_index_pass; QuadIndexedPass quad_index_pass;