[Mesa-dev] [PATCH 6/9] glsl: parser now aware of UBO
vlj
vljn at ovi.com
Fri Sep 23 06:53:11 PDT 2011
---
src/glsl/ast.h | 25 ++++++
src/glsl/ast_to_hir.cpp | 43 ++++++++++-
src/glsl/glsl_parser.yy | 162 +++++++++++++++++++++++++++++++++++++++
src/glsl/glsl_parser_extras.h | 5 +
src/mesa/program/ir_to_mesa.cpp | 5 +
5 files changed, 239 insertions(+), 1 deletions(-)
diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index d1de227..81ba927 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -351,6 +351,15 @@ struct ast_type_qualifier {
*/
unsigned explicit_location:1;
+ /** UBO Layout, should be 2 enum but using bit instead
+ * to be coherent with struct definition
+ */
+ unsigned std140:1;
+ unsigned packed:1;
+ unsigned shared:1;
+ unsigned column_major:1;
+ unsigned row_major:1;
+
/** \name Layout qualifiers for GL_AMD_conservative_depth */
/** \{ */
unsigned depth_any:1;
@@ -538,6 +547,22 @@ public:
int invariant;
};
+class ast_uniform_buffer_object : public ast_node {
+public:
+ ast_uniform_buffer_object(ast_declarator_list* adl,char* block_name=NULL, ast_expression* block_length=NULL) : components(adl),name(block_name),length(block_length) {
+
+ }
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+ ast_declarator_list* components;
+ ast_type_qualifier layout_qualifier;
+ const char* name;
+ ast_expression* length;
+
+};
+
class ast_parameter_declarator : public ast_node {
public:
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 9e7496b..13e60fd 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -82,6 +82,7 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
* by the linker.
*/
state->symbols->push_scope();
+ state->ubo_count = 0;
foreach_list_typed (ast_node, ast, link, & state->translation_unit)
ast->hir(instructions, state);
@@ -1892,8 +1893,11 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
else if (qual->flags.q.out
|| (qual->flags.q.varying && (state->target == vertex_shader)))
var->mode = ir_var_out;
- else if (qual->flags.q.uniform)
+ else if (qual->flags.q.uniform) {
var->mode = ir_var_uniform;
+ var->UBO = NULL;
+ var->removable_uniform = true;
+ }
if (state->all_invariant && (state->current_function == NULL)) {
switch (state->target) {
@@ -2812,6 +2816,43 @@ ast_declarator_list::hir(exec_list *instructions,
return result;
}
+ir_rvalue *
+ast_uniform_buffer_object::hir(exec_list *instructions, _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+ YYLTYPE loc = this->get_location();
+
+ ir_rvalue* result = components->hir(instructions,state);
+
+ /** Count the number or variable in UBO.
+ * Could be done inside ast_declarator_list::hir
+ */
+ int var_count = 0;
+ foreach_list_typed (ast_declaration, decl, link, &this->components->declarations) {
+ var_count++;
+ }
+
+ ubo& current_ubo = state->UniformBufferObjects[state->ubo_count];
+ current_ubo.number_of_variables = var_count;
+ current_ubo.storage_layout = (UBOVariableInfo*) malloc(var_count * sizeof(UBOVariableInfo));
+ current_ubo.name = strdup(this->name);
+
+ int var_position = 0;
+ foreach_list_typed (ast_declaration, decl, link, &this->components->declarations) {
+ ir_variable* var = state->symbols->get_variable(decl->identifier);
+ var->mode = ir_var_uniform;
+ var->removable_uniform = false;
+ current_ubo.storage_layout[var_position].name = strdup(decl->identifier);
+ current_ubo.storage_layout[var_position].Type = var->type;
+ current_ubo.storage_layout[var_position].index = var_position;
+
+ var_position++;
+ }
+ state->ubo_count++;
+
+ return result;
+}
+
ir_rvalue *
ast_parameter_declarator::hir(exec_list *instructions,
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 25d02fb..feb98c7 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -67,6 +67,7 @@
ast_declarator_list *declarator_list;
ast_struct_specifier *struct_specifier;
ast_declaration *declaration;
+ ast_uniform_buffer_object *uniform_buffer_object;
struct {
ast_node *cond;
@@ -195,6 +196,11 @@
%type <node> external_declaration
%type <declarator_list> init_declarator_list
%type <declarator_list> single_declaration
+%type <uniform_buffer_object> uniform_buffer_object
+%type <uniform_buffer_object> uniform_buffer_object_block
+%type <declarator_list> uniform_buffer_object_declaration_list
+%type <declarator_list> ubo_variables_declarator_list
+%type <declarator_list> ubo_single_declaration
%type <expression> initializer
%type <node> declaration
%type <node> declaration_statement
@@ -777,6 +783,10 @@ declaration:
$3->is_precision_statement = true;
$$ = $3;
}
+ | uniform_buffer_object ';'
+ {
+ $$ = $1;
+ }
;
function_prototype:
@@ -1042,6 +1052,134 @@ single_declaration:
}
;
+
+
+uniform_buffer_object:
+ uniform_buffer_object_block
+ {
+ $$ = $1;
+ }
+ | layout_qualifier uniform_buffer_object_block
+ {
+ $2->layout_qualifier = $1;
+ $$ = $2;
+ }
+ | uniform_buffer_object_block any_identifier
+ {
+ $$ = $1;
+ }
+ | layout_qualifier uniform_buffer_object_block any_identifier
+ {
+ $2->layout_qualifier = $1;
+ $$ = $2;
+ }
+ | uniform_buffer_object_block any_identifier '[' constant_expression ']'
+ {
+ $$ = $1;
+ }
+ | layout_qualifier uniform_buffer_object_block any_identifier '[' constant_expression ']'
+ {
+ $2->layout_qualifier = $1;
+ $$ = $2;
+ }
+;
+
+// IDENTIFIER is more accurate than any_identifier, resulting in absence of shift/reduce conflict
+uniform_buffer_object_block:
+ UNIFORM NEW_IDENTIFIER '{' uniform_buffer_object_declaration_list '}'
+ {
+ void *ctx = state;
+ ast_uniform_buffer_object *ubo = new (ctx) ast_uniform_buffer_object($4,$2);
+ $$ = ubo;
+ }
+;
+
+
+uniform_buffer_object_declaration_list:
+ ubo_variables_declarator_list ';'
+ {
+ $$ = $1;
+ }
+ | uniform_buffer_object_declaration_list ubo_variables_declarator_list ';'
+ {
+ $1->declarations.append_list(&($2->declarations));
+ $$ = $1;
+ }
+;
+
+// No initializer here...
+ubo_variables_declarator_list:
+ ubo_single_declaration
+ | ubo_variables_declarator_list ',' any_identifier
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL);
+ decl->set_location(yylloc);
+
+ $$ = $1;
+ $$->declarations.push_tail(&decl->link);
+ state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+ }
+ | ubo_variables_declarator_list ',' any_identifier '[' ']'
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL);
+ decl->set_location(yylloc);
+
+ $$ = $1;
+ $$->declarations.push_tail(&decl->link);
+ state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+ }
+ | ubo_variables_declarator_list ',' any_identifier '[' constant_expression ']'
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL);
+ decl->set_location(yylloc);
+
+ $$ = $1;
+ $$->declarations.push_tail(&decl->link);
+ state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+ }
+ ;
+
+// No initializer here
+ubo_single_declaration:
+ fully_specified_type
+ {
+ void *ctx = state;
+ /* Empty declaration list is valid. */
+ $$ = new(ctx) ast_declarator_list($1);
+ $$->set_location(yylloc);
+ }
+ | fully_specified_type any_identifier
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL);
+
+ $$ = new(ctx) ast_declarator_list($1);
+ $$->set_location(yylloc);
+ $$->declarations.push_tail(&decl->link);
+ }
+ | fully_specified_type any_identifier '[' ']'
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL);
+
+ $$ = new(ctx) ast_declarator_list($1);
+ $$->set_location(yylloc);
+ $$->declarations.push_tail(&decl->link);
+ }
+ | fully_specified_type any_identifier '[' constant_expression ']'
+ {
+ void *ctx = state;
+ ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL);
+
+ $$ = new(ctx) ast_declarator_list($1);
+ $$->set_location(yylloc);
+ $$->declarations.push_tail(&decl->link);
+ }
+ ;
+
fully_specified_type:
type_specifier
{
@@ -1134,6 +1272,30 @@ layout_qualifier_id:
}
}
+ /* Layout qualifiers for UBO */
+ if (!got_one) {
+ if (strcmp($1, "std140") == 0) {
+ got_one = true;
+ $$.flags.q.std140 = 1;
+ }
+ else if (strcmp($1, "packed") == 0) {
+ got_one = true;
+ $$.flags.q.packed = 1;
+ }
+ else if (strcmp($1, "shared") == 0) {
+ got_one = true;
+ $$.flags.q.shared = 1;
+ }
+ else if (strcmp($1, "column_major") == 0) {
+ got_one = true;
+ $$.flags.q.column_major = 1;
+ }
+ else if (strcmp($1, "row_major") == 0) {
+ got_one = true;
+ $$.flags.q.row_major = 1;
+ }
+ }
+
if (!got_one) {
_mesa_glsl_error(& @1, state, "unrecognized layout identifier "
"`%s'\n", $1);
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 8f843eb..4a43291 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -42,6 +42,8 @@ enum _mesa_glsl_parser_targets {
struct gl_context;
+#include <main/mtypes.h>
+
struct _mesa_glsl_parse_state {
_mesa_glsl_parse_state(struct gl_context *ctx, GLenum target,
void *mem_ctx);
@@ -196,6 +198,9 @@ struct _mesa_glsl_parse_state {
/** Shaders containing built-in functions that are used for linking. */
struct gl_shader *builtins_to_link[16];
unsigned num_builtins_to_link;
+
+ ubo UniformBufferObjects[MAX_UBO_IN_SHADER];
+ unsigned ubo_count;
};
typedef struct YYLTYPE {
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 6820e4c..65bfc49 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -3370,6 +3370,11 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader)
sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
shader->num_builtins_to_link = state->num_builtins_to_link;
+ shader->UBOCount = state->ubo_count;
+ for(unsigned i = 0; i<state->ubo_count;i++) {
+ shader->UniformBufferObjects[i] = state->UniformBufferObjects[i];
+ }
+
if (ctx->Shader.Flags & GLSL_LOG) {
_mesa_write_shader_to_file(shader);
}
--
1.7.6.3
More information about the mesa-dev
mailing list