Prechádzať zdrojové kódy

gl_rasterizer: Fix buffers without size

On NVN buffers can be enabled but have no size. According to deko3d and
the behavior we see in Animal Crossing: New Horizons these buffers get
the special address of 0x1000 and limit themselves to 0xfff.

Implement buffers without a size by binding a null buffer to OpenGL
without a side.

https://github.com/devkitPro/deko3d/blob/1d1930beea093b5a663419e93b0649719a3ca5da/source/maxwell/gpu_3d_vbo.cpp#L62-L63
ReinUsesLisp 6 rokov pred
rodič
commit
0bbae63300

+ 2 - 1
src/video_core/engines/maxwell_3d.h

@@ -1259,7 +1259,8 @@ public:
 
 
                     GPUVAddr LimitAddress() const {
                     GPUVAddr LimitAddress() const {
                         return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_high) << 32) |
                         return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_high) << 32) |
-                                                     limit_low);
+                                                     limit_low) +
+                               1;
                     }
                     }
                 } vertex_array_limit[NumVertexArrays];
                 } vertex_array_limit[NumVertexArrays];
 
 

+ 8 - 4
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -185,8 +185,12 @@ void RasterizerOpenGL::SetupVertexBuffer() {
         const GPUVAddr start = vertex_array.StartAddress();
         const GPUVAddr start = vertex_array.StartAddress();
         const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
         const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
 
 
-        ASSERT(end > start);
-        const u64 size = end - start + 1;
+        ASSERT(end >= start);
+        const u64 size = end - start;
+        if (size == 0) {
+            glBindVertexBuffer(static_cast<GLuint>(index), 0, 0, vertex_array.stride);
+            continue;
+        }
         const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
         const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
         glBindVertexBuffer(static_cast<GLuint>(index), vertex_buffer, vertex_buffer_offset,
         glBindVertexBuffer(static_cast<GLuint>(index), vertex_buffer, vertex_buffer_offset,
                            vertex_array.stride);
                            vertex_array.stride);
@@ -310,8 +314,8 @@ std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
         const GPUVAddr start = regs.vertex_array[index].StartAddress();
         const GPUVAddr start = regs.vertex_array[index].StartAddress();
         const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
         const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
 
 
-        ASSERT(end > start);
-        size += end - start + 1;
+        size += end - start;
+        ASSERT(end >= start);
     }
     }
 
 
     return size;
     return size;

+ 3 - 3
src/video_core/renderer_vulkan/vk_rasterizer.cpp

@@ -834,8 +834,8 @@ void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex
         const GPUVAddr start{vertex_array.StartAddress()};
         const GPUVAddr start{vertex_array.StartAddress()};
         const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()};
         const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()};
 
 
-        ASSERT(end > start);
-        const std::size_t size{end - start + 1};
+        ASSERT(end >= start);
+        const std::size_t size{end - start};
         const auto [buffer, offset] = buffer_cache.UploadMemory(start, size);
         const auto [buffer, offset] = buffer_cache.UploadMemory(start, size);
         buffer_bindings.AddVertexBinding(buffer, offset);
         buffer_bindings.AddVertexBinding(buffer, offset);
     }
     }
@@ -1179,7 +1179,7 @@ std::size_t RasterizerVulkan::CalculateVertexArraysSize() const {
         const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()};
         const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()};
         DEBUG_ASSERT(end >= start);
         DEBUG_ASSERT(end >= start);
 
 
-        size += (end - start + 1) * regs.vertex_array[index].enable;
+        size += (end - start) * regs.vertex_array[index].enable;
     }
     }
     return size;
     return size;
 }
 }