mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 22:00:13 +01:00
glsl: Calculate UBO data at link-time
Use the function added in the previous commit. This temporarily causes gles3conform uniform_buffer_object_index_of_not_active_block, uniform_buffer_object_inherit_and_override_layouts, and uniform_buffer_object_repeat_global_scope_layouts to assertion fail. This is fixed in the next commit. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
parent
0ab7399822
commit
514f8c7ec7
3 changed files with 44 additions and 77 deletions
|
|
@ -4187,25 +4187,6 @@ ast_struct_specifier::hir(exec_list *instructions,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct gl_uniform_block *
|
|
||||||
get_next_uniform_block(struct _mesa_glsl_parse_state *state)
|
|
||||||
{
|
|
||||||
if (state->num_uniform_blocks >= state->uniform_block_array_size) {
|
|
||||||
state->uniform_block_array_size *= 2;
|
|
||||||
if (state->uniform_block_array_size <= 4)
|
|
||||||
state->uniform_block_array_size = 4;
|
|
||||||
|
|
||||||
state->uniform_blocks = reralloc(state,
|
|
||||||
state->uniform_blocks,
|
|
||||||
struct gl_uniform_block,
|
|
||||||
state->uniform_block_array_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&state->uniform_blocks[state->num_uniform_blocks],
|
|
||||||
0, sizeof(*state->uniform_blocks));
|
|
||||||
return &state->uniform_blocks[state->num_uniform_blocks++];
|
|
||||||
}
|
|
||||||
|
|
||||||
ir_rvalue *
|
ir_rvalue *
|
||||||
ast_uniform_block::hir(exec_list *instructions,
|
ast_uniform_block::hir(exec_list *instructions,
|
||||||
struct _mesa_glsl_parse_state *state)
|
struct _mesa_glsl_parse_state *state)
|
||||||
|
|
@ -4216,17 +4197,15 @@ ast_uniform_block::hir(exec_list *instructions,
|
||||||
* need to turn those into ir_variables with an association
|
* need to turn those into ir_variables with an association
|
||||||
* with this uniform block.
|
* with this uniform block.
|
||||||
*/
|
*/
|
||||||
struct gl_uniform_block *ubo = get_next_uniform_block(state);
|
enum glsl_interface_packing packing;
|
||||||
ubo->Name = ralloc_strdup(state->uniform_blocks, this->block_name);
|
|
||||||
|
|
||||||
if (this->layout.flags.q.shared) {
|
if (this->layout.flags.q.shared) {
|
||||||
ubo->_Packing = ubo_packing_shared;
|
packing = GLSL_INTERFACE_PACKING_SHARED;
|
||||||
} else if (this->layout.flags.q.packed) {
|
} else if (this->layout.flags.q.packed) {
|
||||||
ubo->_Packing = ubo_packing_packed;
|
packing = GLSL_INTERFACE_PACKING_PACKED;
|
||||||
} else {
|
} else {
|
||||||
/* The default layout is std140.
|
/* The default layout is std140.
|
||||||
*/
|
*/
|
||||||
ubo->_Packing = ubo_packing_std140;
|
packing = GLSL_INTERFACE_PACKING_STD140;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool block_row_major = this->layout.flags.q.row_major;
|
bool block_row_major = this->layout.flags.q.row_major;
|
||||||
|
|
@ -4241,17 +4220,10 @@ ast_uniform_block::hir(exec_list *instructions,
|
||||||
true,
|
true,
|
||||||
block_row_major);
|
block_row_major);
|
||||||
|
|
||||||
STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD140)
|
|
||||||
== unsigned(ubo_packing_std140));
|
|
||||||
STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_SHARED)
|
|
||||||
== unsigned(ubo_packing_shared));
|
|
||||||
STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_PACKED)
|
|
||||||
== unsigned(ubo_packing_packed));
|
|
||||||
|
|
||||||
const glsl_type *block_type =
|
const glsl_type *block_type =
|
||||||
glsl_type::get_interface_instance(fields,
|
glsl_type::get_interface_instance(fields,
|
||||||
num_variables,
|
num_variables,
|
||||||
(enum glsl_interface_packing) ubo->_Packing,
|
packing,
|
||||||
this->block_name);
|
this->block_name);
|
||||||
|
|
||||||
if (!state->symbols->add_type(block_type->name, block_type)) {
|
if (!state->symbols->add_type(block_type->name, block_type)) {
|
||||||
|
|
@ -4310,24 +4282,6 @@ ast_uniform_block::hir(exec_list *instructions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FINISHME: Eventually the rest of this code needs to be moved into the
|
|
||||||
* FINISHME: linker.
|
|
||||||
*/
|
|
||||||
ubo->Uniforms = rzalloc_array(state->uniform_blocks,
|
|
||||||
struct gl_uniform_buffer_variable,
|
|
||||||
num_variables);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < num_variables; i++) {
|
|
||||||
struct gl_uniform_buffer_variable *ubo_var =
|
|
||||||
&ubo->Uniforms[ubo->NumUniforms++];
|
|
||||||
|
|
||||||
ubo_var->Name = ralloc_strdup(state->uniform_blocks, fields[i].name);
|
|
||||||
ubo_var->IndexName = ubo_var->Name;
|
|
||||||
ubo_var->Type = fields[i].type;
|
|
||||||
ubo_var->Offset = 0; /* Assigned at link time. */
|
|
||||||
ubo_var->RowMajor = fields[i].row_major;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -539,10 +539,41 @@ link_update_uniform_buffer_variables(struct gl_shader *shader)
|
||||||
|
|
||||||
assert(var->mode == ir_var_uniform);
|
assert(var->mode == ir_var_uniform);
|
||||||
|
|
||||||
|
if (var->is_interface_instance()) {
|
||||||
|
var->location = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
char sentinel = '\0';
|
||||||
|
|
||||||
|
if (var->type->is_record()) {
|
||||||
|
sentinel = '.';
|
||||||
|
} else if (var->type->is_array()
|
||||||
|
&& var->type->fields.array->is_record()) {
|
||||||
|
sentinel = '[';
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned l = strlen(var->name);
|
||||||
for (unsigned i = 0; i < shader->NumUniformBlocks; i++) {
|
for (unsigned i = 0; i < shader->NumUniformBlocks; i++) {
|
||||||
for (unsigned j = 0; j < shader->UniformBlocks[i].NumUniforms; j++) {
|
for (unsigned j = 0; j < shader->UniformBlocks[i].NumUniforms; j++) {
|
||||||
if (!strcmp(var->name, shader->UniformBlocks[i].Uniforms[j].Name)) {
|
if (sentinel) {
|
||||||
|
const char *begin = shader->UniformBlocks[i].Uniforms[j].Name;
|
||||||
|
const char *end = strchr(begin, sentinel);
|
||||||
|
|
||||||
|
if (end == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (l != (end - begin))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strncmp(var->name, begin, l) == 0) {
|
||||||
|
found = true;
|
||||||
|
var->location = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(var->name,
|
||||||
|
shader->UniformBlocks[i].Uniforms[j].Name)) {
|
||||||
found = true;
|
found = true;
|
||||||
var->uniform_block = i;
|
var->uniform_block = i;
|
||||||
var->location = j;
|
var->location = j;
|
||||||
|
|
@ -614,13 +645,6 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
|
||||||
*/
|
*/
|
||||||
memset(prog->SamplerUnits, 0, sizeof(prog->SamplerUnits));
|
memset(prog->SamplerUnits, 0, sizeof(prog->SamplerUnits));
|
||||||
|
|
||||||
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
|
|
||||||
if (prog->_LinkedShaders[i] == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
link_update_uniform_buffer_variables(prog->_LinkedShaders[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* First pass: Count the uniform resources used by the user-defined
|
/* First pass: Count the uniform resources used by the user-defined
|
||||||
* uniforms. While this happens, each active uniform will have an index
|
* uniforms. While this happens, each active uniform will have an index
|
||||||
* assigned to it.
|
* assigned to it.
|
||||||
|
|
@ -633,6 +657,8 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
|
||||||
if (prog->_LinkedShaders[i] == NULL)
|
if (prog->_LinkedShaders[i] == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
link_update_uniform_buffer_variables(prog->_LinkedShaders[i]);
|
||||||
|
|
||||||
/* Reset various per-shader target counts.
|
/* Reset various per-shader target counts.
|
||||||
*/
|
*/
|
||||||
uniform_size.start_shader();
|
uniform_size.start_shader();
|
||||||
|
|
|
||||||
|
|
@ -873,7 +873,6 @@ link_intrastage_shaders(void *mem_ctx,
|
||||||
unsigned num_shaders)
|
unsigned num_shaders)
|
||||||
{
|
{
|
||||||
struct gl_uniform_block *uniform_blocks = NULL;
|
struct gl_uniform_block *uniform_blocks = NULL;
|
||||||
unsigned num_uniform_blocks = 0;
|
|
||||||
|
|
||||||
/* Check that global variables defined in multiple shaders are consistent.
|
/* Check that global variables defined in multiple shaders are consistent.
|
||||||
*/
|
*/
|
||||||
|
|
@ -881,23 +880,11 @@ link_intrastage_shaders(void *mem_ctx,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Check that uniform blocks between shaders for a stage agree. */
|
/* Check that uniform blocks between shaders for a stage agree. */
|
||||||
for (unsigned i = 0; i < num_shaders; i++) {
|
const int num_uniform_blocks =
|
||||||
struct gl_shader *sh = shader_list[i];
|
link_uniform_blocks(mem_ctx, prog, shader_list, num_shaders,
|
||||||
|
&uniform_blocks);
|
||||||
for (unsigned j = 0; j < sh->NumUniformBlocks; j++) {
|
if (num_uniform_blocks < 0)
|
||||||
link_assign_uniform_block_offsets(sh);
|
|
||||||
|
|
||||||
int index = link_cross_validate_uniform_block(mem_ctx,
|
|
||||||
&uniform_blocks,
|
|
||||||
&num_uniform_blocks,
|
|
||||||
&sh->UniformBlocks[j]);
|
|
||||||
if (index == -1) {
|
|
||||||
linker_error(prog, "uniform block `%s' has mismatching definitions",
|
|
||||||
sh->UniformBlocks[j].Name);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check that there is only a single definition of each function signature
|
/* Check that there is only a single definition of each function signature
|
||||||
* across all shaders.
|
* across all shaders.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue