mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 06:30:10 +01:00
mesa: Expose GLSL interpolation qualifiers in gl_fragment_program.
This patch makes GLSL interpolation qualifiers visible to drivers via the array InterpQualifier[] in gl_fragment_program, so that they can easily be used by driver back-ends to select the correct interpolation mode. Previous to this patch, the GLSL compiler was using the enum ir_variable_interpolation to represent interpolation types. Rather than make a duplicate enum in core mesa to represent the same thing, I moved the enum into mtypes.h and renamed it to be more consistent with the other enums defined there. Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
0fbc8d301b
commit
cf45949d6a
8 changed files with 69 additions and 33 deletions
|
|
@ -1962,11 +1962,11 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
|
|||
}
|
||||
|
||||
if (qual->flags.q.flat)
|
||||
var->interpolation = ir_var_flat;
|
||||
var->interpolation = INTERP_QUALIFIER_FLAT;
|
||||
else if (qual->flags.q.noperspective)
|
||||
var->interpolation = ir_var_noperspective;
|
||||
var->interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
|
||||
else
|
||||
var->interpolation = ir_var_smooth;
|
||||
var->interpolation = INTERP_QUALIFIER_SMOOTH;
|
||||
|
||||
var->pixel_center_integer = qual->flags.q.pixel_center_integer;
|
||||
var->origin_upper_left = qual->flags.q.origin_upper_left;
|
||||
|
|
@ -2630,7 +2630,7 @@ ast_declarator_list::hir(exec_list *instructions,
|
|||
&& state->current_function == NULL
|
||||
&& var->type->is_integer()
|
||||
&& var->mode == ir_var_out
|
||||
&& var->interpolation != ir_var_flat) {
|
||||
&& var->interpolation != INTERP_QUALIFIER_FLAT) {
|
||||
|
||||
_mesa_glsl_error(&loc, state, "If a vertex output is an integer, "
|
||||
"then it must be qualified with 'flat'");
|
||||
|
|
|
|||
|
|
@ -1320,7 +1320,7 @@ ir_swizzle::variable_referenced() const
|
|||
ir_variable::ir_variable(const struct glsl_type *type, const char *name,
|
||||
ir_variable_mode mode)
|
||||
: max_array_access(0), read_only(false), centroid(false), invariant(false),
|
||||
mode(mode), interpolation(ir_var_smooth)
|
||||
mode(mode), interpolation(INTERP_QUALIFIER_SMOOTH)
|
||||
{
|
||||
this->ir_type = ir_type_variable;
|
||||
this->type = type;
|
||||
|
|
@ -1343,9 +1343,9 @@ const char *
|
|||
ir_variable::interpolation_string() const
|
||||
{
|
||||
switch (this->interpolation) {
|
||||
case ir_var_smooth: return "smooth";
|
||||
case ir_var_flat: return "flat";
|
||||
case ir_var_noperspective: return "noperspective";
|
||||
case INTERP_QUALIFIER_SMOOTH: return "smooth";
|
||||
case INTERP_QUALIFIER_FLAT: return "flat";
|
||||
case INTERP_QUALIFIER_NOPERSPECTIVE: return "noperspective";
|
||||
}
|
||||
|
||||
assert(!"Should not get here.");
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "list.h"
|
||||
#include "ir_visitor.h"
|
||||
#include "ir_hierarchical_visitor.h"
|
||||
#include "main/mtypes.h"
|
||||
|
||||
/**
|
||||
* \defgroup IR Intermediate representation nodes
|
||||
|
|
@ -227,12 +228,6 @@ enum ir_variable_mode {
|
|||
ir_var_temporary /**< Temporary variable generated during compilation. */
|
||||
};
|
||||
|
||||
enum ir_variable_interpolation {
|
||||
ir_var_smooth = 0,
|
||||
ir_var_flat,
|
||||
ir_var_noperspective
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Layout qualifiers for gl_FragDepth.
|
||||
*
|
||||
|
|
@ -1679,7 +1674,8 @@ extern bool
|
|||
ir_has_call(ir_instruction *ir);
|
||||
|
||||
extern void
|
||||
do_set_program_inouts(exec_list *instructions, struct gl_program *prog);
|
||||
do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
|
||||
bool is_fragment_shader);
|
||||
|
||||
extern char *
|
||||
prototype_string(const glsl_type *return_type, const char *name,
|
||||
|
|
|
|||
|
|
@ -405,11 +405,11 @@ ir_reader::read_declaration(s_expression *expr)
|
|||
} else if (strcmp(qualifier->value(), "inout") == 0) {
|
||||
var->mode = ir_var_inout;
|
||||
} else if (strcmp(qualifier->value(), "smooth") == 0) {
|
||||
var->interpolation = ir_var_smooth;
|
||||
var->interpolation = INTERP_QUALIFIER_SMOOTH;
|
||||
} else if (strcmp(qualifier->value(), "flat") == 0) {
|
||||
var->interpolation = ir_var_flat;
|
||||
var->interpolation = INTERP_QUALIFIER_FLAT;
|
||||
} else if (strcmp(qualifier->value(), "noperspective") == 0) {
|
||||
var->interpolation = ir_var_noperspective;
|
||||
var->interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
|
||||
} else {
|
||||
ir_read_error(expr, "unknown qualifier: %s", qualifier->value());
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
*
|
||||
* Sets the InputsRead and OutputsWritten of Mesa programs.
|
||||
*
|
||||
* Additionally, for fragment shaders, sets the InterpQualifier array.
|
||||
*
|
||||
* Mesa programs (gl_program, not gl_shader_program) have a set of
|
||||
* flags indicating which varyings are read and written. Computing
|
||||
* which are actually read from some sort of backend code can be
|
||||
|
|
@ -42,9 +44,11 @@
|
|||
|
||||
class ir_set_program_inouts_visitor : public ir_hierarchical_visitor {
|
||||
public:
|
||||
ir_set_program_inouts_visitor(struct gl_program *prog)
|
||||
ir_set_program_inouts_visitor(struct gl_program *prog,
|
||||
bool is_fragment_shader)
|
||||
{
|
||||
this->prog = prog;
|
||||
this->is_fragment_shader = is_fragment_shader;
|
||||
this->ht = hash_table_ctor(0,
|
||||
hash_table_pointer_hash,
|
||||
hash_table_pointer_compare);
|
||||
|
|
@ -61,10 +65,12 @@ public:
|
|||
|
||||
struct gl_program *prog;
|
||||
struct hash_table *ht;
|
||||
bool is_fragment_shader;
|
||||
};
|
||||
|
||||
static void
|
||||
mark(struct gl_program *prog, ir_variable *var, int offset, int len)
|
||||
mark(struct gl_program *prog, ir_variable *var, int offset, int len,
|
||||
bool is_fragment_shader)
|
||||
{
|
||||
/* As of GLSL 1.20, varyings can only be floats, floating-point
|
||||
* vectors or matrices, or arrays of them. For Mesa programs using
|
||||
|
|
@ -75,12 +81,19 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len)
|
|||
*/
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (var->mode == ir_var_in)
|
||||
prog->InputsRead |= BITFIELD64_BIT(var->location + offset + i);
|
||||
else if (var->mode == ir_var_system_value)
|
||||
prog->SystemValuesRead |= (1 << (var->location + offset + i));
|
||||
else
|
||||
prog->OutputsWritten |= BITFIELD64_BIT(var->location + offset + i);
|
||||
GLbitfield64 bitfield = BITFIELD64_BIT(var->location + offset + i);
|
||||
if (var->mode == ir_var_in) {
|
||||
prog->InputsRead |= bitfield;
|
||||
if (is_fragment_shader) {
|
||||
gl_fragment_program *fprog = (gl_fragment_program *) prog;
|
||||
fprog->InterpQualifier[var->location + offset + i] =
|
||||
(glsl_interp_qualifier) var->interpolation;
|
||||
}
|
||||
} else if (var->mode == ir_var_system_value) {
|
||||
prog->SystemValuesRead |= bitfield;
|
||||
} else {
|
||||
prog->OutputsWritten |= bitfield;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,9 +106,11 @@ ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir)
|
|||
|
||||
if (ir->type->is_array()) {
|
||||
mark(this->prog, ir->var, 0,
|
||||
ir->type->length * ir->type->fields.array->matrix_columns);
|
||||
ir->type->length * ir->type->fields.array->matrix_columns,
|
||||
this->is_fragment_shader);
|
||||
} else {
|
||||
mark(this->prog, ir->var, 0, ir->type->matrix_columns);
|
||||
mark(this->prog, ir->var, 0, ir->type->matrix_columns,
|
||||
this->is_fragment_shader);
|
||||
}
|
||||
|
||||
return visit_continue;
|
||||
|
|
@ -121,7 +136,8 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
|
|||
width = deref_var->type->fields.array->matrix_columns;
|
||||
}
|
||||
|
||||
mark(this->prog, var, index->value.i[0] * width, width);
|
||||
mark(this->prog, var, index->value.i[0] * width, width,
|
||||
this->is_fragment_shader);
|
||||
return visit_continue_with_parent;
|
||||
}
|
||||
|
||||
|
|
@ -151,12 +167,17 @@ ir_set_program_inouts_visitor::visit_enter(ir_function_signature *ir)
|
|||
}
|
||||
|
||||
void
|
||||
do_set_program_inouts(exec_list *instructions, struct gl_program *prog)
|
||||
do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
|
||||
bool is_fragment_shader)
|
||||
{
|
||||
ir_set_program_inouts_visitor v(prog);
|
||||
ir_set_program_inouts_visitor v(prog, is_fragment_shader);
|
||||
|
||||
prog->InputsRead = 0;
|
||||
prog->OutputsWritten = 0;
|
||||
prog->SystemValuesRead = 0;
|
||||
if (is_fragment_shader) {
|
||||
memset(((gl_fragment_program *) prog)->InterpQualifier, 0,
|
||||
sizeof(((gl_fragment_program *) prog)->InterpQualifier));
|
||||
}
|
||||
visit_list_elements(&v, instructions);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1790,6 +1790,18 @@ typedef enum
|
|||
} gl_system_value;
|
||||
|
||||
|
||||
/**
|
||||
* The possible interpolation qualifiers that can be applied to a fragment
|
||||
* shader input in GLSL.
|
||||
*/
|
||||
enum glsl_interp_qualifier
|
||||
{
|
||||
INTERP_QUALIFIER_SMOOTH,
|
||||
INTERP_QUALIFIER_FLAT,
|
||||
INTERP_QUALIFIER_NOPERSPECTIVE
|
||||
};
|
||||
|
||||
|
||||
/** Vertex and fragment instructions */
|
||||
struct prog_instruction;
|
||||
struct gl_program_parameter_list;
|
||||
|
|
@ -1890,6 +1902,13 @@ struct gl_fragment_program
|
|||
GLboolean OriginUpperLeft;
|
||||
GLboolean PixelCenterInteger;
|
||||
enum gl_frag_depth_layout FragDepthLayout;
|
||||
|
||||
/**
|
||||
* GLSL interpolation qualifier associated with each fragment shader input.
|
||||
* For inputs that do not have an interpolation qualifier specified in
|
||||
* GLSL, the value is INTERP_QUALIFIER_SMOOTH.
|
||||
*/
|
||||
enum glsl_interp_qualifier InterpQualifier[FRAG_ATTRIB_MAX];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3191,7 +3191,7 @@ get_mesa_program(struct gl_context *ctx,
|
|||
prog->Instructions = mesa_instructions;
|
||||
prog->NumInstructions = num_instructions;
|
||||
|
||||
do_set_program_inouts(shader->ir, prog);
|
||||
do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER);
|
||||
count_resources(prog);
|
||||
|
||||
check_resources(ctx, shader_program, prog);
|
||||
|
|
|
|||
|
|
@ -4966,7 +4966,7 @@ get_mesa_program(struct gl_context *ctx,
|
|||
prog->Instructions = NULL;
|
||||
prog->NumInstructions = 0;
|
||||
|
||||
do_set_program_inouts(shader->ir, prog);
|
||||
do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER);
|
||||
count_resources(v, prog);
|
||||
|
||||
check_resources(ctx, shader_program, v, prog);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue