diff options
-rw-r--r-- | src/glsl/ir_uniform.h | 34 | ||||
-rw-r--r-- | src/glsl/link_uniforms.cpp | 41 |
2 files changed, 74 insertions, 1 deletions
diff --git a/src/glsl/ir_uniform.h b/src/glsl/ir_uniform.h index 225da3fc5ef..913c5377359 100644 --- a/src/glsl/ir_uniform.h +++ b/src/glsl/ir_uniform.h @@ -119,6 +119,40 @@ struct gl_uniform_storage { * uniform if the \c ::driver_storage interface is not used. */ union gl_constant_value *storage; + + /** Fields for GL_ARB_uniform_buffer_object + * @{ + */ + + /** + * GL_UNIFORM_BLOCK_INDEX: index of the uniform block containing + * the uniform, or -1 for the default uniform block. Note that the + * index is into the linked program's UniformBlocks[] array, not + * the linked shader's. + */ + int block_index; + + /** GL_UNIFORM_OFFSET: byte offset within the uniform block, or -1. */ + int offset; + + /** + * GL_UNIFORM_MATRIX_STRIDE: byte stride between columns or rows of + * a matrix. Set to 0 for non-matrices in UBOs, or -1 for uniforms + * in the default uniform block. + */ + int matrix_stride; + + /** + * GL_UNIFORM_ARRAY_STRIDE: byte stride between elements of the + * array. Set to zero for non-arrays in UBOs, or -1 for uniforms + * in the default uniform block. + */ + int array_stride; + + /** GL_UNIFORM_ROW_MAJOR: true iff it's a row-major matrix in a UBO */ + bool row_major; + + /** @} */ }; #ifdef __cplusplus diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp index ff75b8919e9..4cc97cead80 100644 --- a/src/glsl/link_uniforms.cpp +++ b/src/glsl/link_uniforms.cpp @@ -217,6 +217,28 @@ public: this->shader_shadow_samplers = 0; } + void set_and_process(struct gl_shader_program *prog, + ir_variable *var) + { + ubo_var = NULL; + if (var->uniform_block != -1) { + struct gl_uniform_block *block = + &prog->UniformBlocks[var->uniform_block]; + + ubo_block_index = var->uniform_block; + ubo_var_index = var->location; + ubo_var = &block->Uniforms[var->location]; + ubo_byte_offset = ubo_var->Offset; + } + + process(var); + } + + struct gl_uniform_buffer_variable *ubo_var; + int ubo_block_index; + int ubo_var_index; + int ubo_byte_offset; + private: virtual void visit_field(const glsl_type *type, const char *name) { @@ -292,6 +314,23 @@ private: this->uniforms[id].num_driver_storage = 0; this->uniforms[id].driver_storage = NULL; this->uniforms[id].storage = this->values; + if (this->ubo_var) { + this->uniforms[id].block_index = this->ubo_block_index; + + /* FINISHME: Actual std140 offset assignment. */ + this->uniforms[id].offset = this->ubo_byte_offset; + this->ubo_byte_offset += 4 * type->components(); + this->uniforms[id].array_stride = 0; + this->uniforms[id].matrix_stride = 0; + this->uniforms[id].row_major = base_type->is_matrix() && + ubo_var->RowMajor; + } else { + this->uniforms[id].block_index = -1; + this->uniforms[id].offset = -1; + this->uniforms[id].array_stride = -1; + this->uniforms[id].matrix_stride = -1; + this->uniforms[id].row_major = false; + } this->values += values_for_type(type); } @@ -518,7 +557,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog) if (strncmp("gl_", var->name, 3) == 0) continue; - parcel.process(var); + parcel.set_and_process(prog, var); } prog->_LinkedShaders[i]->active_samplers = parcel.shader_samplers_used; |