summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/maxwell_3d.h3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp12
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp42
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp2
5 files changed, 53 insertions, 12 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 59d5752d2..7bbc6600b 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1259,7 +1259,8 @@ public:
1259 1259
1260 GPUVAddr LimitAddress() const { 1260 GPUVAddr LimitAddress() const {
1261 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_high) << 32) | 1261 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_high) << 32) |
1262 limit_low); 1262 limit_low) +
1263 1;
1263 } 1264 }
1264 } vertex_array_limit[NumVertexArrays]; 1265 } vertex_array_limit[NumVertexArrays];
1265 1266
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 4c16c89d2..6fe155bcc 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -186,8 +186,12 @@ void RasterizerOpenGL::SetupVertexBuffer() {
186 const GPUVAddr start = vertex_array.StartAddress(); 186 const GPUVAddr start = vertex_array.StartAddress();
187 const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); 187 const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
188 188
189 ASSERT(end > start); 189 ASSERT(end >= start);
190 const u64 size = end - start + 1; 190 const u64 size = end - start;
191 if (size == 0) {
192 glBindVertexBuffer(static_cast<GLuint>(index), 0, 0, vertex_array.stride);
193 continue;
194 }
191 const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size); 195 const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
192 glBindVertexBuffer(static_cast<GLuint>(index), vertex_buffer, vertex_buffer_offset, 196 glBindVertexBuffer(static_cast<GLuint>(index), vertex_buffer, vertex_buffer_offset,
193 vertex_array.stride); 197 vertex_array.stride);
@@ -311,8 +315,8 @@ std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
311 const GPUVAddr start = regs.vertex_array[index].StartAddress(); 315 const GPUVAddr start = regs.vertex_array[index].StartAddress();
312 const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); 316 const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
313 317
314 ASSERT(end > start); 318 size += end - start;
315 size += end - start + 1; 319 ASSERT(end >= start);
316 } 320 }
317 321
318 return size; 322 return size;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 8a1f57891..68464e637 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -877,8 +877,12 @@ void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex
877 const GPUVAddr start{vertex_array.StartAddress()}; 877 const GPUVAddr start{vertex_array.StartAddress()};
878 const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()}; 878 const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()};
879 879
880 ASSERT(end > start); 880 ASSERT(end >= start);
881 const std::size_t size{end - start + 1}; 881 const std::size_t size{end - start};
882 if (size == 0) {
883 buffer_bindings.AddVertexBinding(DefaultBuffer(), 0);
884 continue;
885 }
882 const auto [buffer, offset] = buffer_cache.UploadMemory(start, size); 886 const auto [buffer, offset] = buffer_cache.UploadMemory(start, size);
883 buffer_bindings.AddVertexBinding(buffer, offset); 887 buffer_bindings.AddVertexBinding(buffer, offset);
884 } 888 }
@@ -1033,8 +1037,7 @@ void RasterizerVulkan::SetupConstBuffer(const ConstBufferEntry& entry,
1033 const Tegra::Engines::ConstBufferInfo& buffer) { 1037 const Tegra::Engines::ConstBufferInfo& buffer) {
1034 if (!buffer.enabled) { 1038 if (!buffer.enabled) {
1035 // Set values to zero to unbind buffers 1039 // Set values to zero to unbind buffers
1036 update_descriptor_queue.AddBuffer(buffer_cache.GetEmptyBuffer(sizeof(float)), 0, 1040 update_descriptor_queue.AddBuffer(DefaultBuffer(), 0, DEFAULT_BUFFER_SIZE);
1037 sizeof(float));
1038 return; 1041 return;
1039 } 1042 }
1040 1043
@@ -1057,7 +1060,9 @@ void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAdd
1057 if (size == 0) { 1060 if (size == 0) {
1058 // Sometimes global memory pointers don't have a proper size. Upload a dummy entry 1061 // Sometimes global memory pointers don't have a proper size. Upload a dummy entry
1059 // because Vulkan doesn't like empty buffers. 1062 // because Vulkan doesn't like empty buffers.
1060 constexpr std::size_t dummy_size = 4; 1063 // Note: Do *not* use DefaultBuffer() here, storage buffers can be written breaking the
1064 // default buffer.
1065 static constexpr std::size_t dummy_size = 4;
1061 const auto buffer = buffer_cache.GetEmptyBuffer(dummy_size); 1066 const auto buffer = buffer_cache.GetEmptyBuffer(dummy_size);
1062 update_descriptor_queue.AddBuffer(buffer, 0, dummy_size); 1067 update_descriptor_queue.AddBuffer(buffer, 0, dummy_size);
1063 return; 1068 return;
@@ -1222,7 +1227,7 @@ std::size_t RasterizerVulkan::CalculateVertexArraysSize() const {
1222 const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()}; 1227 const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()};
1223 DEBUG_ASSERT(end >= start); 1228 DEBUG_ASSERT(end >= start);
1224 1229
1225 size += (end - start + 1) * regs.vertex_array[index].enable; 1230 size += (end - start) * regs.vertex_array[index].enable;
1226 } 1231 }
1227 return size; 1232 return size;
1228} 1233}
@@ -1269,4 +1274,29 @@ RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions)
1269 return renderpass_params; 1274 return renderpass_params;
1270} 1275}
1271 1276
1277VkBuffer RasterizerVulkan::DefaultBuffer() {
1278 if (default_buffer) {
1279 return *default_buffer;
1280 }
1281
1282 VkBufferCreateInfo ci;
1283 ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1284 ci.pNext = nullptr;
1285 ci.flags = 0;
1286 ci.size = DEFAULT_BUFFER_SIZE;
1287 ci.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
1288 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1289 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1290 ci.queueFamilyIndexCount = 0;
1291 ci.pQueueFamilyIndices = nullptr;
1292 default_buffer = device.GetLogical().CreateBuffer(ci);
1293 default_buffer_commit = memory_manager.Commit(default_buffer, false);
1294
1295 scheduler.RequestOutsideRenderPassOperationContext();
1296 scheduler.Record([buffer = *default_buffer](vk::CommandBuffer cmdbuf) {
1297 cmdbuf.FillBuffer(buffer, 0, DEFAULT_BUFFER_SIZE, 0);
1298 });
1299 return *default_buffer;
1300}
1301
1272} // namespace Vulkan 1302} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 2fa46b0cc..d41a7929e 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -155,6 +155,7 @@ private:
155 using Texceptions = std::bitset<Maxwell::NumRenderTargets + 1>; 155 using Texceptions = std::bitset<Maxwell::NumRenderTargets + 1>;
156 156
157 static constexpr std::size_t ZETA_TEXCEPTION_INDEX = 8; 157 static constexpr std::size_t ZETA_TEXCEPTION_INDEX = 8;
158 static constexpr VkDeviceSize DEFAULT_BUFFER_SIZE = 4 * sizeof(float);
158 159
159 void FlushWork(); 160 void FlushWork();
160 161
@@ -247,6 +248,8 @@ private:
247 248
248 RenderPassParams GetRenderPassParams(Texceptions texceptions) const; 249 RenderPassParams GetRenderPassParams(Texceptions texceptions) const;
249 250
251 VkBuffer DefaultBuffer();
252
250 Core::System& system; 253 Core::System& system;
251 Core::Frontend::EmuWindow& render_window; 254 Core::Frontend::EmuWindow& render_window;
252 VKScreenInfo& screen_info; 255 VKScreenInfo& screen_info;
@@ -271,6 +274,9 @@ private:
271 VKFenceManager fence_manager; 274 VKFenceManager fence_manager;
272 VKQueryCache query_cache; 275 VKQueryCache query_cache;
273 276
277 vk::Buffer default_buffer;
278 VKMemoryCommit default_buffer_commit;
279
274 std::array<View, Maxwell::NumRenderTargets> color_attachments; 280 std::array<View, Maxwell::NumRenderTargets> color_attachments;
275 View zeta_attachment; 281 View zeta_attachment;
276 282
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;