mesa: use gl_shader_variable in program resource list
Patch changes linker to allocate gl_shader_variable instead of using ir_variable. This makes it possible to get rid of ir_variables and ir in memory after linking. v2: check that we do not create duplicate entries with packed varyings v3: document 'patch' bit (Ilia Mirkin) Signed-off-by: Tapani Pälli <tapani.palli@intel.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
@@ -3362,6 +3362,30 @@ build_stageref(struct gl_shader_program *shProg, const char *name,
|
|||||||
return stages;
|
return stages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create gl_shader_variable from ir_variable class.
|
||||||
|
*/
|
||||||
|
static gl_shader_variable *
|
||||||
|
create_shader_variable(struct gl_shader_program *shProg, const ir_variable *in)
|
||||||
|
{
|
||||||
|
gl_shader_variable *out = ralloc(shProg, struct gl_shader_variable);
|
||||||
|
if (!out)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
out->type = in->type;
|
||||||
|
out->name = ralloc_strdup(shProg, in->name);
|
||||||
|
|
||||||
|
if (!out->name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
out->location = in->data.location;
|
||||||
|
out->index = in->data.index;
|
||||||
|
out->patch = in->data.patch;
|
||||||
|
out->mode = in->data.mode;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
add_interface_variables(struct gl_shader_program *shProg,
|
add_interface_variables(struct gl_shader_program *shProg,
|
||||||
exec_list *ir, GLenum programInterface)
|
exec_list *ir, GLenum programInterface)
|
||||||
@@ -3413,9 +3437,13 @@ add_interface_variables(struct gl_shader_program *shProg,
|
|||||||
if (strncmp(var->name, "gl_out_FragData", 15) == 0)
|
if (strncmp(var->name, "gl_out_FragData", 15) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!add_program_resource(shProg, programInterface, var,
|
gl_shader_variable *sha_v = create_shader_variable(shProg, var);
|
||||||
build_stageref(shProg, var->name,
|
if (!sha_v)
|
||||||
var->data.mode) | mask))
|
return false;
|
||||||
|
|
||||||
|
if (!add_program_resource(shProg, programInterface, sha_v,
|
||||||
|
build_stageref(shProg, sha_v->name,
|
||||||
|
sha_v->mode) | mask))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -3445,9 +3473,12 @@ add_packed_varyings(struct gl_shader_program *shProg, int stage, GLenum type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type == iface) {
|
if (type == iface) {
|
||||||
if (!add_program_resource(shProg, iface, var,
|
gl_shader_variable *sha_v = create_shader_variable(shProg, var);
|
||||||
build_stageref(shProg, var->name,
|
if (!sha_v)
|
||||||
var->data.mode)))
|
return false;
|
||||||
|
if (!add_program_resource(shProg, iface, sha_v,
|
||||||
|
build_stageref(shProg, sha_v->name,
|
||||||
|
sha_v->mode)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3467,7 +3498,10 @@ add_fragdata_arrays(struct gl_shader_program *shProg)
|
|||||||
ir_variable *var = node->as_variable();
|
ir_variable *var = node->as_variable();
|
||||||
if (var) {
|
if (var) {
|
||||||
assert(var->data.mode == ir_var_shader_out);
|
assert(var->data.mode == ir_var_shader_out);
|
||||||
if (!add_program_resource(shProg, GL_PROGRAM_OUTPUT, var,
|
gl_shader_variable *sha_v = create_shader_variable(shProg, var);
|
||||||
|
if (!sha_v)
|
||||||
|
return false;
|
||||||
|
if (!add_program_resource(shProg, GL_PROGRAM_OUTPUT, sha_v,
|
||||||
1 << MESA_SHADER_FRAGMENT))
|
1 << MESA_SHADER_FRAGMENT))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -3718,8 +3752,14 @@ build_program_resource_list(struct gl_shader_program *shProg)
|
|||||||
if (shProg->SeparateShader) {
|
if (shProg->SeparateShader) {
|
||||||
if (!add_packed_varyings(shProg, input_stage, GL_PROGRAM_INPUT))
|
if (!add_packed_varyings(shProg, input_stage, GL_PROGRAM_INPUT))
|
||||||
return;
|
return;
|
||||||
if (!add_packed_varyings(shProg, output_stage, GL_PROGRAM_OUTPUT))
|
|
||||||
return;
|
/* Only when dealing with multiple stages, otherwise we would have
|
||||||
|
* duplicate gl_shader_variable entries.
|
||||||
|
*/
|
||||||
|
if (input_stage != output_stage) {
|
||||||
|
if (!add_packed_varyings(shProg, output_stage, GL_PROGRAM_OUTPUT))
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!add_fragdata_arrays(shProg))
|
if (!add_fragdata_arrays(shProg))
|
||||||
|
@@ -2524,6 +2524,67 @@ struct gl_active_atomic_buffer
|
|||||||
GLboolean StageReferences[MESA_SHADER_STAGES];
|
GLboolean StageReferences[MESA_SHADER_STAGES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data container for shader queries. This holds only the minimal
|
||||||
|
* amount of required information for resource queries to work.
|
||||||
|
*/
|
||||||
|
struct gl_shader_variable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Declared type of the variable
|
||||||
|
*/
|
||||||
|
const struct glsl_type *type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declared name of the variable
|
||||||
|
*/
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage location of the base of this variable
|
||||||
|
*
|
||||||
|
* The precise meaning of this field depends on the nature of the variable.
|
||||||
|
*
|
||||||
|
* - Vertex shader input: one of the values from \c gl_vert_attrib.
|
||||||
|
* - Vertex shader output: one of the values from \c gl_varying_slot.
|
||||||
|
* - Geometry shader input: one of the values from \c gl_varying_slot.
|
||||||
|
* - Geometry shader output: one of the values from \c gl_varying_slot.
|
||||||
|
* - Fragment shader input: one of the values from \c gl_varying_slot.
|
||||||
|
* - Fragment shader output: one of the values from \c gl_frag_result.
|
||||||
|
* - Uniforms: Per-stage uniform slot number for default uniform block.
|
||||||
|
* - Uniforms: Index within the uniform block definition for UBO members.
|
||||||
|
* - Non-UBO Uniforms: explicit location until linking then reused to
|
||||||
|
* store uniform slot number.
|
||||||
|
* - Other: This field is not currently used.
|
||||||
|
*
|
||||||
|
* If the variable is a uniform, shader input, or shader output, and the
|
||||||
|
* slot has not been assigned, the value will be -1.
|
||||||
|
*/
|
||||||
|
int location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output index for dual source blending.
|
||||||
|
*
|
||||||
|
* \note
|
||||||
|
* The GLSL spec only allows the values 0 or 1 for the index in \b dual
|
||||||
|
* source blending.
|
||||||
|
*/
|
||||||
|
unsigned index:1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether a shader input/output is per-patch in tessellation
|
||||||
|
* shader stages.
|
||||||
|
*/
|
||||||
|
unsigned patch:1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage class of the variable.
|
||||||
|
*
|
||||||
|
* \sa (n)ir_variable_mode
|
||||||
|
*/
|
||||||
|
unsigned mode:4;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Active resource in a gl_shader_program
|
* Active resource in a gl_shader_program
|
||||||
*/
|
*/
|
||||||
|
@@ -56,7 +56,7 @@ const type * RESOURCE_ ## name (gl_program_resource *res) { \
|
|||||||
return (type *) res->Data; \
|
return (type *) res->Data; \
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_RESOURCE_FUNC(VAR, ir_variable);
|
DECL_RESOURCE_FUNC(VAR, gl_shader_variable);
|
||||||
DECL_RESOURCE_FUNC(UBO, gl_uniform_block);
|
DECL_RESOURCE_FUNC(UBO, gl_uniform_block);
|
||||||
DECL_RESOURCE_FUNC(UNI, gl_uniform_storage);
|
DECL_RESOURCE_FUNC(UNI, gl_uniform_storage);
|
||||||
DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer);
|
DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer);
|
||||||
@@ -101,14 +101,14 @@ _mesa_BindAttribLocation(GLhandleARB program, GLuint index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_active_attrib(const ir_variable *var)
|
is_active_attrib(const gl_shader_variable *var)
|
||||||
{
|
{
|
||||||
if (!var)
|
if (!var)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (var->data.mode) {
|
switch (var->mode) {
|
||||||
case ir_var_shader_in:
|
case ir_var_shader_in:
|
||||||
return var->data.location != -1;
|
return var->location != -1;
|
||||||
|
|
||||||
case ir_var_system_value:
|
case ir_var_system_value:
|
||||||
/* From GL 4.3 core spec, section 11.1.1 (Vertex Attributes):
|
/* From GL 4.3 core spec, section 11.1.1 (Vertex Attributes):
|
||||||
@@ -116,9 +116,9 @@ is_active_attrib(const ir_variable *var)
|
|||||||
* are enumerated, including the special built-in inputs gl_VertexID
|
* are enumerated, including the special built-in inputs gl_VertexID
|
||||||
* and gl_InstanceID."
|
* and gl_InstanceID."
|
||||||
*/
|
*/
|
||||||
return var->data.location == SYSTEM_VALUE_VERTEX_ID ||
|
return var->location == SYSTEM_VALUE_VERTEX_ID ||
|
||||||
var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE ||
|
var->location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE ||
|
||||||
var->data.location == SYSTEM_VALUE_INSTANCE_ID;
|
var->location == SYSTEM_VALUE_INSTANCE_ID;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -163,7 +163,7 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ir_variable *const var = RESOURCE_VAR(res);
|
const gl_shader_variable *const var = RESOURCE_VAR(res);
|
||||||
|
|
||||||
if (!is_active_attrib(var))
|
if (!is_active_attrib(var))
|
||||||
return;
|
return;
|
||||||
@@ -174,8 +174,8 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index,
|
|||||||
* consider gl_VertexIDMESA as gl_VertexID for purposes of checking
|
* consider gl_VertexIDMESA as gl_VertexID for purposes of checking
|
||||||
* active attributes.
|
* active attributes.
|
||||||
*/
|
*/
|
||||||
if (var->data.mode == ir_var_system_value &&
|
if (var->mode == ir_var_system_value &&
|
||||||
var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
|
var->location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
|
||||||
var_name = "gl_VertexID";
|
var_name = "gl_VertexID";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +427,7 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name)
|
|||||||
const char*
|
const char*
|
||||||
_mesa_program_resource_name(struct gl_program_resource *res)
|
_mesa_program_resource_name(struct gl_program_resource *res)
|
||||||
{
|
{
|
||||||
const ir_variable *var;
|
const gl_shader_variable *var;
|
||||||
switch (res->Type) {
|
switch (res->Type) {
|
||||||
case GL_UNIFORM_BLOCK:
|
case GL_UNIFORM_BLOCK:
|
||||||
case GL_SHADER_STORAGE_BLOCK:
|
case GL_SHADER_STORAGE_BLOCK:
|
||||||
@@ -437,8 +437,8 @@ _mesa_program_resource_name(struct gl_program_resource *res)
|
|||||||
case GL_PROGRAM_INPUT:
|
case GL_PROGRAM_INPUT:
|
||||||
var = RESOURCE_VAR(res);
|
var = RESOURCE_VAR(res);
|
||||||
/* Special case gl_VertexIDMESA -> gl_VertexID. */
|
/* Special case gl_VertexIDMESA -> gl_VertexID. */
|
||||||
if (var->data.mode == ir_var_system_value &&
|
if (var->mode == ir_var_system_value &&
|
||||||
var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
|
var->location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
|
||||||
return "gl_VertexID";
|
return "gl_VertexID";
|
||||||
}
|
}
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
@@ -857,14 +857,14 @@ program_resource_location(struct gl_shader_program *shProg,
|
|||||||
*/
|
*/
|
||||||
switch (res->Type) {
|
switch (res->Type) {
|
||||||
case GL_PROGRAM_INPUT: {
|
case GL_PROGRAM_INPUT: {
|
||||||
const ir_variable *var = RESOURCE_VAR(res);
|
const gl_shader_variable *var = RESOURCE_VAR(res);
|
||||||
|
|
||||||
/* If the input is an array, fail if the index is out of bounds. */
|
/* If the input is an array, fail if the index is out of bounds. */
|
||||||
if (array_index > 0
|
if (array_index > 0
|
||||||
&& array_index >= var->type->length) {
|
&& array_index >= var->type->length) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return (var->data.location +
|
return (var->location +
|
||||||
(array_index * var->type->without_array()->matrix_columns) -
|
(array_index * var->type->without_array()->matrix_columns) -
|
||||||
VERT_ATTRIB_GENERIC0);
|
VERT_ATTRIB_GENERIC0);
|
||||||
}
|
}
|
||||||
@@ -874,7 +874,7 @@ program_resource_location(struct gl_shader_program *shProg,
|
|||||||
&& array_index >= RESOURCE_VAR(res)->type->length) {
|
&& array_index >= RESOURCE_VAR(res)->type->length) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return RESOURCE_VAR(res)->data.location + array_index - FRAG_RESULT_DATA0;
|
return RESOURCE_VAR(res)->location + array_index - FRAG_RESULT_DATA0;
|
||||||
case GL_UNIFORM:
|
case GL_UNIFORM:
|
||||||
/* If the uniform is built-in, fail. */
|
/* If the uniform is built-in, fail. */
|
||||||
if (RESOURCE_UNI(res)->builtin)
|
if (RESOURCE_UNI(res)->builtin)
|
||||||
@@ -954,7 +954,7 @@ _mesa_program_resource_location_index(struct gl_shader_program *shProg,
|
|||||||
if (!res || !(res->StageReferences & (1 << MESA_SHADER_FRAGMENT)))
|
if (!res || !(res->StageReferences & (1 << MESA_SHADER_FRAGMENT)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return RESOURCE_VAR(res)->data.index;
|
return RESOURCE_VAR(res)->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
@@ -1252,7 +1252,7 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
|
|||||||
case GL_LOCATION_INDEX:
|
case GL_LOCATION_INDEX:
|
||||||
if (res->Type != GL_PROGRAM_OUTPUT)
|
if (res->Type != GL_PROGRAM_OUTPUT)
|
||||||
goto invalid_operation;
|
goto invalid_operation;
|
||||||
*val = RESOURCE_VAR(res)->data.index;
|
*val = RESOURCE_VAR(res)->index;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case GL_NUM_COMPATIBLE_SUBROUTINES:
|
case GL_NUM_COMPATIBLE_SUBROUTINES:
|
||||||
@@ -1309,7 +1309,7 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
|
|||||||
switch (res->Type) {
|
switch (res->Type) {
|
||||||
case GL_PROGRAM_INPUT:
|
case GL_PROGRAM_INPUT:
|
||||||
case GL_PROGRAM_OUTPUT:
|
case GL_PROGRAM_OUTPUT:
|
||||||
*val = RESOURCE_VAR(res)->data.patch;
|
*val = RESOURCE_VAR(res)->patch;
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
goto invalid_operation;
|
goto invalid_operation;
|
||||||
|
Reference in New Issue
Block a user