diff options
Diffstat (limited to '')
-rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.cpp | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 9627eb129..d72d99899 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -7,7 +7,6 @@ #include <span> #include <vector> -#include "video_core/buffer_cache/buffer_cache.h" #include "video_core/renderer_vulkan/maxwell_to_vk.h" #include "video_core/renderer_vulkan/vk_buffer_cache.h" #include "video_core/renderer_vulkan/vk_scheduler.h" @@ -303,9 +302,13 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& m DescriptorPool& descriptor_pool) : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, staging_pool{staging_pool_}, guest_descriptor_queue{guest_descriptor_queue_}, - uint8_pass(device, scheduler, descriptor_pool, staging_pool, compute_pass_descriptor_queue), quad_index_pass(device, scheduler, descriptor_pool, staging_pool, compute_pass_descriptor_queue) { + if (device.GetDriverID() != VK_DRIVER_ID_QUALCOMM_PROPRIETARY) { + // TODO: FixMe: Uint8Pass compute shader does not build on some Qualcomm drivers. + uint8_pass = std::make_unique<Uint8Pass>(device, scheduler, descriptor_pool, staging_pool, + compute_pass_descriptor_queue); + } quad_array_index_buffer = std::make_shared<QuadArrayIndexBuffer>(device_, memory_allocator_, scheduler_, staging_pool_); quad_strip_index_buffer = std::make_shared<QuadStripIndexBuffer>(device_, memory_allocator_, @@ -442,7 +445,9 @@ void BufferCacheRuntime::BindIndexBuffer(PrimitiveTopology topology, IndexFormat topology == PrimitiveTopology::QuadStrip); } else if (vk_index_type == VK_INDEX_TYPE_UINT8_EXT && !device.IsExtIndexTypeUint8Supported()) { vk_index_type = VK_INDEX_TYPE_UINT16; - std::tie(vk_buffer, vk_offset) = uint8_pass.Assemble(num_indices, buffer, offset); + if (uint8_pass) { + std::tie(vk_buffer, vk_offset) = uint8_pass->Assemble(num_indices, buffer, offset); + } } if (vk_buffer == VK_NULL_HANDLE) { // Vulkan doesn't support null index buffers. Replace it with our own null buffer. @@ -496,6 +501,40 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset } } +void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings& bindings) { + boost::container::small_vector<VkBuffer, 32> buffer_handles; + for (u32 index = 0; index < bindings.buffers.size(); index++) { + auto& buffer = *reinterpret_cast<Buffer*>(bindings.buffers[index]); + auto handle = buffer.Handle(); + if (handle == VK_NULL_HANDLE) { + bindings.offsets[index] = 0; + bindings.sizes[index] = VK_WHOLE_SIZE; + if (!device.HasNullDescriptor()) { + ReserveNullBuffer(); + handle = *null_buffer; + } + } + buffer_handles.push_back(handle); + } + if (device.IsExtExtendedDynamicStateSupported()) { + scheduler.Record([bindings = bindings, + buffer_handles = buffer_handles](vk::CommandBuffer cmdbuf) { + cmdbuf.BindVertexBuffers2EXT( + bindings.min_index, bindings.max_index - bindings.min_index, buffer_handles.data(), + reinterpret_cast<const VkDeviceSize*>(bindings.offsets.data()), + reinterpret_cast<const VkDeviceSize*>(bindings.sizes.data()), + reinterpret_cast<const VkDeviceSize*>(bindings.strides.data())); + }); + } else { + scheduler.Record([bindings = bindings, + buffer_handles = buffer_handles](vk::CommandBuffer cmdbuf) { + cmdbuf.BindVertexBuffers( + bindings.min_index, bindings.max_index - bindings.min_index, buffer_handles.data(), + reinterpret_cast<const VkDeviceSize*>(bindings.offsets.data())); + }); + } +} + void BufferCacheRuntime::BindTransformFeedbackBuffer(u32 index, VkBuffer buffer, u32 offset, u32 size) { if (!device.IsExtTransformFeedbackSupported()) { @@ -517,6 +556,25 @@ void BufferCacheRuntime::BindTransformFeedbackBuffer(u32 index, VkBuffer buffer, }); } +void BufferCacheRuntime::BindTransformFeedbackBuffers(VideoCommon::HostBindings& bindings) { + if (!device.IsExtTransformFeedbackSupported()) { + // Already logged in the rasterizer + return; + } + boost::container::small_vector<VkBuffer, 4> buffer_handles; + for (u32 index = 0; index < bindings.buffers.size(); index++) { + auto& buffer = *reinterpret_cast<Buffer*>(bindings.buffers[index]); + buffer_handles.push_back(buffer.Handle()); + } + scheduler.Record( + [bindings = bindings, buffer_handles = buffer_handles](vk::CommandBuffer cmdbuf) { + cmdbuf.BindTransformFeedbackBuffersEXT( + 0, static_cast<u32>(buffer_handles.size()), buffer_handles.data(), + reinterpret_cast<const VkDeviceSize*>(bindings.offsets.data()), + reinterpret_cast<const VkDeviceSize*>(bindings.sizes.data())); + }); +} + void BufferCacheRuntime::ReserveNullBuffer() { if (null_buffer) { return; |