From 932b0ef1ceecf873213447a8778e5cbe1b3b6be7 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 14 Jul 2014 15:48:38 -0700 Subject: [PATCH] glsl: Use bit-flags image attributes and uint16_t for the image format All of the GL image enums fit in 16-bits. Also move the fields from the anonymous "image" structucture to the next higher structure. This will enable packing the bits with the other bitfield. Valgrind massif results for a trimmed apitrace of dota2: n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B) Before (32-bit): 76 40,572,916,873 68,831,248 63,328,783 5,502,465 0 After (32-bit): 70 40,577,421,777 68,487,584 62,973,695 5,513,889 0 Before (64-bit): 60 36,822,640,058 96,526,824 88,735,296 7,791,528 0 After (64-bit): 74 37,124,603,758 95,891,808 88,466,712 7,425,096 0 A real savings of 346KiB on 32-bit and 262KiB on 64-bit. Signed-off-by: Ian Romanick Reviewed-by: Kenneth Graunke --- src/glsl/ast_function.cpp | 10 +++++----- src/glsl/ast_to_hir.cpp | 14 +++++++------- src/glsl/builtin_functions.cpp | 10 +++++----- src/glsl/ir.cpp | 20 ++++++++++---------- src/glsl/ir.h | 27 +++++++++++++-------------- src/glsl/link_uniforms.cpp | 4 ++-- 6 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 39c7beeb22a..7130d616282 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -103,35 +103,35 @@ verify_image_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state, * qualifiers. [...] It is legal to have additional qualifiers * on a formal parameter, but not to have fewer." */ - if (actual->data.image.coherent && !formal->data.image.coherent) { + if (actual->data.image_coherent && !formal->data.image_coherent) { _mesa_glsl_error(loc, state, "function call parameter `%s' drops " "`coherent' qualifier", formal->name); return false; } - if (actual->data.image._volatile && !formal->data.image._volatile) { + if (actual->data.image_volatile && !formal->data.image_volatile) { _mesa_glsl_error(loc, state, "function call parameter `%s' drops " "`volatile' qualifier", formal->name); return false; } - if (actual->data.image.restrict_flag && !formal->data.image.restrict_flag) { + if (actual->data.image_restrict && !formal->data.image_restrict) { _mesa_glsl_error(loc, state, "function call parameter `%s' drops " "`restrict' qualifier", formal->name); return false; } - if (actual->data.image.read_only && !formal->data.image.read_only) { + if (actual->data.image_read_only && !formal->data.image_read_only) { _mesa_glsl_error(loc, state, "function call parameter `%s' drops " "`readonly' qualifier", formal->name); return false; } - if (actual->data.image.write_only && !formal->data.image.write_only) { + if (actual->data.image_write_only && !formal->data.image_write_only) { _mesa_glsl_error(loc, state, "function call parameter `%s' drops " "`writeonly' qualifier", formal->name); diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 30b02d01662..897505c6053 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2360,11 +2360,11 @@ apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual, "global variables"); } - var->data.image.read_only |= qual->flags.q.read_only; - var->data.image.write_only |= qual->flags.q.write_only; - var->data.image.coherent |= qual->flags.q.coherent; - var->data.image._volatile |= qual->flags.q._volatile; - var->data.image.restrict_flag |= qual->flags.q.restrict_flag; + var->data.image_read_only |= qual->flags.q.read_only; + var->data.image_write_only |= qual->flags.q.write_only; + var->data.image_coherent |= qual->flags.q.coherent; + var->data.image_volatile |= qual->flags.q._volatile; + var->data.image_restrict |= qual->flags.q.restrict_flag; var->data.read_only = true; if (qual->flags.q.explicit_image_format) { @@ -2378,7 +2378,7 @@ apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual, "base data type of the image"); } - var->data.image.format = qual->image_format; + var->data.image_format = qual->image_format; } else { if (var->data.mode == ir_var_uniform && !qual->flags.q.write_only) { _mesa_glsl_error(loc, state, "uniforms not qualified with " @@ -2386,7 +2386,7 @@ apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual, "qualifier"); } - var->data.image.format = GL_NONE; + var->data.image_format = GL_NONE; } } } diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp index c882ec8dd0d..9be7f6d1a76 100644 --- a/src/glsl/builtin_functions.cpp +++ b/src/glsl/builtin_functions.cpp @@ -4476,11 +4476,11 @@ builtin_builder::_image_prototype(const glsl_type *image_type, * accept everything that needs to be accepted, and reject cases * like loads from write-only or stores to read-only images. */ - image->data.image.read_only = flags & IMAGE_FUNCTION_READ_ONLY; - image->data.image.write_only = flags & IMAGE_FUNCTION_WRITE_ONLY; - image->data.image.coherent = true; - image->data.image._volatile = true; - image->data.image.restrict_flag = true; + image->data.image_read_only = (flags & IMAGE_FUNCTION_READ_ONLY) != 0; + image->data.image_write_only = (flags & IMAGE_FUNCTION_WRITE_ONLY) != 0; + image->data.image_coherent = true; + image->data.image_volatile = true; + image->data.image_restrict = true; return sig; } diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index d09ff9e5ffa..b289c29756d 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -1568,11 +1568,11 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name, this->data.interpolation = INTERP_QUALIFIER_NONE; this->data.max_array_access = 0; this->data.atomic.offset = 0; - this->data.image.read_only = false; - this->data.image.write_only = false; - this->data.image.coherent = false; - this->data.image._volatile = false; - this->data.image.restrict_flag = false; + this->data.image_read_only = false; + this->data.image_write_only = false; + this->data.image_coherent = false; + this->data.image_volatile = false; + this->data.image_restrict = false; if (type != NULL) { if (type->base_type == GLSL_TYPE_SAMPLER) @@ -1678,11 +1678,11 @@ ir_function_signature::qualifiers_match(exec_list *params) a->data.interpolation != b->data.interpolation || a->data.centroid != b->data.centroid || a->data.sample != b->data.sample || - a->data.image.read_only != b->data.image.read_only || - a->data.image.write_only != b->data.image.write_only || - a->data.image.coherent != b->data.image.coherent || - a->data.image._volatile != b->data.image._volatile || - a->data.image.restrict_flag != b->data.image.restrict_flag) { + a->data.image_read_only != b->data.image_read_only || + a->data.image_write_only != b->data.image_write_only || + a->data.image_coherent != b->data.image_coherent || + a->data.image_volatile != b->data.image_volatile || + a->data.image_restrict != b->data.image_restrict) { /* parameter a's qualifiers don't match */ return a->name; diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 5032c2610fa..e9051732bcc 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -697,6 +697,19 @@ public: */ unsigned index:1; + + /** + * ARB_shader_image_load_store qualifiers. + */ + unsigned image_read_only:1; /**< "readonly" qualifier. */ + unsigned image_write_only:1; /**< "writeonly" qualifier. */ + unsigned image_coherent:1; + unsigned image_volatile:1; + unsigned image_restrict:1; + + /** Image internal format if specified explicitly, otherwise GL_NONE. */ + uint16_t image_format; + /** * \brief Layout qualifier for gl_FragDepth. * @@ -744,20 +757,6 @@ public: unsigned offset; } atomic; - /** - * ARB_shader_image_load_store qualifiers. - */ - struct { - bool read_only; /**< "readonly" qualifier. */ - bool write_only; /**< "writeonly" qualifier. */ - bool coherent; - bool _volatile; - bool restrict_flag; - - /** Image internal format if specified explicitly, otherwise GL_NONE. */ - GLenum format; - } image; - /** * Highest element accessed with a constant expression array index * diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp index ddb20565866..258d279ea17 100644 --- a/src/glsl/link_uniforms.cpp +++ b/src/glsl/link_uniforms.cpp @@ -829,8 +829,8 @@ link_set_image_access_qualifiers(struct gl_shader_program *prog) (void) found; const gl_uniform_storage *storage = &prog->UniformStorage[id]; const unsigned index = storage->image[i].index; - const GLenum access = (var->data.image.read_only ? GL_READ_ONLY : - var->data.image.write_only ? GL_WRITE_ONLY : + const GLenum access = (var->data.image_read_only ? GL_READ_ONLY : + var->data.image_write_only ? GL_WRITE_ONLY : GL_READ_WRITE); for (unsigned j = 0; j < MAX2(1, storage->array_elements); ++j)