Fix #131091: GL: Weird Lines appearing in Gizmo Overlays

This happened because NVidia GPUs require higher alignment
for SSBO binds than for vertex inputs.

This is related to	#131103 which fixed it for vulkan.

Add a common capability option for that.
This commit is contained in:
Clément Foucault
2024-11-28 17:22:12 +01:00
parent 8fb12839f2
commit ec84fe5fdb
8 changed files with 28 additions and 6 deletions

View File

@@ -34,6 +34,9 @@ int GPU_max_shader_storage_buffer_bindings();
int GPU_max_compute_shader_storage_blocks();
int GPU_max_samplers();
size_t GPU_max_storage_buffer_size();
/* Used when binding subrange of SSBOs. In bytes.
* The start of the range must be aligned with this value. */
size_t GPU_storage_buffer_alignment();
int GPU_extensions_len();
const char *GPU_extension_get(int i);

View File

@@ -227,6 +227,11 @@ size_t GPU_max_storage_buffer_size()
return GCaps.max_storage_buffer_size;
}
size_t GPU_storage_buffer_alignment()
{
return GCaps.storage_buffer_alignment;
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@@ -40,6 +40,7 @@ struct GPUCapabilities {
int max_shader_storage_buffer_bindings = 0;
int max_compute_shader_storage_blocks = 0;
size_t max_storage_buffer_size = 0;
size_t storage_buffer_alignment = 256;
int extensions_len = 0;
const char *(*extension_get)(int);

View File

@@ -498,6 +498,7 @@ void MTLBackend::capabilities_init(MTLContext *ctx)
* Can use argument buffers if a higher limit is required. */
GCaps.max_shader_storage_buffer_bindings = 14;
GCaps.max_storage_buffer_size = size_t(ctx->device.maxBufferLength);
GCaps.storage_buffer_alignment = 256; /* TODO(fclem): But also unused. */
GCaps.max_work_group_count[0] = 65535;
GCaps.max_work_group_count[1] = 65535;

View File

@@ -583,6 +583,9 @@ void GLBackend::capabilities_init()
int64_t max_ssbo_size;
glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_ssbo_size);
GCaps.max_storage_buffer_size = size_t(max_ssbo_size);
GLint ssbo_alignment;
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_alignment);
GCaps.storage_buffer_alignment = size_t(ssbo_alignment);
GCaps.transform_feedback_support = true;
GCaps.texture_view_support = epoxy_gl_version() >= 43 ||

View File

@@ -8,6 +8,8 @@
* Mimics old style opengl immediate mode drawing.
*/
#include "GPU_capabilities.hh"
#include "gpu_context_private.hh"
#include "gpu_shader_private.hh"
#include "gpu_vertex_format_private.hh"
@@ -96,9 +98,14 @@ uchar *GLImmediate::begin()
recreate_buffer = true;
}
/* ensure vertex data is aligned */
/* Might waste a little space, but it's safe. */
const uint pre_padding = padding(buffer_offset(), vertex_format.stride);
uint vert_alignment = vertex_format.stride;
if (unwrap(this->shader)->is_polyline) {
/* Polyline needs to bind the buffer as SSBO.
* The start of the range needs to match the SSBO alignment requirements. */
vert_alignment = max_uu(vert_alignment, GPU_storage_buffer_alignment());
}
/* Ensure vertex data is aligned. Might waste a little space, but it's safe. */
const uint pre_padding = padding(buffer_offset(), vert_alignment);
if (!recreate_buffer && ((bytes_needed + pre_padding) <= available_bytes)) {
buffer_offset() += pre_padding;

View File

@@ -573,6 +573,7 @@ void VKBackend::capabilities_init(VKDevice &device)
GCaps.max_shader_storage_buffer_bindings = GCaps.max_compute_shader_storage_blocks = min_uu(
limits.maxPerStageDescriptorStorageBuffers, INT_MAX);
GCaps.max_storage_buffer_size = size_t(limits.maxStorageBufferRange);
GCaps.storage_buffer_alignment = limits.minStorageBufferOffsetAlignment;
GCaps.max_parallel_compilations = BLI_system_thread_count();
GCaps.mem_stats_support = true;

View File

@@ -8,11 +8,13 @@
* Mimics old style OpenGL immediate mode drawing.
*/
#include "vk_immediate.hh"
#include "GPU_capabilities.hh"
#include "vk_backend.hh"
#include "vk_context.hh"
#include "vk_data_conversion.hh"
#include "vk_framebuffer.hh"
#include "vk_immediate.hh"
#include "vk_state_manager.hh"
#include "CLG_log.h"
@@ -51,8 +53,7 @@ uchar *VKImmediate::begin()
vertex_format_converter.init(&vertex_format, workarounds);
const size_t bytes_needed = vertex_buffer_size(&vertex_format_converter.device_format_get(),
vertex_len);
VkDeviceSize offset_alignment =
device.physical_device_properties_get().limits.minStorageBufferOffsetAlignment;
size_t offset_alignment = GPU_storage_buffer_alignment();
VKBuffer &buffer = ensure_space(bytes_needed, offset_alignment);
/* Apply alignment when allocating new sub buffer, to reduce signed/unsigned data conversion