From 2be0aeaf9979dfedb67986c79695e702161663ab Mon Sep 17 00:00:00 2001 From: Shylie Date: Sun, 26 May 2024 12:35:15 -0400 Subject: [PATCH] Add AMD_vertex_shader_layer support --- source/glad.c | 11 ++++--- source/glad/glad.h | 12 ++++--- source/glerminal-private.h | 1 + source/glerminal.cpp | 64 ++++++++++++++++++++++++++++++++++---- 4 files changed, 73 insertions(+), 15 deletions(-) diff --git a/source/glad.c b/source/glad.c index fd0759b..e046964 100644 --- a/source/glad.c +++ b/source/glad.c @@ -1,22 +1,22 @@ /* - OpenGL loader generated by glad 0.1.36 on Sun May 26 12:09:35 2024. + OpenGL loader generated by glad 0.1.36 on Sun May 26 16:07:25 2024. Language/Generator: C/C++ Specification: gl APIs: gl=4.5 Profile: core Extensions: - + GL_AMD_vertex_shader_layer Loader: True Local files: False Omit khrplatform: False Reproducible: False Commandline: - --profile="core" --api="gl=4.5" --generator="c" --spec="gl" --extensions="" + --profile="core" --api="gl=4.5" --generator="c" --spec="gl" --extensions="GL_AMD_vertex_shader_layer" Online: - https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D4.5 + https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D4.5&extensions=GL_AMD_vertex_shader_layer */ #include @@ -968,6 +968,7 @@ PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL; PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL; PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL; PFNGLWAITSYNCPROC glad_glWaitSync = NULL; +int GLAD_GL_AMD_vertex_shader_layer = 0; static void load_GL_VERSION_1_0(GLADloadproc load) { if(!GLAD_GL_VERSION_1_0) return; glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); @@ -1723,7 +1724,7 @@ static void load_GL_VERSION_4_5(GLADloadproc load) { } static int find_extensionsGL(void) { if (!get_exts()) return 0; - (void)&has_ext; + GLAD_GL_AMD_vertex_shader_layer = has_ext("GL_AMD_vertex_shader_layer"); free_exts(); return 1; } diff --git a/source/glad/glad.h b/source/glad/glad.h index 9e66e36..12ef68a 100644 --- a/source/glad/glad.h +++ b/source/glad/glad.h @@ -1,22 +1,22 @@ /* - OpenGL loader generated by glad 0.1.36 on Sun May 26 12:09:35 2024. + OpenGL loader generated by glad 0.1.36 on Sun May 26 16:07:25 2024. Language/Generator: C/C++ Specification: gl APIs: gl=4.5 Profile: core Extensions: - + GL_AMD_vertex_shader_layer Loader: True Local files: False Omit khrplatform: False Reproducible: False Commandline: - --profile="core" --api="gl=4.5" --generator="c" --spec="gl" --extensions="" + --profile="core" --api="gl=4.5" --generator="c" --spec="gl" --extensions="GL_AMD_vertex_shader_layer" Online: - https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D4.5 + https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D4.5&extensions=GL_AMD_vertex_shader_layer */ @@ -3648,6 +3648,10 @@ typedef void (APIENTRYP PFNGLTEXTUREBARRIERPROC)(void); GLAPI PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier; #define glTextureBarrier glad_glTextureBarrier #endif +#ifndef GL_AMD_vertex_shader_layer +#define GL_AMD_vertex_shader_layer 1 +GLAPI int GLAD_GL_AMD_vertex_shader_layer; +#endif #ifdef __cplusplus } diff --git a/source/glerminal-private.h b/source/glerminal-private.h index 75a7479..2ca2459 100644 --- a/source/glerminal-private.h +++ b/source/glerminal-private.h @@ -7,6 +7,7 @@ #include #include +#include #include #include diff --git a/source/glerminal.cpp b/source/glerminal.cpp index cccfff2..59fe366 100644 --- a/source/glerminal.cpp +++ b/source/glerminal.cpp @@ -52,7 +52,36 @@ namespace " gl_Position = vec4(scaled_offset.x + temp.x, scaled_offset.y - temp.y, 0, 1);\n" "}"; + // note: AMD_vertex_shader_layer support required + constexpr char VERTEX_SHADER_AMD_SOURCE[] = + "#version 450 core\n" + "#extension GL_AMD_vertex_shader_layer : enable\n" + "layout (location = 0) in vec2 position;\n" + "layout (location = 1) in vec2 offset;\n" + "layout (location = 2) in int sprite;\n" + "uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n" + "layout (std430, binding = 0) buffer LayerScales" + "{\n" + " float scales[];\n" + "} lss;\n" + "out VS_OUT {\n" + " flat int sprite;\n" + " vec2 texcoord;\n" + "} vs_out;\n" + "void main()\n" + "{\n" + " const int layer = int(floor(gl_InstanceID / " GRID_SIZE_UNIFORM_NAME ".y));\n" + " gl_Layer = layer;\n" + " vec2 scaled_offset = 2 * offset * " GRID_SIZE_UNIFORM_NAME ".zw;\n" + " vs_out.sprite = sprite;\n" + " vs_out.texcoord = vec2(position.x + 1, -position.y);\n" + " vec2 cell_position = vec2(lss.scales[layer] + (gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) - " GRID_SIZE_UNIFORM_NAME ".x * floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) * " GRID_SIZE_UNIFORM_NAME ".z), -floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) * " GRID_SIZE_UNIFORM_NAME ".z));\n" + " vec2 temp = ((position + vec2(-0.5, 0.5)) * lss.scales[layer] + cell_position + vec2(0.5, -0.5)) * " GRID_SIZE_UNIFORM_NAME ".zw * 2 + vec2(-1, 1);\n" + " gl_Position = vec4(scaled_offset.x + temp.x, scaled_offset.y - temp.y, 0, 1);\n" + "}"; + constexpr const char* VERTEX_SHADER_SOURCE_PTR = VERTEX_SHADER_SOURCE; + constexpr const char* VERTEX_SHADER_AMD_SOURCE_PTR = VERTEX_SHADER_AMD_SOURCE; constexpr char GEOMETRY_SHADER_SOURCE[] = "#version 450 core\n" @@ -98,7 +127,22 @@ namespace " FragColor = texture(" SPRITES_UNIFORM_NAME ", vec3(texcoord, sprite));\n" "}"; + // note: AMD_vertex_shader_layer support required + constexpr char FRAGMENT_SHADER_AMD_SOURCE[] = + "#version 450 core\n" + "in VS_OUT {\n" + " flat int sprite;\n" + " vec2 texcoord;\n" + "} fs_in;\n" + "layout (binding = 0) uniform sampler2DArray " SPRITES_UNIFORM_NAME ";\n" + "out vec4 FragColor;\n" + "void main()\n" + "{\n" + " FragColor = texture(" SPRITES_UNIFORM_NAME ", vec3(fs_in.texcoord, fs_in.sprite));\n" + "}"; + constexpr const char* FRAGMENT_SHADER_SOURCE_PTR = FRAGMENT_SHADER_SOURCE; + constexpr const char* FRAGMENT_SHADER_AMD_SOURCE_PTR = FRAGMENT_SHADER_AMD_SOURCE; constexpr char SCREEN_VERTEX_SHADER_SOURCE[] = "#version 450 core\n" @@ -215,14 +259,12 @@ namespace glerminal update_layer_colors(); update_layer_scales(); - glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); glUseProgram(m_program); glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); glBindVertexArray(m_vao); glClear(GL_COLOR_BUFFER_BIT); glDrawArraysInstanced(GL_TRIANGLES, 0, 6, GRID_AREA * LAYER_COUNT); - glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); glUseProgram(m_screen_program); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindVertexArray(m_screen_vao); @@ -399,6 +441,7 @@ namespace glerminal glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); // -- setup vertex data -- // create vertex buffer object @@ -450,9 +493,12 @@ namespace glerminal glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_layer_colors_buffer); // -- setup shader program -- + // test for features + const bool vertex_shader_layer_supported = glfwExtensionSupported("GL_AMD_vertex_shader_layer"); + // compile const unsigned int vertex_shader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertex_shader, 1, &VERTEX_SHADER_SOURCE_PTR, nullptr); + glShaderSource(vertex_shader, 1, &(vertex_shader_layer_supported ? VERTEX_SHADER_AMD_SOURCE_PTR : VERTEX_SHADER_SOURCE_PTR), nullptr); glCompileShader(vertex_shader); const unsigned int geometry_shader = glCreateShader(GL_GEOMETRY_SHADER); @@ -460,7 +506,7 @@ namespace glerminal glCompileShader(geometry_shader); const unsigned int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment_shader, 1, &FRAGMENT_SHADER_SOURCE_PTR, nullptr); + glShaderSource(fragment_shader, 1, &(vertex_shader_layer_supported ? FRAGMENT_SHADER_AMD_SOURCE_PTR : FRAGMENT_SHADER_SOURCE_PTR), nullptr); glCompileShader(fragment_shader); constexpr int INFO_LOG_SIZE = 512; @@ -507,7 +553,11 @@ namespace glerminal // link m_program = glCreateProgram(); glAttachShader(m_program, vertex_shader); - glAttachShader(m_program, geometry_shader); + // only need geometry shader if AMD_vertex_shader_layer is not supported + if (!vertex_shader_layer_supported) + { + glAttachShader(m_program, geometry_shader); + } glAttachShader(m_program, fragment_shader); glLinkProgram(m_program); glDeleteShader(vertex_shader); @@ -518,6 +568,8 @@ namespace glerminal glGetProgramiv(m_program, GL_LINK_STATUS, &success); if (!success) { + glGetProgramInfoLog(m_program, INFO_LOG_SIZE, nullptr, info_log); + glDeleteProgram(m_program); throw std::runtime_error("Could not link shader program."); @@ -673,7 +725,7 @@ void glerminal_run(glerminal_init_cb init, glerminal_main_cb main) } catch (const std::runtime_error& e) { - e.what(); + std::cout << e.what() << std::endl; } }