From c77b257094b15e7c53b62cb50bfbcd7c5003f2a8 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 7 Apr 2010 16:59:46 -0700 Subject: [PATCH] Add support for GL_ARB_draw_buffers extension --- glsl_parser_extras.cpp | 9 +++++++++ glsl_parser_extras.h | 8 ++++++++ ir_variable.cpp | 43 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/glsl_parser_extras.cpp b/glsl_parser_extras.cpp index 6cd69c8b882..553cd675a7a 100644 --- a/glsl_parser_extras.cpp +++ b/glsl_parser_extras.cpp @@ -126,6 +126,15 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, ? "enable" : "require"); return false; } + } if (strcmp(name, "GL_ARB_draw_buffers") == 0) { + /* This extension is only supported in fragment shaders. + */ + if (state->target != fragment_shader) { + unsupported = true; + } else { + state->ARB_draw_buffers_enable = (ext_mode != extension_disable); + state->ARB_draw_buffers_warn = (ext_mode == extension_warn); + } } else { unsupported = true; } diff --git a/glsl_parser_extras.h b/glsl_parser_extras.h index 7759eda535f..51e4eb89ccf 100644 --- a/glsl_parser_extras.h +++ b/glsl_parser_extras.h @@ -59,6 +59,14 @@ struct _mesa_glsl_parse_state { /** Loop or switch statement containing the current instructions. */ class ir_instruction *loop_or_switch_nesting; + + /** + * \name Enable bits for GLSL extensions + */ + /*@{*/ + unsigned ARB_draw_buffers_enable:1; + unsigned ARB_draw_buffers_warn:1; + /*@}*/ }; typedef struct YYLTYPE { diff --git a/ir_variable.cpp b/ir_variable.cpp index 41359b56162..76a528ca2be 100644 --- a/ir_variable.cpp +++ b/ir_variable.cpp @@ -30,7 +30,7 @@ #define Elements(x) (sizeof(x)/sizeof(*(x))) #endif -static void +static ir_variable * add_variable(const char *name, enum ir_variable_mode mode, const glsl_type *type, exec_list *instructions, glsl_symbol_table *symtab) @@ -48,6 +48,7 @@ add_variable(const char *name, enum ir_variable_mode mode, instructions->push_tail(var); symtab->add_variable(var->name, var); + return var; } @@ -197,8 +198,6 @@ generate_110_fs_variables(exec_list *instructions, } generate_110_uniforms(instructions, symtab); - /* FINISHME: Add support for gl_FragData[GL_MAX_DRAW_BUFFERS]. */ - /* FINISHME: The size of this array is implementation dependent based on the * FINISHME: value of GL_MAX_TEXTURE_COORDS. GL_MAX_TEXTURE_COORDS must be * FINISHME: at least 2, so hard-code 2 for now. @@ -212,14 +211,35 @@ generate_110_fs_variables(exec_list *instructions, symtab); } + +static void +generate_ARB_draw_buffers_fs_variables(exec_list *instructions, + glsl_symbol_table *symtab, bool warn) +{ + /* FINISHME: The size of this array is implementation dependent based on the + * FINISHME: value of GL_MAX_DRAW_BUFFERS. GL_MAX_DRAW_BUFFERS must be + * FINISHME: at least 1, so hard-code 1 for now. + */ + const glsl_type *const vec4_type = + glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1); + const glsl_type *const vec4_array_type = + glsl_type::get_array_instance(vec4_type, 1); + + ir_variable *const fd = + add_variable("gl_FragData", ir_var_out, vec4_array_type, instructions, + symtab); + + if (warn) + fd->warn_extension = "GL_ARB_draw_buffers"; +} + + static void generate_120_fs_variables(exec_list *instructions, glsl_symbol_table *symtab) { - /* GLSL version 1.20 did not add any built-in variables in the fragment - * shader. - */ generate_110_fs_variables(instructions, symtab); + generate_ARB_draw_buffers_fs_variables(instructions, symtab, false); } static void @@ -253,6 +273,17 @@ initialize_fs_variables(exec_list *instructions, generate_130_fs_variables(instructions, state->symbols); break; } + + + /* Since GL_ARB_draw_buffers is included in GLSL 1.20 and later, we + * can basically ignore any extension settings for it. + */ + if (state->language_version < 120) { + if (state->ARB_draw_buffers_enable) { + generate_ARB_draw_buffers_fs_variables(instructions, state->symbols, + state->ARB_draw_buffers_warn); + } + } } void -- 2.30.2