diff options
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 12 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 42 | ||||
| -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 |
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 | ||
| 1277 | VkBuffer 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; |