gl_DrawID Not Available Even With GL_ARB_shader_draw_parameters

I’ve recently shipped a new rendering pipeline in my game that uses glMultiDrawArraysIndirect to render chunks of a voxel map. Meshes contain chunk-relative positions, which are translated to world-relative positions by sampling a SSBO using gl_DrawID in the vertex shader.

It works great on 99% of player’s GPUs, however some players see every chunk overlapping in the corner of the world, as gl_DrawID is always 0.

I am able to replicate this on my laptop, which has integrated Intel UHD graphics. I verified the SSBO contains valid data, and passed gl_DrawID to the fragment shader (via a flat out int) and recoloured the map red if the value was 0. The entire map was red.

The players who are facing issues are running OpenGL 4.6 on Intel and AMD GPUs, and both GL_ARB_shader_draw_parameters and GL_ARB_multi_draw_indirect extensions are present. Some AMD GPUs are able to render the map without issues.

I can toggle this newer rendering pipeline dynamically, but I am unable to reliably detect if their GPU can support it. Is there another extension I should be checking for?

The below post from last year might give you some ideas.

Also, you might verify that you’re populating and binding the GL_DRAW_INDIRECT_BUFFER properly, providing the correct drawCount to the draw call, and of course checking for GL errors.

Failing that, consider rolling your own gl_DrawID. For suggestions, see:

Thank you for your reply. I’m passing commands directly rather than using a buffer and I’ve ensured the drawCount is correct.

I store all per-instance data in one large VBO and use baseInstance and instanceCount to control which ranges of this VBO to render, so unfortunately I can’t use baseInstance as a draw ID.

Currently my per-instance data fits in a 32-bit integer and adding a new vertex attribute for a draw ID would double the amount of RAM used by my VBO. With those extra 32 bits I could store world-relative positions and not need gl_DrawID.

I’ve tried changing the order of commands as per that post from last year but had no success. If it did work, another older GPU could have another problem and I’d be back at square one.

Worst comes to worst I could render two triangles using glMultiDrawArraysIndirect and colour them red when gl_DrawID == 0 or green when gl_DrawID > 0, then read back the pixels. If there are no green pixels, revert to the old rendering method.

For reference, here is my rendering code:

DrawArraysIndirectCommand* commands;
int lastMeshCount;

void RenderMap(int ssboBinding, uint ssboHandle, uint meshVAO, int* meshStarts, int* meshLengths, int* chunkWorldPos, int meshCount)
{
    // Update SSBO data
    Gl.BindBuffer(BufferTarget.ShaderStorageBuffer, ssboHandle);
    Gl.BindBufferBase(BufferTarget.ShaderStorageBuffer, ssboBinding, ssboHandle);
    Gl.BufferSubData(BufferTarget.ShaderStorageBuffer, IntPtr.Zero, (uint)(meshCount * sizeof(int)), (IntPtr)chunkWorldPos);
    Gl.BindBuffer(BufferTarget.ShaderStorageBuffer, 0);


    // Allocate memory for commands
    var stride = Marshal.SizeOf<DrawArraysIndirectCommand>();
    var bytes = meshCount * stride;

    if (commands == null)
        commands = (DrawArraysIndirectCommand*)Helper.Alloc(bytes);
    else if (lastMeshCount < meshCount)
        commands = (DrawArraysIndirectCommand*)Helper.Realloc(commands, bytes);

    lastMeshCount = Math.Max(lastMeshCount, meshCount);


    // Populate the commands array
    var write = commands;
    var end = commands + meshCount;

    while (write < end)
    {
        write->baseInstance = (uint)*meshStarts++;
        write->count = 4;
        write->first = 0;
        write->instanceCount = (uint)*meshLengths++;

        write++;
    }


    // Draw
    Gl.BindVertexArray(meshVAO);
    Gl.BindBuffer(BufferTarget.DrawIndirectBuffer, 0);
    Gl.MultiDrawArraysIndirect(PrimitiveType.TriangleStrip, (IntPtr)commands, meshCount, stride);
    Gl.BindVertexArray(0);
}

You may know this, but just be aware that what you’re doing won’t work on an OpenGL core profile, only an OpenGL compatibility profile.

The core profile requires the array of MultiDrawIndirect (MDI) subdraw structures (DrawArraysIndirectCommand[] in this case) to be provided in a GL buffer object bound to GL_DRAW_INDIRECT_BUFFER. The compatibility profile extends this to allow the MDI subdraw array to be provided in CPU-side “client array”, as you’re doing above.

Is it possible that the folks that are experiencing issues have OpenGL implementations that don’t support the OpenGL compatibility profile, either at all or very well? NVIDIA of course supports both, which might explain why you’re (apparently) not getting problem reports from those running on NVIDIA GPUs+drivers with this code, but only those running on AMD and Intel GPUs+drivers.

Related:

  • Make sure you’re checking for GL errors. A GL context created in the OpenGL core profile should be ideally throwing a GL error for the above code.
  • Also make sure your GL context creation code is requiring an OpenGL compatibility profile, and terminating with a fatal error if it can only obtain a GL context for an OpenGL core profile.

Thank you, I’ll try with a draw indirect buffer and see if it works on my laptop.

The AMD player’s logs indicate it’s using a compatibility profile:

OpenGL Renderer: amd radeon rx 6950 xt
GPU: amd radeon rx 6950 xt
OpenGL Version: 4.6.14800 Compatibility Profile Context 22.5.1 30.0.15021.11005
OpenGL Version (int): 46
ShadingLanguageVersion: 4.60

Extensions: GL_AMDX_debug_output,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_half_float_fetch,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_stencil_export,GL_AMD_shader_stencil_value_export,GL_AMD_shader_trace,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_sparse_texture_pool,GL_AMD_stencil_operation_extended,GL_AMD_texture_cube_map_array,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_viewport_index,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_snorm,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_separate_stencil,GL_ATI_texture_compression_3dc,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_compiled_vertex_array,GL_EXT_copy_buffer,GL_EXT_copy_texture,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_memory_object,GL_EXT_memory_object_win32,GL_EXT_multi_draw_arrays,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_pixel_buffer_object,GL_EXT_point_parameters,GL_EXT_polygon_offset_clamp,GL_EXT_provoking_vertex,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_win32,GL_EXT_separate_specular_color,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texgen_reflection,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_bptc,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_edge_clamp,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_integer,GL_EXT_texture_lod,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_rectangle,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_R8,GL_EXT_texture_sRGB_RG8,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_storage,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_IBM_texture_mirrored_repeat,GL_INTEL_fragment_shader_ordering,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KTX_buffer_region,GL_NV_alpha_to_coverage_dither_control,GL_NV_blend_square,GL_NV_conditional_render,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_depth_buffer_float,GL_NV_explicit_multisample,GL_NV_float_buffer,GL_NV_half_float,GL_NV_primitive_restart,GL_NV_shader_atomic_int64,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_OES_EGL_image,GL_SGIS_generate_mipmap,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_lod,GL_SUN_multi_draw_arrays,GL_WIN_swap_hint,WGL_EXT_swap_control

And the Intel player’s logs isn’t using a compatibility profile:

OpenGL Renderer: intel(r) uhd graphics 620
GPU: intel(r) uhd graphics 620
OpenGL Version: 4.6.0 - Build 31.0.101.2111
OpenGL Version (int): 46
ShadingLanguageVersion: 4.60 - Build 31.0.101.2111

Extensions: GL_3DFX_texture_compression_FXT1,GL_AMD_depth_clamp_separate,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_viewport_index,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_bit_encoding,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_separate_stencil,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_compiled_vertex_array,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_range_elements,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_memory_object,GL_EXT_memory_object_win32,GL_EXT_multi_draw_arrays,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_polygon_offset_clamp,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_win32,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_compression_s3tc,GL_EXT_texture_edge_clamp,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_rectangle,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_storage,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_IBM_texture_mirrored_repeat,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_multi_rate_fragment_shader,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_shader_subgroup,GL_KHR_shader_subgroup_arithmetic,GL_KHR_shader_subgroup_ballot,GL_KHR_shader_subgroup_basic,GL_KHR_shader_subgroup_clustered,GL_KHR_shader_subgroup_quad,GL_KHR_shader_subgroup_shuffle,GL_KHR_shader_subgroup_shuffle_relative,GL_KHR_shader_subgroup_vote,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_NV_blend_square,GL_NV_conditional_render,GL_NV_primitive_restart,GL_NV_texgen_reflection,GL_SGIS_generate_mipmap,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_lod,GL_SUN_multi_draw_arrays,GL_WIN_swap_hint,WGL_EXT_swap_control

They sent screenshots and each chunk of the map is rendered overlapped in the corner of the map, so these commands are definitely being passed to the GPU and multiple chunks are being rendered.

It works! As a quick test I’m creating a buffer and deleting it after rendering, and the entire map renders correctly on my laptop.

// Copy commands to a buffer first
var gIndirectBuffer = Gl.GenBuffer();
Gl.BindBuffer(BufferTarget.DrawIndirectBuffer, gIndirectBuffer);
Gl.BufferData(BufferTarget.DrawIndirectBuffer, (uint)(stride * count), (IntPtr)commands, BufferUsage.DynamicDraw);


// Draw indirect
Gl.MultiDrawArraysIndirect(PrimitiveType.TriangleStrip, IntPtr.Zero, count, stride);


// Cleanup
Gl.BindVertexArray(0);
Gl.BindBuffer(BufferTarget.DrawIndirectBuffer, 0);
Gl.DeleteBuffers(gIndirectBuffer);

I’ll use this method from now on, which works on both my NVIDIA 3070 and integrated laptop Intel GPU. Thank you :slight_smile:

Great! Glad you’ve found a solution that works for both.

1 Like