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.
1d1930beea/source/maxwell/gpu_3d_vbo.cpp (L62-L63)
This commit is contained in:
parent
f293b15611
commit
0bbae63300
|
@ -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];
|
||||||
|
|
||||||
|
|
|
@ -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);
|
ASSERT(end >= start);
|
||||||
const u64 size = end - start + 1;
|
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;
|
||||||
size += end - start + 1;
|
ASSERT(end >= start);
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
|
|
@ -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);
|
ASSERT(end >= start);
|
||||||
const std::size_t size{end - start + 1};
|
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue