diff options
| author | 2020-04-21 19:20:53 -0300 | |
|---|---|---|
| committer | 2020-04-21 19:55:52 -0300 | |
| commit | 488ed8bd02c8014cf9c70aff76371a77ad36765c (patch) | |
| tree | 708fbc174390f2a1613adf2bcfe8c28bf4145d20 | |
| parent | gl_rasterizer: Fix buffers without size (diff) | |
| download | yuzu-488ed8bd02c8014cf9c70aff76371a77ad36765c.tar.gz yuzu-488ed8bd02c8014cf9c70aff76371a77ad36765c.tar.xz yuzu-488ed8bd02c8014cf9c70aff76371a77ad36765c.zip | |
vk_rasterizer: Add lazy default buffer maker and use it for empty buffers
Introduce a default buffer getter that lazily constructs an empty
buffer. This is intended to match OpenGL's buffer 0.
Use this for disabled vertex and uniform buffers.
While we are at it, include vertex buffer usages for staging buffers to
silence validation errors.
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 36 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp | 2 |
3 files changed, 40 insertions, 4 deletions
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 2ebf34fc4..538cf73a6 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -836,6 +836,10 @@ void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex | |||
| 836 | 836 | ||
| 837 | ASSERT(end >= start); | 837 | ASSERT(end >= start); |
| 838 | const std::size_t size{end - start}; | 838 | const std::size_t size{end - start}; |
| 839 | if (size == 0) { | ||
| 840 | buffer_bindings.AddVertexBinding(DefaultBuffer(), 0); | ||
| 841 | continue; | ||
| 842 | } | ||
| 839 | const auto [buffer, offset] = buffer_cache.UploadMemory(start, size); | 843 | const auto [buffer, offset] = buffer_cache.UploadMemory(start, size); |
| 840 | buffer_bindings.AddVertexBinding(buffer, offset); | 844 | buffer_bindings.AddVertexBinding(buffer, offset); |
| 841 | } | 845 | } |
| @@ -990,8 +994,7 @@ void RasterizerVulkan::SetupConstBuffer(const ConstBufferEntry& entry, | |||
| 990 | const Tegra::Engines::ConstBufferInfo& buffer) { | 994 | const Tegra::Engines::ConstBufferInfo& buffer) { |
| 991 | if (!buffer.enabled) { | 995 | if (!buffer.enabled) { |
| 992 | // Set values to zero to unbind buffers | 996 | // Set values to zero to unbind buffers |
| 993 | update_descriptor_queue.AddBuffer(buffer_cache.GetEmptyBuffer(sizeof(float)), 0, | 997 | update_descriptor_queue.AddBuffer(DefaultBuffer(), 0, DEFAULT_BUFFER_SIZE); |
| 994 | sizeof(float)); | ||
| 995 | return; | 998 | return; |
| 996 | } | 999 | } |
| 997 | 1000 | ||
| @@ -1014,7 +1017,9 @@ void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAdd | |||
| 1014 | if (size == 0) { | 1017 | if (size == 0) { |
| 1015 | // Sometimes global memory pointers don't have a proper size. Upload a dummy entry | 1018 | // Sometimes global memory pointers don't have a proper size. Upload a dummy entry |
| 1016 | // because Vulkan doesn't like empty buffers. | 1019 | // because Vulkan doesn't like empty buffers. |
| 1017 | constexpr std::size_t dummy_size = 4; | 1020 | // Note: Do *not* use DefaultBuffer() here, storage buffers can be written breaking the |
| 1021 | // default buffer. | ||
| 1022 | static constexpr std::size_t dummy_size = 4; | ||
| 1018 | const auto buffer = buffer_cache.GetEmptyBuffer(dummy_size); | 1023 | const auto buffer = buffer_cache.GetEmptyBuffer(dummy_size); |
| 1019 | update_descriptor_queue.AddBuffer(buffer, 0, dummy_size); | 1024 | update_descriptor_queue.AddBuffer(buffer, 0, dummy_size); |
| 1020 | return; | 1025 | return; |
| @@ -1226,4 +1231,29 @@ RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions) | |||
| 1226 | return renderpass_params; | 1231 | return renderpass_params; |
| 1227 | } | 1232 | } |
| 1228 | 1233 | ||
| 1234 | VkBuffer RasterizerVulkan::DefaultBuffer() { | ||
| 1235 | if (default_buffer) { | ||
| 1236 | return *default_buffer; | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | VkBufferCreateInfo ci; | ||
| 1240 | ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; | ||
| 1241 | ci.pNext = nullptr; | ||
| 1242 | ci.flags = 0; | ||
| 1243 | ci.size = DEFAULT_BUFFER_SIZE; | ||
| 1244 | ci.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | | ||
| 1245 | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; | ||
| 1246 | ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; | ||
| 1247 | ci.queueFamilyIndexCount = 0; | ||
| 1248 | ci.pQueueFamilyIndices = nullptr; | ||
| 1249 | default_buffer = device.GetLogical().CreateBuffer(ci); | ||
| 1250 | default_buffer_commit = memory_manager.Commit(default_buffer, false); | ||
| 1251 | |||
| 1252 | scheduler.RequestOutsideRenderPassOperationContext(); | ||
| 1253 | scheduler.Record([buffer = *default_buffer](vk::CommandBuffer cmdbuf) { | ||
| 1254 | cmdbuf.FillBuffer(buffer, 0, DEFAULT_BUFFER_SIZE, 0); | ||
| 1255 | }); | ||
| 1256 | return *default_buffer; | ||
| 1257 | } | ||
| 1258 | |||
| 1229 | } // namespace Vulkan | 1259 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index d9108f862..eafc7bace 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h | |||
| @@ -148,6 +148,7 @@ private: | |||
| 148 | using Texceptions = std::bitset<Maxwell::NumRenderTargets + 1>; | 148 | using Texceptions = std::bitset<Maxwell::NumRenderTargets + 1>; |
| 149 | 149 | ||
| 150 | static constexpr std::size_t ZETA_TEXCEPTION_INDEX = 8; | 150 | static constexpr std::size_t ZETA_TEXCEPTION_INDEX = 8; |
| 151 | static constexpr VkDeviceSize DEFAULT_BUFFER_SIZE = 4 * sizeof(float); | ||
| 151 | 152 | ||
| 152 | void FlushWork(); | 153 | void FlushWork(); |
| 153 | 154 | ||
| @@ -240,6 +241,8 @@ private: | |||
| 240 | 241 | ||
| 241 | RenderPassParams GetRenderPassParams(Texceptions texceptions) const; | 242 | RenderPassParams GetRenderPassParams(Texceptions texceptions) const; |
| 242 | 243 | ||
| 244 | VkBuffer DefaultBuffer(); | ||
| 245 | |||
| 243 | Core::System& system; | 246 | Core::System& system; |
| 244 | Core::Frontend::EmuWindow& render_window; | 247 | Core::Frontend::EmuWindow& render_window; |
| 245 | VKScreenInfo& screen_info; | 248 | VKScreenInfo& screen_info; |
| @@ -263,6 +266,9 @@ private: | |||
| 263 | VKSamplerCache sampler_cache; | 266 | VKSamplerCache sampler_cache; |
| 264 | VKQueryCache query_cache; | 267 | VKQueryCache query_cache; |
| 265 | 268 | ||
| 269 | vk::Buffer default_buffer; | ||
| 270 | VKMemoryCommit default_buffer_commit; | ||
| 271 | |||
| 266 | std::array<View, Maxwell::NumRenderTargets> color_attachments; | 272 | std::array<View, Maxwell::NumRenderTargets> color_attachments; |
| 267 | View zeta_attachment; | 273 | View zeta_attachment; |
| 268 | 274 | ||
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index 94d954d7a..c76ab5c2d 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp | |||
| @@ -81,7 +81,7 @@ VKBuffer& VKStagingBufferPool::CreateStagingBuffer(std::size_t size, bool host_v | |||
| 81 | ci.size = 1ULL << log2; | 81 | ci.size = 1ULL << log2; |
| 82 | ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | | 82 | ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | |
| 83 | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | | 83 | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | |
| 84 | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; | 84 | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; |
| 85 | ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; | 85 | ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
| 86 | ci.queueFamilyIndexCount = 0; | 86 | ci.queueFamilyIndexCount = 0; |
| 87 | ci.pQueueFamilyIndices = nullptr; | 87 | ci.pQueueFamilyIndices = nullptr; |