glsl: add the patch in/out qualifier (v2)
v2: Dropped some unrelated reordering in glsl_parser.yy as Ken suggested. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:

committed by
Marek Olšák

parent
1036b024d4
commit
1009b3311f
@@ -434,6 +434,7 @@ struct ast_type_qualifier {
|
|||||||
unsigned out:1;
|
unsigned out:1;
|
||||||
unsigned centroid:1;
|
unsigned centroid:1;
|
||||||
unsigned sample:1;
|
unsigned sample:1;
|
||||||
|
unsigned patch:1;
|
||||||
unsigned uniform:1;
|
unsigned uniform:1;
|
||||||
unsigned buffer:1;
|
unsigned buffer:1;
|
||||||
unsigned smooth:1;
|
unsigned smooth:1;
|
||||||
|
@@ -2487,6 +2487,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
|
|||||||
var->data.stream = qual->stream;
|
var->data.stream = qual->stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qual->flags.q.patch)
|
||||||
|
var->data.patch = 1;
|
||||||
|
|
||||||
if (qual->flags.q.attribute && state->stage != MESA_SHADER_VERTEX) {
|
if (qual->flags.q.attribute && state->stage != MESA_SHADER_VERTEX) {
|
||||||
var->type = glsl_type::error_type;
|
var->type = glsl_type::error_type;
|
||||||
_mesa_glsl_error(loc, state,
|
_mesa_glsl_error(loc, state,
|
||||||
@@ -3209,6 +3212,17 @@ handle_tess_ctrl_shader_output_decl(struct _mesa_glsl_parse_state *state,
|
|||||||
num_vertices = state->out_qualifier->vertices;
|
num_vertices = state->out_qualifier->vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!var->type->is_array() && !var->data.patch) {
|
||||||
|
_mesa_glsl_error(&loc, state,
|
||||||
|
"tessellation control shader outputs must be arrays");
|
||||||
|
|
||||||
|
/* To avoid cascading failures, short circuit the checks below. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var->data.patch)
|
||||||
|
return;
|
||||||
|
|
||||||
validate_layout_qualifier_vertex_count(state, loc, var, num_vertices,
|
validate_layout_qualifier_vertex_count(state, loc, var, num_vertices,
|
||||||
&state->tcs_output_size,
|
&state->tcs_output_size,
|
||||||
"geometry shader input");
|
"geometry shader input");
|
||||||
@@ -3958,6 +3972,33 @@ ast_declarator_list::hir(exec_list *instructions,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* From section 4.3.4 of the GLSL 4.00 spec:
|
||||||
|
* "Input variables may not be declared using the patch in qualifier
|
||||||
|
* in tessellation control or geometry shaders."
|
||||||
|
*
|
||||||
|
* From section 4.3.6 of the GLSL 4.00 spec:
|
||||||
|
* "It is an error to use patch out in a vertex, tessellation
|
||||||
|
* evaluation, or geometry shader."
|
||||||
|
*
|
||||||
|
* This doesn't explicitly forbid using them in a fragment shader, but
|
||||||
|
* that's probably just an oversight.
|
||||||
|
*/
|
||||||
|
if (state->stage != MESA_SHADER_TESS_EVAL
|
||||||
|
&& this->type->qualifier.flags.q.patch
|
||||||
|
&& this->type->qualifier.flags.q.in) {
|
||||||
|
|
||||||
|
_mesa_glsl_error(&loc, state, "'patch in' can only be used in a "
|
||||||
|
"tessellation evaluation shader");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->stage != MESA_SHADER_TESS_CTRL
|
||||||
|
&& this->type->qualifier.flags.q.patch
|
||||||
|
&& this->type->qualifier.flags.q.out) {
|
||||||
|
|
||||||
|
_mesa_glsl_error(&loc, state, "'patch out' can only be used in a "
|
||||||
|
"tessellation control shader");
|
||||||
|
}
|
||||||
|
|
||||||
/* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
|
/* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
|
||||||
*/
|
*/
|
||||||
if (this->type->qualifier.precision != ast_precision_none) {
|
if (this->type->qualifier.precision != ast_precision_none) {
|
||||||
@@ -5481,6 +5522,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
|
|||||||
interpret_interpolation_qualifier(qual, var_mode, state, &loc);
|
interpret_interpolation_qualifier(qual, var_mode, state, &loc);
|
||||||
fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
|
fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
|
||||||
fields[i].sample = qual->flags.q.sample ? 1 : 0;
|
fields[i].sample = qual->flags.q.sample ? 1 : 0;
|
||||||
|
fields[i].patch = qual->flags.q.patch ? 1 : 0;
|
||||||
|
|
||||||
/* Only save explicitly defined streams in block's field */
|
/* Only save explicitly defined streams in block's field */
|
||||||
fields[i].stream = qual->flags.q.explicit_stream ? qual->stream : -1;
|
fields[i].stream = qual->flags.q.explicit_stream ? qual->stream : -1;
|
||||||
@@ -5815,6 +5857,8 @@ ast_interface_block::hir(exec_list *instructions,
|
|||||||
earlier_per_vertex->fields.structure[j].centroid;
|
earlier_per_vertex->fields.structure[j].centroid;
|
||||||
fields[i].sample =
|
fields[i].sample =
|
||||||
earlier_per_vertex->fields.structure[j].sample;
|
earlier_per_vertex->fields.structure[j].sample;
|
||||||
|
fields[i].patch =
|
||||||
|
earlier_per_vertex->fields.structure[j].patch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5994,6 +6038,7 @@ ast_interface_block::hir(exec_list *instructions,
|
|||||||
var->data.interpolation = fields[i].interpolation;
|
var->data.interpolation = fields[i].interpolation;
|
||||||
var->data.centroid = fields[i].centroid;
|
var->data.centroid = fields[i].centroid;
|
||||||
var->data.sample = fields[i].sample;
|
var->data.sample = fields[i].sample;
|
||||||
|
var->data.patch = fields[i].patch;
|
||||||
var->init_interface_type(block_type);
|
var->init_interface_type(block_type);
|
||||||
|
|
||||||
if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform)
|
if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform)
|
||||||
|
@@ -86,7 +86,8 @@ bool
|
|||||||
ast_type_qualifier::has_auxiliary_storage() const
|
ast_type_qualifier::has_auxiliary_storage() const
|
||||||
{
|
{
|
||||||
return this->flags.q.centroid
|
return this->flags.q.centroid
|
||||||
|| this->flags.q.sample;
|
|| this->flags.q.sample
|
||||||
|
|| this->flags.q.patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
|
@@ -883,10 +883,10 @@ builtin_variable_generator::generate_tcs_special_vars()
|
|||||||
add_system_value(SYSTEM_VALUE_VERTICES_IN, int_t, "gl_PatchVerticesIn");
|
add_system_value(SYSTEM_VALUE_VERTICES_IN, int_t, "gl_PatchVerticesIn");
|
||||||
add_system_value(SYSTEM_VALUE_INVOCATION_ID, int_t, "gl_InvocationID");
|
add_system_value(SYSTEM_VALUE_INVOCATION_ID, int_t, "gl_InvocationID");
|
||||||
|
|
||||||
add_output(VARYING_SLOT_TESS_LEVEL_OUTER,
|
add_output(VARYING_SLOT_TESS_LEVEL_OUTER, array(float_t, 4),
|
||||||
array(float_t, 4), "gl_TessLevelOuter");
|
"gl_TessLevelOuter")->data.patch = 1;
|
||||||
add_output(VARYING_SLOT_TESS_LEVEL_INNER,
|
add_output(VARYING_SLOT_TESS_LEVEL_INNER, array(float_t, 2),
|
||||||
array(float_t, 2), "gl_TessLevelInner");
|
"gl_TessLevelInner")->data.patch = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -315,6 +315,7 @@ invariant KEYWORD(120, 100, 120, 100, INVARIANT);
|
|||||||
flat KEYWORD(130, 100, 130, 300, FLAT);
|
flat KEYWORD(130, 100, 130, 300, FLAT);
|
||||||
smooth KEYWORD(130, 300, 130, 300, SMOOTH);
|
smooth KEYWORD(130, 300, 130, 300, SMOOTH);
|
||||||
noperspective KEYWORD(130, 300, 130, 0, NOPERSPECTIVE);
|
noperspective KEYWORD(130, 300, 130, 0, NOPERSPECTIVE);
|
||||||
|
patch KEYWORD_WITH_ALT(0, 300, 400, 0, yyextra->ARB_tessellation_shader_enable, PATCH);
|
||||||
|
|
||||||
sampler1D DEPRECATED_ES_KEYWORD(SAMPLER1D);
|
sampler1D DEPRECATED_ES_KEYWORD(SAMPLER1D);
|
||||||
sampler2D return SAMPLER2D;
|
sampler2D return SAMPLER2D;
|
||||||
@@ -576,7 +577,6 @@ usamplerBuffer KEYWORD(140, 300, 140, 0, USAMPLERBUFFER);
|
|||||||
|
|
||||||
/* Additional reserved words in GLSL ES 3.00 */
|
/* Additional reserved words in GLSL ES 3.00 */
|
||||||
resource KEYWORD(0, 300, 0, 0, RESOURCE);
|
resource KEYWORD(0, 300, 0, 0, RESOURCE);
|
||||||
patch KEYWORD(0, 300, 0, 0, PATCH);
|
|
||||||
sample KEYWORD_WITH_ALT(400, 300, 400, 0, yyextra->ARB_gpu_shader5_enable, SAMPLE);
|
sample KEYWORD_WITH_ALT(400, 300, 400, 0, yyextra->ARB_gpu_shader5_enable, SAMPLE);
|
||||||
subroutine KEYWORD(0, 300, 0, 0, SUBROUTINE);
|
subroutine KEYWORD(0, 300, 0, 0, SUBROUTINE);
|
||||||
|
|
||||||
|
@@ -1866,7 +1866,11 @@ auxiliary_storage_qualifier:
|
|||||||
memset(& $$, 0, sizeof($$));
|
memset(& $$, 0, sizeof($$));
|
||||||
$$.flags.q.sample = 1;
|
$$.flags.q.sample = 1;
|
||||||
}
|
}
|
||||||
/* TODO: "patch" also goes here someday. */
|
| PATCH
|
||||||
|
{
|
||||||
|
memset(& $$, 0, sizeof($$));
|
||||||
|
$$.flags.q.patch = 1;
|
||||||
|
}
|
||||||
|
|
||||||
storage_qualifier:
|
storage_qualifier:
|
||||||
CONST_TOK
|
CONST_TOK
|
||||||
|
@@ -861,6 +861,8 @@ _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
|
|||||||
printf("centroid ");
|
printf("centroid ");
|
||||||
if (q->flags.q.sample)
|
if (q->flags.q.sample)
|
||||||
printf("sample ");
|
printf("sample ");
|
||||||
|
if (q->flags.q.patch)
|
||||||
|
printf("patch ");
|
||||||
if (q->flags.q.uniform)
|
if (q->flags.q.uniform)
|
||||||
printf("uniform ");
|
printf("uniform ");
|
||||||
if (q->flags.q.buffer)
|
if (q->flags.q.buffer)
|
||||||
|
@@ -122,6 +122,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
|||||||
this->fields.structure[i].centroid = fields[i].centroid;
|
this->fields.structure[i].centroid = fields[i].centroid;
|
||||||
this->fields.structure[i].sample = fields[i].sample;
|
this->fields.structure[i].sample = fields[i].sample;
|
||||||
this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
|
this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
|
||||||
|
this->fields.structure[i].patch = fields[i].patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtx_unlock(&glsl_type::mutex);
|
mtx_unlock(&glsl_type::mutex);
|
||||||
@@ -154,6 +155,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
|||||||
this->fields.structure[i].centroid = fields[i].centroid;
|
this->fields.structure[i].centroid = fields[i].centroid;
|
||||||
this->fields.structure[i].sample = fields[i].sample;
|
this->fields.structure[i].sample = fields[i].sample;
|
||||||
this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
|
this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
|
||||||
|
this->fields.structure[i].patch = fields[i].patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtx_unlock(&glsl_type::mutex);
|
mtx_unlock(&glsl_type::mutex);
|
||||||
@@ -722,6 +724,9 @@ glsl_type::record_compare(const glsl_type *b) const
|
|||||||
if (this->fields.structure[i].sample
|
if (this->fields.structure[i].sample
|
||||||
!= b->fields.structure[i].sample)
|
!= b->fields.structure[i].sample)
|
||||||
return false;
|
return false;
|
||||||
|
if (this->fields.structure[i].patch
|
||||||
|
!= b->fields.structure[i].patch)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@@ -751,6 +751,12 @@ struct glsl_struct_field {
|
|||||||
*/
|
*/
|
||||||
unsigned matrix_layout:2;
|
unsigned matrix_layout:2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For interface blocks, 1 if this variable is a per-patch input or output
|
||||||
|
* (as in ir_variable::patch). 0 otherwise.
|
||||||
|
*/
|
||||||
|
unsigned patch:1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For interface blocks, it has a value if this variable uses multiple vertex
|
* For interface blocks, it has a value if this variable uses multiple vertex
|
||||||
* streams (as in ir_variable::stream). -1 otherwise.
|
* streams (as in ir_variable::stream). -1 otherwise.
|
||||||
|
@@ -1643,6 +1643,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
|
|||||||
this->data.read_only = false;
|
this->data.read_only = false;
|
||||||
this->data.centroid = false;
|
this->data.centroid = false;
|
||||||
this->data.sample = false;
|
this->data.sample = false;
|
||||||
|
this->data.patch = false;
|
||||||
this->data.invariant = false;
|
this->data.invariant = false;
|
||||||
this->data.how_declared = ir_var_declared_normally;
|
this->data.how_declared = ir_var_declared_normally;
|
||||||
this->data.mode = mode;
|
this->data.mode = mode;
|
||||||
@@ -1785,6 +1786,7 @@ ir_function_signature::qualifiers_match(exec_list *params)
|
|||||||
a->data.interpolation != b->data.interpolation ||
|
a->data.interpolation != b->data.interpolation ||
|
||||||
a->data.centroid != b->data.centroid ||
|
a->data.centroid != b->data.centroid ||
|
||||||
a->data.sample != b->data.sample ||
|
a->data.sample != b->data.sample ||
|
||||||
|
a->data.patch != b->data.patch ||
|
||||||
a->data.image_read_only != b->data.image_read_only ||
|
a->data.image_read_only != b->data.image_read_only ||
|
||||||
a->data.image_write_only != b->data.image_write_only ||
|
a->data.image_write_only != b->data.image_write_only ||
|
||||||
a->data.image_coherent != b->data.image_coherent ||
|
a->data.image_coherent != b->data.image_coherent ||
|
||||||
|
@@ -622,6 +622,7 @@ public:
|
|||||||
unsigned read_only:1;
|
unsigned read_only:1;
|
||||||
unsigned centroid:1;
|
unsigned centroid:1;
|
||||||
unsigned sample:1;
|
unsigned sample:1;
|
||||||
|
unsigned patch:1;
|
||||||
unsigned invariant:1;
|
unsigned invariant:1;
|
||||||
unsigned precise:1;
|
unsigned precise:1;
|
||||||
|
|
||||||
|
@@ -167,6 +167,7 @@ void ir_print_visitor::visit(ir_variable *ir)
|
|||||||
|
|
||||||
const char *const cent = (ir->data.centroid) ? "centroid " : "";
|
const char *const cent = (ir->data.centroid) ? "centroid " : "";
|
||||||
const char *const samp = (ir->data.sample) ? "sample " : "";
|
const char *const samp = (ir->data.sample) ? "sample " : "";
|
||||||
|
const char *const patc = (ir->data.patch) ? "patch " : "";
|
||||||
const char *const inv = (ir->data.invariant) ? "invariant " : "";
|
const char *const inv = (ir->data.invariant) ? "invariant " : "";
|
||||||
const char *const mode[] = { "", "uniform ", "shader_storage",
|
const char *const mode[] = { "", "uniform ", "shader_storage",
|
||||||
"shader_in ", "shader_out ",
|
"shader_in ", "shader_out ",
|
||||||
@@ -177,8 +178,8 @@ void ir_print_visitor::visit(ir_variable *ir)
|
|||||||
const char *const interp[] = { "", "smooth", "flat", "noperspective" };
|
const char *const interp[] = { "", "smooth", "flat", "noperspective" };
|
||||||
STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT);
|
STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT);
|
||||||
|
|
||||||
fprintf(f, "(%s%s%s%s%s%s%s) ",
|
fprintf(f, "(%s%s%s%s%s%s%s%s) ",
|
||||||
loc, cent, samp, inv, mode[ir->data.mode],
|
loc, cent, samp, patc, inv, mode[ir->data.mode],
|
||||||
stream[ir->data.stream],
|
stream[ir->data.stream],
|
||||||
interp[ir->data.interpolation]);
|
interp[ir->data.interpolation]);
|
||||||
|
|
||||||
|
@@ -417,6 +417,8 @@ ir_reader::read_declaration(s_expression *expr)
|
|||||||
var->data.centroid = 1;
|
var->data.centroid = 1;
|
||||||
} else if (strcmp(qualifier->value(), "sample") == 0) {
|
} else if (strcmp(qualifier->value(), "sample") == 0) {
|
||||||
var->data.sample = 1;
|
var->data.sample = 1;
|
||||||
|
} else if (strcmp(qualifier->value(), "patch") == 0) {
|
||||||
|
var->data.patch = 1;
|
||||||
} else if (strcmp(qualifier->value(), "invariant") == 0) {
|
} else if (strcmp(qualifier->value(), "invariant") == 0) {
|
||||||
var->data.invariant = 1;
|
var->data.invariant = 1;
|
||||||
} else if (strcmp(qualifier->value(), "uniform") == 0) {
|
} else if (strcmp(qualifier->value(), "uniform") == 0) {
|
||||||
|
@@ -140,6 +140,24 @@ ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var)
|
|||||||
type = type->fields.array;
|
type = type->fields.array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->shader_stage == MESA_SHADER_TESS_CTRL &&
|
||||||
|
var->data.mode == ir_var_shader_in) {
|
||||||
|
assert(type->is_array());
|
||||||
|
type = type->fields.array;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->shader_stage == MESA_SHADER_TESS_CTRL &&
|
||||||
|
var->data.mode == ir_var_shader_out && !var->data.patch) {
|
||||||
|
assert(type->is_array());
|
||||||
|
type = type->fields.array;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->shader_stage == MESA_SHADER_TESS_EVAL &&
|
||||||
|
var->data.mode == ir_var_shader_in && !var->data.patch) {
|
||||||
|
assert(type->is_array());
|
||||||
|
type = type->fields.array;
|
||||||
|
}
|
||||||
|
|
||||||
mark(this->prog, var, 0, type->count_attribute_slots(),
|
mark(this->prog, var, 0, type->count_attribute_slots(),
|
||||||
this->shader_stage == MESA_SHADER_FRAGMENT);
|
this->shader_stage == MESA_SHADER_FRAGMENT);
|
||||||
}
|
}
|
||||||
@@ -165,6 +183,9 @@ ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir)
|
|||||||
*
|
*
|
||||||
* *Except gl_PrimitiveIDIn, as noted below.
|
* *Except gl_PrimitiveIDIn, as noted below.
|
||||||
*
|
*
|
||||||
|
* For tessellation control shaders all inputs and non-patch outputs are
|
||||||
|
* arrays. For tessellation evaluation shaders non-patch inputs are arrays.
|
||||||
|
*
|
||||||
* If the index can't be interpreted as a constant, or some other problem
|
* If the index can't be interpreted as a constant, or some other problem
|
||||||
* occurs, then nothing will be marked and false will be returned.
|
* occurs, then nothing will be marked and false will be returned.
|
||||||
*/
|
*/
|
||||||
@@ -184,6 +205,24 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var,
|
|||||||
type = type->fields.array;
|
type = type->fields.array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->shader_stage == MESA_SHADER_TESS_CTRL &&
|
||||||
|
var->data.mode == ir_var_shader_in) {
|
||||||
|
assert(type->is_array());
|
||||||
|
type = type->fields.array;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->shader_stage == MESA_SHADER_TESS_CTRL &&
|
||||||
|
var->data.mode == ir_var_shader_out && !var->data.patch) {
|
||||||
|
assert(type->is_array());
|
||||||
|
type = type->fields.array;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->shader_stage == MESA_SHADER_TESS_EVAL &&
|
||||||
|
var->data.mode == ir_var_shader_in && !var->data.patch) {
|
||||||
|
assert(type->is_array());
|
||||||
|
type = type->fields.array;
|
||||||
|
}
|
||||||
|
|
||||||
/* The code below only handles:
|
/* The code below only handles:
|
||||||
*
|
*
|
||||||
* - Indexing into matrices
|
* - Indexing into matrices
|
||||||
@@ -242,6 +281,22 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_multiple_vertices(gl_shader_stage stage, ir_variable *var)
|
||||||
|
{
|
||||||
|
if (var->data.patch)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (var->data.mode == ir_var_shader_in)
|
||||||
|
return stage == MESA_SHADER_GEOMETRY ||
|
||||||
|
stage == MESA_SHADER_TESS_CTRL ||
|
||||||
|
stage == MESA_SHADER_TESS_EVAL;
|
||||||
|
if (var->data.mode == ir_var_shader_out)
|
||||||
|
return stage == MESA_SHADER_TESS_CTRL;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ir_visitor_status
|
ir_visitor_status
|
||||||
ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
|
ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
|
||||||
{
|
{
|
||||||
@@ -256,10 +311,9 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
|
|||||||
*/
|
*/
|
||||||
if (ir_dereference_variable * const deref_var =
|
if (ir_dereference_variable * const deref_var =
|
||||||
inner_array->array->as_dereference_variable()) {
|
inner_array->array->as_dereference_variable()) {
|
||||||
if (this->shader_stage == MESA_SHADER_GEOMETRY &&
|
if (is_multiple_vertices(this->shader_stage, deref_var->var)) {
|
||||||
deref_var->var->data.mode == ir_var_shader_in) {
|
/* foo is a geometry or tessellation shader input, so i is
|
||||||
/* foo is a geometry shader input, so i is the vertex, and j the
|
* the vertex, and j the part of the input we're accessing.
|
||||||
* part of the input we're accessing.
|
|
||||||
*/
|
*/
|
||||||
if (try_mark_partial_variable(deref_var->var, ir->array_index))
|
if (try_mark_partial_variable(deref_var->var, ir->array_index))
|
||||||
{
|
{
|
||||||
@@ -275,10 +329,9 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
|
|||||||
} else if (ir_dereference_variable * const deref_var =
|
} else if (ir_dereference_variable * const deref_var =
|
||||||
ir->array->as_dereference_variable()) {
|
ir->array->as_dereference_variable()) {
|
||||||
/* ir => foo[i], where foo is a variable. */
|
/* ir => foo[i], where foo is a variable. */
|
||||||
if (this->shader_stage == MESA_SHADER_GEOMETRY &&
|
if (is_multiple_vertices(this->shader_stage, deref_var->var)) {
|
||||||
deref_var->var->data.mode == ir_var_shader_in) {
|
/* foo is a geometry or tessellation shader input, so i is
|
||||||
/* foo is a geometry shader input, so i is the vertex, and we're
|
* the vertex, and we're accessing the entire input.
|
||||||
* accessing the entire input.
|
|
||||||
*/
|
*/
|
||||||
mark_whole_variable(deref_var->var);
|
mark_whole_variable(deref_var->var);
|
||||||
/* We've now taken care of foo, but i might contain a subexpression
|
/* We've now taken care of foo, but i might contain a subexpression
|
||||||
|
@@ -116,6 +116,18 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (input->data.patch != output->data.patch) {
|
||||||
|
linker_error(prog,
|
||||||
|
"%s shader output `%s' %s patch qualifier, "
|
||||||
|
"but %s shader input %s patch qualifier\n",
|
||||||
|
_mesa_shader_stage_to_string(producer_stage),
|
||||||
|
output->name,
|
||||||
|
(output->data.patch) ? "has" : "lacks",
|
||||||
|
_mesa_shader_stage_to_string(consumer_stage),
|
||||||
|
(input->data.patch) ? "has" : "lacks");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!prog->IsES && input->data.invariant != output->data.invariant) {
|
if (!prog->IsES && input->data.invariant != output->data.invariant) {
|
||||||
linker_error(prog,
|
linker_error(prog,
|
||||||
"%s shader output `%s' %s invariant qualifier, "
|
"%s shader output `%s' %s invariant qualifier, "
|
||||||
@@ -989,7 +1001,8 @@ varying_matches::compute_packing_class(const ir_variable *var)
|
|||||||
*
|
*
|
||||||
* Therefore, the packing class depends only on the interpolation type.
|
* Therefore, the packing class depends only on the interpolation type.
|
||||||
*/
|
*/
|
||||||
unsigned packing_class = var->data.centroid | (var->data.sample << 1);
|
unsigned packing_class = var->data.centroid | (var->data.sample << 1) |
|
||||||
|
(var->data.patch << 2);
|
||||||
packing_class *= 4;
|
packing_class *= 4;
|
||||||
packing_class += var->data.interpolation;
|
packing_class += var->data.interpolation;
|
||||||
return packing_class;
|
return packing_class;
|
||||||
|
@@ -159,6 +159,7 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
|
|||||||
iface_t->fields.structure[i].interpolation;
|
iface_t->fields.structure[i].interpolation;
|
||||||
new_var->data.centroid = iface_t->fields.structure[i].centroid;
|
new_var->data.centroid = iface_t->fields.structure[i].centroid;
|
||||||
new_var->data.sample = iface_t->fields.structure[i].sample;
|
new_var->data.sample = iface_t->fields.structure[i].sample;
|
||||||
|
new_var->data.patch = iface_t->fields.structure[i].patch;
|
||||||
|
|
||||||
new_var->init_interface_type(iface_t);
|
new_var->init_interface_type(iface_t);
|
||||||
hash_table_insert(interface_namespace, new_var,
|
hash_table_insert(interface_namespace, new_var,
|
||||||
|
@@ -610,6 +610,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
|
|||||||
}
|
}
|
||||||
packed_var->data.centroid = unpacked_var->data.centroid;
|
packed_var->data.centroid = unpacked_var->data.centroid;
|
||||||
packed_var->data.sample = unpacked_var->data.sample;
|
packed_var->data.sample = unpacked_var->data.sample;
|
||||||
|
packed_var->data.patch = unpacked_var->data.patch;
|
||||||
packed_var->data.interpolation = unpacked_var->data.interpolation;
|
packed_var->data.interpolation = unpacked_var->data.interpolation;
|
||||||
packed_var->data.location = location;
|
packed_var->data.location = location;
|
||||||
unpacked_var->insert_before(packed_var);
|
unpacked_var->insert_before(packed_var);
|
||||||
|
Reference in New Issue
Block a user