From c9c2ab44cae17043b9404fa5f8bfb2580866dc65 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Tue, 11 Aug 2015 01:56:12 +0200 Subject: [PATCH 1/5] use ARRAYSIZE --- hw/xbox/nv2a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 6f3f4c0434..800e202d29 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -4959,7 +4959,7 @@ static void pgraph_method(NV2AState *d, pg->draw_arrays_max_count = MAX(pg->draw_arrays_max_count, start + count); - assert(pg->draw_arrays_length < sizeof(pg->gl_draw_arrays_start) / sizeof(pg->gl_draw_arrays_start[0])); + assert(pg->draw_arrays_length < ARRAYSIZE(pg->gl_draw_arrays_start)); /* Attempt to connect primitives */ if (pg->draw_arrays_length > 0) { From 4f441ad6e07b445cd1bdb908d772f19a8e7aaa19 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Tue, 11 Aug 2015 01:59:22 +0200 Subject: [PATCH 2/5] Use v0 to v15 instead of custom attribs --- hw/xbox/nv2a_shaders.c | 63 +++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/hw/xbox/nv2a_shaders.c b/hw/xbox/nv2a_shaders.c index 7e5495b158..3b08e8eabd 100644 --- a/hw/xbox/nv2a_shaders.c +++ b/hw/xbox/nv2a_shaders.c @@ -90,24 +90,34 @@ static QString* generate_fixed_function(const ShaderState state, qstring_append(s, "#version 330\n" "\n" -"in vec4 position;\n" -"in vec4 weight;\n" -"in vec3 normal;\n" -"in vec4 diffuse;\n" -"in vec4 specular;\n" -"in float fogCoord;\n" -"in vec4 backDiffuse;\n" -"in vec4 backSpecular;\n" -"in vec4 texture0;\n" -"in vec4 texture1;\n" -"in vec4 texture2;\n" -"in vec4 texture3;\n" +"#define position v0\n" +"#define weight v1\n" +"#define normal v2.xyz\n" +"#define diffuse v3\n" +"#define specular v4\n" +"#define fogCoord v5.x\n" +"#define pointSize v6\n" +"#define backDiffuse v7\n" +"#define backSpecular v8\n" +"#define texture0 v9\n" +"#define texture1 v10\n" +"#define texture2 v11\n" +"#define texture3 v12\n" +"#define reserved1 v13\n" +"#define reserved2 v14\n" +"#define reserved3 v15\n" "\n"); - qstring_append(s, STRUCT_VERTEX_DATA); + for(i = 0; i < 16; i++) { + qstring_append_fmt(s, "in vec4 v%d;\n", i); + } + + qstring_append(s, "\n" + STRUCT_VERTEX_DATA); qstring_append_fmt(s, "noperspective out VertexData %c_vtx;\n", out_prefix); qstring_append_fmt(s, "#define vtx %c_vtx", out_prefix); + qstring_append(s, "\n" /* FIXME: Add these uniforms using code when they are used */ @@ -330,28 +340,11 @@ ShaderBinding* generate_shaders(const ShaderState state) } - if (state.fixed_function) { - /* bind fixed function vertex attributes */ - glBindAttribLocation(program, NV2A_VERTEX_ATTR_POSITION, "position"); - glBindAttribLocation(program, NV2A_VERTEX_ATTR_WEIGHT, "weight"); - glBindAttribLocation(program, NV2A_VERTEX_ATTR_DIFFUSE, "diffuse"); - glBindAttribLocation(program, NV2A_VERTEX_ATTR_SPECULAR, "specular"); - glBindAttribLocation(program, NV2A_VERTEX_ATTR_FOG, "fog"); - glBindAttribLocation(program, NV2A_VERTEX_ATTR_BACK_DIFFUSE, "backDiffuse"); - glBindAttribLocation(program, NV2A_VERTEX_ATTR_BACK_SPECULAR, "backSpecular"); - glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE0, "texture0"); - glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE1, "texture1"); - glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE2, "texture2"); - glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE3, "texture3"); - } else if (state.vertex_program) { - /* Bind attributes for transform program*/ - char tmp[8]; - for(i = 0; i < 16; i++) { - snprintf(tmp, sizeof(tmp), "v%d", i); - glBindAttribLocation(program, i, tmp); - } - } else { - assert(false); + /* Bind attributes for vertices */ + char tmp[8]; + for(i = 0; i < 16; i++) { + snprintf(tmp, sizeof(tmp), "v%d", i); + glBindAttribLocation(program, i, tmp); } From 725a8e14b602db92c01fa411724b89d612dcd9ff Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Tue, 11 Aug 2015 02:41:16 +0200 Subject: [PATCH 3/5] Move back NV2A_VERTEX_ATTR_* to nv2a.c --- hw/xbox/nv2a.c | 18 ++++++++++++++++++ hw/xbox/nv2a_shaders.h | 17 ----------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 800e202d29..8e2d5432e8 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -1269,6 +1269,24 @@ static const SurfaceColorFormatInfo kelvin_surface_color_format_map[] = { {4, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, }; +#define NV2A_VERTEX_ATTR_POSITION 0 +#define NV2A_VERTEX_ATTR_WEIGHT 1 +#define NV2A_VERTEX_ATTR_NORMAL 2 +#define NV2A_VERTEX_ATTR_DIFFUSE 3 +#define NV2A_VERTEX_ATTR_SPECULAR 4 +#define NV2A_VERTEX_ATTR_FOG 5 +#define NV2A_VERTEX_ATTR_POINT_SIZE 6 +#define NV2A_VERTEX_ATTR_BACK_DIFFUSE 7 +#define NV2A_VERTEX_ATTR_BACK_SPECULAR 8 +#define NV2A_VERTEX_ATTR_TEXTURE0 9 +#define NV2A_VERTEX_ATTR_TEXTURE1 10 +#define NV2A_VERTEX_ATTR_TEXTURE2 11 +#define NV2A_VERTEX_ATTR_TEXTURE3 12 +#define NV2A_VERTEX_ATTR_RESERVED1 13 +#define NV2A_VERTEX_ATTR_RESERVED2 14 +#define NV2A_VERTEX_ATTR_RESERVED3 15 + + #define NV2A_CRYSTAL_FREQ 13500000 #define NV2A_NUM_CHANNELS 32 #define NV2A_NUM_SUBCHANNELS 8 diff --git a/hw/xbox/nv2a_shaders.h b/hw/xbox/nv2a_shaders.h index 54d40fb4cc..56f82b8707 100644 --- a/hw/xbox/nv2a_shaders.h +++ b/hw/xbox/nv2a_shaders.h @@ -27,23 +27,6 @@ #include "nv2a_vsh.h" #include "nv2a_psh.h" -#define NV2A_VERTEX_ATTR_POSITION 0 -#define NV2A_VERTEX_ATTR_WEIGHT 1 -#define NV2A_VERTEX_ATTR_NORMAL 2 -#define NV2A_VERTEX_ATTR_DIFFUSE 3 -#define NV2A_VERTEX_ATTR_SPECULAR 4 -#define NV2A_VERTEX_ATTR_FOG 5 -#define NV2A_VERTEX_ATTR_POINT_SIZE 6 -#define NV2A_VERTEX_ATTR_BACK_DIFFUSE 7 -#define NV2A_VERTEX_ATTR_BACK_SPECULAR 8 -#define NV2A_VERTEX_ATTR_TEXTURE0 9 -#define NV2A_VERTEX_ATTR_TEXTURE1 10 -#define NV2A_VERTEX_ATTR_TEXTURE2 11 -#define NV2A_VERTEX_ATTR_TEXTURE3 12 -#define NV2A_VERTEX_ATTR_RESERVED1 13 -#define NV2A_VERTEX_ATTR_RESERVED2 14 -#define NV2A_VERTEX_ATTR_RESERVED3 15 - #define NV2A_MAX_TRANSFORM_PROGRAM_LENGTH 136 #define NV2A_VERTEXSHADER_CONSTANTS 192 From 848eaf2b743c861da48d6cf78d2988c2a92f9aba Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Tue, 11 Aug 2015 01:55:44 +0200 Subject: [PATCH 4/5] Move debug routines and macros to nv2a_debug --- hw/xbox/Makefile.objs | 2 +- hw/xbox/nv2a.c | 79 +--------------------------------------- hw/xbox/nv2a.h | 2 +- hw/xbox/nv2a_debug.c | 81 ++++++++++++++++++++++++++++++++++++++++++ hw/xbox/nv2a_debug.h | 58 ++++++++++++++++++++++++++++++ hw/xbox/nv2a_shaders.c | 8 +---- 6 files changed, 143 insertions(+), 87 deletions(-) create mode 100644 hw/xbox/nv2a_debug.c create mode 100644 hw/xbox/nv2a_debug.h diff --git a/hw/xbox/Makefile.objs b/hw/xbox/Makefile.objs index 84f900713e..636660cd1c 100644 --- a/hw/xbox/Makefile.objs +++ b/hw/xbox/Makefile.objs @@ -2,7 +2,7 @@ obj-y += xbox.o chihiro.o obj-y += xbox_pci.o acpi_xbox.o obj-y += amd_smbus.o smbus_xbox_smc.o smbus_cx25871.o smbus_adm1032.o obj-y += nvnet.o -obj-y += nv2a.o nv2a_vsh.o nv2a_psh.o nv2a_shaders.o +obj-y += nv2a.o nv2a_vsh.o nv2a_psh.o nv2a_shaders.o nv2a_debug.o obj-y += swizzle.o g-lru-cache.o obj-y += mcpx_apu.o mcpx_aci.o obj-y += lpc47m157.o diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 8e2d5432e8..a9c552ff5d 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -34,87 +34,10 @@ #include "hw/xbox/swizzle.h" #include "hw/xbox/u_format_r11g11b10f.h" #include "hw/xbox/nv2a_shaders.h" +#include "hw/xbox/nv2a_debug.h" #include "hw/xbox/nv2a.h" -// #define DEBUG_NV2A -#ifdef DEBUG_NV2A -# define NV2A_DPRINTF(format, ...) printf("nv2a: " format, ## __VA_ARGS__) -#else -# define NV2A_DPRINTF(format, ...) do { } while (0) -#endif - -// #define DEBUG_NV2A_GL -#ifdef DEBUG_NV2A_GL - -static void gl_debug_message(bool cc, const char *fmt, ...) -{ - size_t n; - char buffer[1024]; - va_list ap; - va_start(ap, fmt); - n = vsnprintf(buffer, sizeof(buffer), fmt, ap); - assert(n <= sizeof(buffer)); - va_end(ap); - glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, - 0, GL_DEBUG_SEVERITY_NOTIFICATION, n, buffer); - if (cc) { - fwrite(buffer, sizeof(char), n, stdout); - fputc('\n', stdout); - } -} - -static void gl_debug_group_begin(const char *fmt, ...) -{ - size_t n; - char buffer[1024]; - va_list ap; - va_start(ap, fmt); - n = vsnprintf(buffer, sizeof(buffer), fmt, ap); - assert(n <= sizeof(buffer)); - va_end(ap); - - /* Check for errors before entering group */ - assert(glGetError() == GL_NO_ERROR); - glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, n, buffer); -} - -static void gl_debug_group_end(void) -{ - /* Check for errors when leaving group */ - assert(glGetError() == GL_NO_ERROR); - glPopDebugGroup(); -} - -static void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...) -{ - size_t n; - char buffer[1024]; - va_list ap; - va_start(ap, fmt); - n = vsnprintf(buffer, sizeof(buffer), fmt, ap); - assert(n <= sizeof(buffer)); - va_end(ap); - - glObjectLabel(target, name, n, buffer); -} - -# define NV2A_GL_DPRINTF(cc, format, ...) \ - gl_debug_message(cc, "nv2a: " format, ## __VA_ARGS__) -# define NV2A_GL_DGROUP_BEGIN(format, ...) \ - gl_debug_group_begin("nv2a: " format, ## __VA_ARGS__) -# define NV2A_GL_DGROUP_END() \ - gl_debug_group_end() -# define NV2A_GL_DLABEL(target, name, format, ...) \ - gl_debug_label(target, name, "nv2a: { " format " }", ## __VA_ARGS__) - -#else -# define NV2A_GL_DPRINTF(cc, format, ...) do { } while (0) -# define NV2A_GL_DGROUP_BEGIN(format, ...) do { } while (0) -# define NV2A_GL_DGROUP_END() do { } while (0) -# define NV2A_GL_DLABEL(target, name, format, ...) do { } while (0) -#endif - #define USE_TEXTURE_CACHE #define NV_NUM_BLOCKS 21 diff --git a/hw/xbox/nv2a.h b/hw/xbox/nv2a.h index 281e4cbbad..24b665aad7 100644 --- a/hw/xbox/nv2a.h +++ b/hw/xbox/nv2a.h @@ -22,4 +22,4 @@ void nv2a_init(PCIBus *bus, int devfn, MemoryRegion *ram); -#endif \ No newline at end of file +#endif diff --git a/hw/xbox/nv2a_debug.c b/hw/xbox/nv2a_debug.c new file mode 100644 index 0000000000..63f107644d --- /dev/null +++ b/hw/xbox/nv2a_debug.c @@ -0,0 +1,81 @@ +/* + * QEMU Geforce NV2A debug helpers + * + * Copyright (c) 2015 Jannik Vogel + * Copyright (c) 2012 espes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "hw/xbox/nv2a_debug.h" + +#ifdef DEBUG_NV2A_GL + +#include +#include +#include + +void gl_debug_message(bool cc, const char *fmt, ...) +{ + size_t n; + char buffer[1024]; + va_list ap; + va_start(ap, fmt); + n = vsnprintf(buffer, sizeof(buffer), fmt, ap); + assert(n <= sizeof(buffer)); + va_end(ap); + glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, + 0, GL_DEBUG_SEVERITY_NOTIFICATION, n, buffer); + if (cc) { + fwrite(buffer, sizeof(char), n, stdout); + fputc('\n', stdout); + } +} + +void gl_debug_group_begin(const char *fmt, ...) +{ + size_t n; + char buffer[1024]; + va_list ap; + va_start(ap, fmt); + n = vsnprintf(buffer, sizeof(buffer), fmt, ap); + assert(n <= sizeof(buffer)); + va_end(ap); + + /* Check for errors before entering group */ + assert(glGetError() == GL_NO_ERROR); + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, n, buffer); +} + +void gl_debug_group_end(void) +{ + /* Check for errors when leaving group */ + assert(glGetError() == GL_NO_ERROR); + glPopDebugGroup(); +} + +void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...) +{ + size_t n; + char buffer[1024]; + va_list ap; + va_start(ap, fmt); + n = vsnprintf(buffer, sizeof(buffer), fmt, ap); + assert(n <= sizeof(buffer)); + va_end(ap); + + glObjectLabel(target, name, n, buffer); +} + +#endif diff --git a/hw/xbox/nv2a_debug.h b/hw/xbox/nv2a_debug.h new file mode 100644 index 0000000000..2ec727845b --- /dev/null +++ b/hw/xbox/nv2a_debug.h @@ -0,0 +1,58 @@ +/* + * QEMU Geforce NV2A debug helpers + * + * Copyright (c) 2015 Jannik Vogel + * Copyright (c) 2012 espes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HW_NV2A_DEBUG_H +#define HW_NV2A_DEBUG_H + +// #define DEBUG_NV2A +#ifdef DEBUG_NV2A +# define NV2A_DPRINTF(format, ...) printf("nv2a: " format, ## __VA_ARGS__) +#else +# define NV2A_DPRINTF(format, ...) do { } while (0) +#endif + +// #define DEBUG_NV2A_GL +#ifdef DEBUG_NV2A_GL + +#include +#include "gl/gloffscreen.h" + +void gl_debug_message(bool cc, const char *fmt, ...); +void gl_debug_group_begin(const char *fmt, ...); +void gl_debug_group_end(void); +void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...); + +# define NV2A_GL_DPRINTF(cc, format, ...) \ + gl_debug_message(cc, "nv2a: " format, ## __VA_ARGS__) +# define NV2A_GL_DGROUP_BEGIN(format, ...) \ + gl_debug_group_begin("nv2a: " format, ## __VA_ARGS__) +# define NV2A_GL_DGROUP_END() \ + gl_debug_group_end() +# define NV2A_GL_DLABEL(target, name, format, ...) \ + gl_debug_label(target, name, "nv2a: { " format " }", ## __VA_ARGS__) + +#else +# define NV2A_GL_DPRINTF(cc, format, ...) do { } while (0) +# define NV2A_GL_DGROUP_BEGIN(format, ...) do { } while (0) +# define NV2A_GL_DGROUP_END() do { } while (0) +# define NV2A_GL_DLABEL(target, name, format, ...) do { } while (0) +#endif + +#endif diff --git a/hw/xbox/nv2a_shaders.c b/hw/xbox/nv2a_shaders.c index 3b08e8eabd..95780dd560 100644 --- a/hw/xbox/nv2a_shaders.c +++ b/hw/xbox/nv2a_shaders.c @@ -19,16 +19,10 @@ */ #include "qemu-common.h" +#include "hw/xbox/nv2a_debug.h" #include "hw/xbox/nv2a_shaders_common.h" #include "hw/xbox/nv2a_shaders.h" -// #define NV2A_DEBUG -#ifdef NV2A_DEBUG -# define NV2A_DPRINTF(format, ...) printf("nv2a: " format, ## __VA_ARGS__) -#else -# define NV2A_DPRINTF(format, ...) do { } while (0) -#endif - static void generate_geometry_shader_pass_vertex(QString* s, const char* v) { qstring_append_fmt(s, " gl_Position = gl_in[%s].gl_Position;\n", v); From 0260b29578c2ea3ee2c48916f69047fe81599105 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Tue, 11 Aug 2015 02:01:16 +0200 Subject: [PATCH 5/5] Split GLSL compilation into function --- hw/xbox/nv2a_shaders.c | 93 ++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 49 deletions(-) diff --git a/hw/xbox/nv2a_shaders.c b/hw/xbox/nv2a_shaders.c index 95780dd560..936d9cad4b 100644 --- a/hw/xbox/nv2a_shaders.c +++ b/hw/xbox/nv2a_shaders.c @@ -284,10 +284,42 @@ static QString* generate_fixed_function(const ShaderState state, return s; } +static GLuint create_gl_shader(GLenum gl_shader_type, + const char *code, + const char *name) +{ + GLint compiled = 0; + + NV2A_GL_DGROUP_BEGIN("Creating new %s", name); + + GLuint shader = glCreateShader(gl_shader_type); + glShaderSource(shader, 1, &code, 0); + glCompileShader(shader); + + /* Check it compiled */ + compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLchar* log; + GLint log_length; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length); + log = g_malloc(log_length * sizeof(GLchar)); + glGetShaderInfoLog(shader, log_length, NULL, log); + fprintf(stderr, "nv2a: %s compilation failed: %s\n", name, log); + g_free(log); + + NV2A_GL_DGROUP_END(); + abort(); + } + + NV2A_GL_DGROUP_END(); + + return shader; +} + ShaderBinding* generate_shaders(const ShaderState state) { int i, j; - GLint compiled = 0; bool with_geom = state.primitive_mode == PRIM_TYPE_QUADS; char vtx_prefix = with_geom ? 'v' : 'g'; @@ -312,24 +344,11 @@ ShaderBinding* generate_shaders(const ShaderState state) if (vertex_shader_code) { const char* vertex_shader_code_str = qstring_get_str(vertex_shader_code); - GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + GLuint vertex_shader = create_gl_shader(GL_VERTEX_SHADER, + vertex_shader_code_str, + "vertex shader"); glAttachShader(program, vertex_shader); - glShaderSource(vertex_shader, 1, &vertex_shader_code_str, 0); - glCompileShader(vertex_shader); - - NV2A_DPRINTF("bind new vertex shader, code:\n%s\n", vertex_shader_code_str); - - /* Check it compiled */ - compiled = 0; - glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - GLchar log[1024]; - glGetShaderInfoLog(vertex_shader, 1024, NULL, log); - fprintf(stderr, "nv2a: vertex shader compilation failed: %s\n", log); - abort(); - } - QDECREF(vertex_shader_code); } @@ -343,8 +362,6 @@ ShaderBinding* generate_shaders(const ShaderState state) /* generate a fragment shader from register combiners */ - GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); - glAttachShader(program, fragment_shader); QString *fragment_shader_code = psh_translate(state.combiner_control, state.shader_stage_program, @@ -361,46 +378,24 @@ ShaderBinding* generate_shaders(const ShaderState state) const char *fragment_shader_code_str = qstring_get_str(fragment_shader_code); - NV2A_DPRINTF("bind new fragment shader, code:\n%s\n", fragment_shader_code_str); - - glShaderSource(fragment_shader, 1, &fragment_shader_code_str, 0); - glCompileShader(fragment_shader); - - /* Check it compiled */ - glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - GLchar log[1024]; - glGetShaderInfoLog(fragment_shader, 1024, NULL, log); - fprintf(stderr, "nv2a: fragment shader compilation failed: %s\n", log); - abort(); - } + GLuint fragment_shader = create_gl_shader(GL_FRAGMENT_SHADER, + fragment_shader_code_str, + "fragment shader"); + glAttachShader(program, fragment_shader); QDECREF(fragment_shader_code); if (with_geom) { - GLuint geometry_shader = glCreateShader(GL_GEOMETRY_SHADER); - glAttachShader(program, geometry_shader); - QString* geometry_shader_code = generate_geometry_shader(state.primitive_mode); const char* geometry_shader_code_str = qstring_get_str(geometry_shader_code); - NV2A_DPRINTF("bind geometry shader, code:\n%s\n", geometry_shader_code_str); - - glShaderSource(geometry_shader, 1, &geometry_shader_code_str, 0); - glCompileShader(geometry_shader); - - /* Check it compiled */ - compiled = 0; - glGetShaderiv(geometry_shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - GLchar log[2048]; - glGetShaderInfoLog(geometry_shader, 2048, NULL, log); - fprintf(stderr, "nv2a: geometry shader compilation failed: %s\n", log); - abort(); - } + GLuint geometry_shader = create_gl_shader(GL_GEOMETRY_SHADER, + geometry_shader_code_str, + "geometry shader"); + glAttachShader(program, geometry_shader); QDECREF(geometry_shader_code); }