summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-04-21 19:20:53 -0300
committerGravatar ReinUsesLisp2020-04-21 19:55:52 -0300
commit488ed8bd02c8014cf9c70aff76371a77ad36765c (patch)
tree708fbc174390f2a1613adf2bcfe8c28bf4145d20 /src
parentgl_rasterizer: Fix buffers without size (diff)
downloadyuzu-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.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp36
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp2
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
1234VkBuffer 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;