Compare commits

...

6 Commits

Author SHA1 Message Date
Ian Romanick
d6db9143b6 ARB prog parser: Compile lexer as C++ 2011-04-14 12:00:57 -07:00
Ian Romanick
9c0b233c44 ARB prog parser: Compile parser as C++
This is in anticipation of generating GLSL IR from the parser.

The C++ rules for enums vs. ints are just plain broken.
2011-04-14 11:57:59 -07:00
Ian Romanick
364aa72824 glsl: Make bvec types accessible 2011-04-14 11:53:31 -07:00
Ian Romanick
d290ec228b glsl: Add glsl_type::get_sampler_instance method 2011-04-14 11:53:31 -07:00
Ian Romanick
c0906e06ee glsl: Add ir_unop_lit
Like the noise opcode, this opcode really shouldn't exist.  The only
reason it exists is to facilitate translation of assembly shaders to
IR.  These changes include the addition of ir_unop_lit and the
lowering pass that removes it.
2011-04-14 11:53:08 -07:00
Ian Romanick
b6c49104ce glsl: Lower ir_unop_exp to ir_binop_pow
Instead of lowering e^x to 2^(x * log2(e)), lower it to e^x using the
POW opcode.  On GPUs that have a POW instruction, this saves a
multiply (the log2 is already removed by the constant expression evaluator).
2011-04-14 11:52:06 -07:00
16 changed files with 1479 additions and 647 deletions

View File

@@ -63,6 +63,9 @@ const glsl_type glsl_type::builtin_core_types[] = {
};
const glsl_type *const glsl_type::bool_type = & builtin_core_types[0];
const glsl_type *const glsl_type::bvec2_type = & builtin_core_types[1];
const glsl_type *const glsl_type::bvec3_type = & builtin_core_types[2];
const glsl_type *const glsl_type::bvec4_type = & builtin_core_types[3];
const glsl_type *const glsl_type::int_type = & builtin_core_types[4];
const glsl_type *const glsl_type::ivec4_type = & builtin_core_types[7];
const glsl_type *const glsl_type::float_type = & builtin_core_types[8];

View File

@@ -450,6 +450,125 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
return t;
}
/**
* Convert sampler type attributes into an index in the sampler_types array
*/
#define SAMPLER_TYPE_INDEX(dim, sample_type, array, shadow) \
((unsigned(dim) * 12) | (sample_type * 4) | (unsigned(array) * 2) \
| unsigned(shadow))
/**
* \note
* Arrays like this are \b the argument for C99-style designated initializers.
* Too bad C++ and VisualStudio are too cool for that sort of useful
* functionality.
*/
const glsl_type *const glsl_type::sampler_types[] = {
/* GLSL_SAMPLER_DIM_1D */
&builtin_130_types[10], /* uint */
NULL, /* uint, shadow */
&builtin_130_types[5], /* uint, array */
NULL, /* uint, array, shadow */
&builtin_130_types[9], /* int */
NULL, /* int, shadow */
&builtin_130_types[4], /* int, array */
NULL, /* int, array, shadow */
&builtin_110_types[0], /* float */
&builtin_110_types[1], /* float, shadow */
&builtin_EXT_texture_array_types[0], /* float, array */
&builtin_EXT_texture_array_types[2], /* float, array, shadow */
/* GLSL_SAMPLER_DIM_2D */
&builtin_130_types[12], /* uint */
NULL, /* uint, shadow */
&builtin_130_types[7], /* uint, array */
NULL, /* uint, array, shadow */
&builtin_130_types[11], /* int */
NULL, /* int, shadow */
&builtin_130_types[6], /* int, array */
NULL, /* int, array, shadow */
&builtin_core_types[15], /* float */
&builtin_110_types[2], /* float, shadow */
&builtin_EXT_texture_array_types[1], /* float, array */
&builtin_EXT_texture_array_types[3], /* float, array, shadow */
/* GLSL_SAMPLER_DIM_3D */
&builtin_130_types[14], /* uint */
NULL, /* uint, shadow */
NULL, /* uint, array */
NULL, /* uint, array, shadow */
&builtin_130_types[13], /* int */
NULL, /* int, shadow */
NULL, /* int, array */
NULL, /* int, array, shadow */
&builtin_110_types[3], /* float */
NULL, /* float, shadow */
NULL, /* float, array */
NULL, /* float, array, shadow */
/* GLSL_SAMPLER_DIM_CUBE */
&builtin_130_types[16], /* uint */
NULL, /* uint, shadow */
NULL, /* uint, array */
NULL, /* uint, array, shadow */
&builtin_130_types[15], /* int */
NULL, /* int, shadow */
NULL, /* int, array */
NULL, /* int, array, shadow */
&builtin_core_types[16], /* float */
&builtin_130_types[8], /* float, shadow */
NULL, /* float, array */
NULL, /* float, array, shadow */
/* GLSL_SAMPLER_DIM_RECT */
NULL, /* uint */
NULL, /* uint, shadow */
NULL, /* uint, array */
NULL, /* uint, array, shadow */
NULL, /* int */
NULL, /* int, shadow */
NULL, /* int, array */
NULL, /* int, array, shadow */
&builtin_ARB_texture_rectangle_types[0], /* float */
&builtin_ARB_texture_rectangle_types[1], /* float, shadow */
NULL, /* float, array */
NULL, /* float, array, shadow */
/* GLSL_SAMPLER_DIM_BUF */
&builtin_EXT_texture_buffer_object_types[2], /* uint */
NULL, /* uint, shadow */
NULL, /* uint, array */
NULL, /* uint, array, shadow */
&builtin_EXT_texture_buffer_object_types[1], /* int */
NULL, /* int, shadow */
NULL, /* int, array */
NULL, /* int, array, shadow */
&builtin_EXT_texture_buffer_object_types[0], /* float */
NULL, /* float, shadow */
NULL, /* float, array */
NULL, /* float, array, shadow */
};
const glsl_type *
glsl_type::get_sampler_instance(glsl_sampler_dim dim,
bool shadow, bool array,
unsigned sample_type)
{
const glsl_type *const t =
sampler_types[SAMPLER_TYPE_INDEX(dim, sample_type, array, shadow)];
if (t == NULL)
return NULL;
assert(t->base_type == GLSL_TYPE_SAMPLER);
assert(t->sampler_dimensionality == dim);
assert(t->sampler_shadow == shadow);
assert(t->sampler_array == array);
assert(t->sampler_type == sample_type);
return t;
}
const glsl_type *
glsl_type::field_type(const char *name) const

View File

@@ -155,6 +155,9 @@ struct glsl_type {
static const glsl_type *const vec3_type;
static const glsl_type *const vec4_type;
static const glsl_type *const bool_type;
static const glsl_type *const bvec2_type;
static const glsl_type *const bvec3_type;
static const glsl_type *const bvec4_type;
static const glsl_type *const mat2_type;
static const glsl_type *const mat2x3_type;
static const glsl_type *const mat2x4_type;
@@ -208,6 +211,13 @@ struct glsl_type {
unsigned num_fields,
const char *name);
/**
* Get the instance of a sampler type
*/
static const glsl_type *get_sampler_instance(glsl_sampler_dim dim,
bool shadow, bool array,
unsigned sample_type);
/**
* Query the total number of scalars that make up a scalar, vector or matrix
*/
@@ -439,6 +449,13 @@ private:
static const glsl_type builtin_EXT_texture_buffer_object_types[];
/*@}*/
/**
* Table of sampler types used internally by get_sampler_instance
*
* \sa glsl_type::get_sampler_instance
*/
static const glsl_type *const sampler_types[];
/**
* \name Methods to populate a symbol table with built-in types.
*

View File

@@ -432,6 +432,7 @@ static const char *const operator_strs[] = {
"dFdx",
"dFdy",
"noise",
"lit",
"+",
"-",
"*",

View File

@@ -822,10 +822,19 @@ enum ir_expression_operation {
ir_unop_noise,
/**
* Calculate lighting coefficients
*
* Like this noise opcode, this opcode really shouldn't exist. The
* only reason it exists is to facilitate translation of assembly
* shaders to IR.
*/
ir_unop_lit,
/**
* A sentinel marking the last of the unary operations.
*/
ir_last_unop = ir_unop_noise,
ir_last_unop = ir_unop_lit,
ir_binop_add,
ir_binop_sub,

View File

@@ -29,12 +29,14 @@
*/
/* Operations for lower_instructions() */
#define SUB_TO_ADD_NEG 0x01
#define DIV_TO_MUL_RCP 0x02
#define EXP_TO_EXP2 0x04
#define POW_TO_EXP2 0x08
#define LOG_TO_LOG2 0x10
#define MOD_TO_FRACT 0x20
#define SUB_TO_ADD_NEG (1U << 0)
#define DIV_TO_MUL_RCP (1U << 1)
#define EXP_TO_EXP2 (1U << 2)
#define EXP_TO_POW (1U << 3)
#define POW_TO_EXP2 (1U << 4)
#define LOG_TO_LOG2 (1U << 5)
#define MOD_TO_FRACT (1U << 6)
#define LIT_TO_POW_FLAT (1U << 7)
bool do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations);

View File

@@ -301,6 +301,11 @@ ir_validate::visit_leave(ir_expression *ir)
assert(ir->operands[0]->type == ir->type);
break;
case ir_unop_lit:
assert(ir->type == glsl_type::vec4_type);
assert(ir->operands[0]->type == glsl_type::vec4_type);
break;
case ir_unop_noise:
/* XXX what can we assert here? */
break;

View File

@@ -33,9 +33,11 @@
* - SUB_TO_ADD_NEG
* - DIV_TO_MUL_RCP
* - EXP_TO_EXP2
* - EXP_TO_POW
* - POW_TO_EXP2
* - LOG_TO_LOG2
* - MOD_TO_FRACT
* - LIT_TO_POW_FLAT
*
* SUB_TO_ADD_NEG:
* ---------------
@@ -62,6 +64,12 @@
* do have base 2 versions, so this pass converts exp and log to exp2
* and log2 operations.
*
* EXP_TO_POW:
* -----------
* Few if any GPUs have an instruction for e**x, but they may have an x**y
* instruction. For these GPUs, convert \c ir_unop_exp to a \c ir_binop_pow
* with an immediate value of e for the first parameter.
*
* POW_TO_EXP2:
* -----------
* Many older GPUs don't have an x**y instruction. For these GPUs, convert
@@ -74,6 +82,17 @@
* Many GPUs don't have a MOD instruction (945 and 965 included), and
* if we have to break it down like this anyway, it gives an
* opportunity to do things like constant fold the (1.0 / op1) easily.
*
* LIT_TO_POW_FLAT:
* ----------------
* Lower the LIT instruction into a sequence of equivalent instructions.
*
* New GPUs have removed support for the CISC-like LIT instruction. Instead,
* this must be implemented using a sequence of simpler instructions. Even some
* older GPUs, such as i915, lack support for a LIT instruction. This version
* of the lowering pass lowers \c ir_unop_lit to a sequence of IR that does
* \b not include an if-statement. In the future it may be beneficial to add
* a version of the lowering pass that generates an if-statement.
*/
#include "main/core.h" /* for M_LOG2E */
@@ -97,8 +116,10 @@ private:
void div_to_mul_rcp(ir_expression *);
void mod_to_fract(ir_expression *);
void exp_to_exp2(ir_expression *);
void exp_to_pow(ir_expression *);
void pow_to_exp2(ir_expression *);
void log_to_log2(ir_expression *);
void lit_to_pow_flat(ir_expression *ir);
};
/**
@@ -187,6 +208,15 @@ lower_instructions_visitor::exp_to_exp2(ir_expression *ir)
this->progress = true;
}
void
lower_instructions_visitor::exp_to_pow(ir_expression *ir)
{
ir->operation = ir_binop_pow;
ir->operands[1] = ir->operands[0];
ir->operands[0] = new(ir) ir_constant(float(M_E));
this->progress = true;
}
void
lower_instructions_visitor::pow_to_exp2(ir_expression *ir)
{
@@ -246,10 +276,130 @@ lower_instructions_visitor::mod_to_fract(ir_expression *ir)
this->progress = true;
}
void
lower_instructions_visitor::lit_to_pow_flat(ir_expression *ir)
{
ir_instruction *inst;
/* The ARB_vertex_program spec says that LIT does:
*
* tmp = VectorLoad(op0);
* if (tmp.x < 0) tmp.x = 0;
* if (tmp.y < 0) tmp.y = 0;
* if (tmp.w < -(128.0-epsilon)) tmp.w = -(128.0-epsilon);
* else if (tmp.w > 128-epsilon) tmp.w = 128-epsilon;
* result.x = 1.0;
* result.y = tmp.x;
* result.z = (tmp.x > 0) ? RoughApproxPower(tmp.y, tmp.w) : 0.0;
* result.w = 1.0;
*
* This can be lowered to:
*
* tmp.yzw = max(vec3(0.0, 0.0, -(128.0 - epsilon)), op0.xyw);
* tmp.w = min(128.0 - epsilon, tmp.w);
* tmp.z = pow(tmp.z, tmp.w);
* tmp.xw = vec2(1.0, 1.0);
* if (tmp.y <= 0)
* tmp.z = 0;
*/
ir_variable *const tmp_var =
new(ir) ir_variable(glsl_type::vec4_type, "lit_tmp", ir_var_temporary);
this->base_ir->insert_before(tmp_var);
/* Generate 'tmp.yzw = max(vec3(0.0, 0.0, -(128.0 - epsilon)), op0.xyw);'
* The "other" API defined the minimum and maximum values used here as the
* values that can be represented in an 8.8 fixed-point value.
*/
ir_constant_data clamp_data = { { 0 } };
clamp_data.f[2] = (float) -(double(0x7fff) / 256.0);
ir_expression *const max_expr =
new(ir) ir_expression(ir_binop_max, glsl_type::vec3_type,
new(ir) ir_constant(glsl_type::vec3_type,
&clamp_data),
new(ir) ir_swizzle(ir->operands[0], 0, 1, 3, 0, 3));
inst = new(ir) ir_assignment(new(ir) ir_dereference_variable(tmp_var),
max_expr, NULL, 0x0E);
this->base_ir->insert_before(inst);
/* Generate 'tmp.w = min(128.0 - epsilon, tmp.w);'
*/
ir_rvalue *const tmp_w =
new(ir) ir_swizzle(new(ir) ir_dereference_variable(tmp_var),
3, 3, 3, 3, 1);
ir_expression *const min_expr =
new(ir) ir_expression(ir_binop_min, glsl_type::float_type,
new(ir) ir_constant(-clamp_data.f[2]),
tmp_w);
inst = new(ir) ir_assignment(new(ir) ir_dereference_variable(tmp_var),
min_expr, NULL, (1U << 3));
this->base_ir->insert_before(inst);
/* Generate 'tmp.z = pow(tmp.z, tmp.w);'
*/
ir_rvalue *const tmp_z =
new(ir) ir_swizzle(new(ir) ir_dereference_variable(tmp_var),
2, 2, 2, 2, 1);
ir_expression *const pow_expr =
new(ir) ir_expression(ir_binop_pow, glsl_type::float_type,
tmp_z, tmp_w->clone(ir, NULL));
inst = new(ir) ir_assignment(new(ir) ir_dereference_variable(tmp_var),
pow_expr,
NULL,
(1U << 2));
this->base_ir->insert_before(inst);
/* Generate 'tmp.xw = vec2(1.0, 1.0);'
*/
ir_constant_data output_data = { { 0 } };
output_data.f[0] = 1.0F;
output_data.f[1] = 1.0F;
inst = new(ir) ir_assignment(new(ir) ir_dereference_variable(tmp_var),
new(ir) ir_constant(glsl_type::vec2_type,
&output_data),
NULL,
0x09);
this->base_ir->insert_before(inst);
/* Generate 'if (tmp.y <= 0) tmp.z = 0;'
*/
ir_rvalue *const tmp_y =
new(ir) ir_swizzle(new(ir) ir_dereference_variable(tmp_var),
1, 1, 1, 1, 1);
ir_expression *const cmp_expr =
new(ir) ir_expression(ir_binop_lequal,
glsl_type::bool_type,
tmp_y,
new(ir) ir_constant(0.0F));
inst = new(ir) ir_assignment(new(ir) ir_dereference_variable(tmp_var),
new(ir) ir_constant(0.0F),
cmp_expr,
(1U << 2));
this->base_ir->insert_before(inst);
/* FINISHME: Convert lower_instructions_visitor to an ir_rvalue_visitor so
* FINISHME: that this ugly hack can be removed.
*/
ir->operation = ir_binop_add;
ir->operands[0] = new(ir) ir_dereference_variable(tmp_var);
ir->operands[1] = ir_constant::zero(ir, glsl_type::vec4_type);
this->progress = true;
}
ir_visitor_status
lower_instructions_visitor::visit_leave(ir_expression *ir)
{
switch (ir->operation) {
case ir_unop_lit:
if (lowering(LIT_TO_POW_FLAT))
lit_to_pow_flat(ir);
break;
case ir_binop_sub:
if (lowering(SUB_TO_ADD_NEG))
sub_to_add_neg(ir);
@@ -261,7 +411,9 @@ lower_instructions_visitor::visit_leave(ir_expression *ir)
break;
case ir_unop_exp:
if (lowering(EXP_TO_EXP2))
if (lowering(EXP_TO_POW))
exp_to_pow(ir);
else if (lowering(EXP_TO_EXP2))
exp_to_exp2(ir);
break;

View File

@@ -74,10 +74,10 @@ main/api_exec_es1.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py m
main/api_exec_es2.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py
$(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES2.0 > $@
program/program_parse.tab.c program/program_parse.tab.h: program/program_parse.y
bison -v -d --output=program/program_parse.tab.c $<
program/program_parse.cpp program/program_parse.tab.h: program/program_parse.y
bison -v -o program/program_parse.cpp --defines=program/program_parse.tab.h $<
program/lex.yy.c: program/program_lexer.l
program/program_lexer.cpp: program/program_lexer.l
flex --never-interactive --outfile=$@ $<
######################################################################

View File

@@ -100,7 +100,8 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
DIV_TO_MUL_RCP |
SUB_TO_ADD_NEG |
EXP_TO_EXP2 |
LOG_TO_LOG2);
LOG_TO_LOG2 |
LIT_TO_POW_FLAT);
/* Pre-gen6 HW can only nest if-statements 16 deep. Beyond this,
* if-statements need to be flattened.

View File

@@ -1195,6 +1195,10 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
break;
}
case ir_unop_lit:
emit(ir, OPCODE_LIT, result_dst, op[0]);
break;
case ir_binop_add:
emit(ir, OPCODE_ADD, result_dst, op[0], op[1]);
break;

View File

@@ -21,11 +21,17 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
extern "C" {
#include "main/glheader.h"
#include "main/imports.h"
#include "program/prog_instruction.h"
#include "program/prog_statevars.h"
#include "program/symbol_table.h"
};
#include "glsl_types.h"
#include "ir.h"
#include "program/program_parser.h"
#include "program/program_parse.tab.h"
@@ -60,19 +66,34 @@
} while (0)
#define return_opcode(condition, token, opcode, len) \
#define return_opcode(condition, token, len) \
do { \
if (condition && \
_mesa_parse_instruction_suffix(yyextra, \
yytext + len, \
& yylval->temp_inst)) { \
yylval->temp_inst.Opcode = OPCODE_ ## opcode; \
& yylval->opcode)) { \
yylval->opcode.opcode = 0; \
return token; \
} else { \
return handle_ident(yyextra, yytext, yylval); \
} \
} while (0)
#define return_common(condition, token, _opcode, len) \
do { \
if (condition && \
_mesa_parse_instruction_suffix(yyextra, \
yytext + len, \
& yylval->opcode)) { \
yylval->opcode.opcode = _opcode; \
return token; \
} else { \
return handle_ident(yyextra, yytext, yylval); \
} \
} while (0)
#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
SWIZZLE_NIL, SWIZZLE_NIL)
@@ -182,74 +203,76 @@ OUTPUT { return OUTPUT; }
PARAM { return PARAM; }
TEMP { yylval->integer = at_temp; return TEMP; }
ABS{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, ABS, 3); }
ADD{sz}{cc}{sat} { return_opcode( 1, BIN_OP, ADD, 3); }
ARL { return_opcode(require_ARB_vp, ARL, ARL, 3); }
ABS{sz}{cc}{sat} { return_common( true, VECTOR_OP, ir_unop_abs, 3); }
ADD{sz}{cc}{sat} { return_common( true, BIN_OP, ir_binop_add, 3); }
ARL { return_opcode(require_ARB_vp, ARL, 3); }
CMP{sat} { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
COS{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
CMP{sat} { return_opcode(require_ARB_fp, CMP_OP, 3); }
COS{szf}{cc}{sat} { return_common(require_ARB_fp, SCALAR_OP, ir_unop_cos, 3); }
DDX{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDX, 3); }
DDY{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDY, 3); }
DP3{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP3, 3); }
DP4{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP4, 3); }
DPH{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DPH, 3); }
DST{szf}{cc}{sat} { return_opcode( 1, BIN_OP, DST, 3); }
DDX{szf}{cc}{sat} { return_common(require_NV_fp, VECTOR_OP, ir_unop_dFdx, 3); }
DDY{szf}{cc}{sat} { return_common(require_NV_fp, VECTOR_OP, ir_unop_dFdy, 3); }
DP3{sz}{cc}{sat} { return_opcode( true, DP3_OP, 3); }
DP4{sz}{cc}{sat} { return_opcode( true, DP4_OP, 3); }
DPH{sz}{cc}{sat} { return_opcode( true, DPH_OP, 3); }
DST{szf}{cc}{sat} { return_opcode( true, DST_OP, 3); }
EX2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, EX2, 3); }
EXP { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
EX2{szf}{cc}{sat} { return_common( true, SCALAR_OP, ir_unop_exp, 3); }
/* FINISHME: Somehow communicate that this is the low precision version. */
EXP { return_common(require_ARB_vp, SCALAR_OP, ir_unop_exp, 3); }
FLR{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FLR, 3); }
FRC{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FRC, 3); }
FLR{sz}{cc}{sat} { return_common( true, VECTOR_OP, ir_unop_floor, 3); }
FRC{sz}{cc}{sat} { return_common( true, VECTOR_OP, ir_unop_fract, 3); }
KIL { return_opcode(require_ARB_fp, KIL, KIL, 3); }
KIL { return_opcode(require_ARB_fp, KIL, 3); }
LIT{szf}{cc}{sat} { return_opcode( 1, VECTOR_OP, LIT, 3); }
LG2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, LG2, 3); }
LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
LRP{sz}{cc}{sat} { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
LIT{szf}{cc}{sat} { return_common( true, VECTOR_OP, ir_unop_lit, 3); }
LG2{szf}{cc}{sat} { return_common( true, SCALAR_OP, ir_unop_log, 3); }
/* FINISHME: Somehow communicate that this is the low precision version. */
LOG { return_common(require_ARB_vp, SCALAR_OP, ir_unop_log, 3); }
LRP{sz}{cc}{sat} { return_opcode(require_ARB_fp, LRP_OP, 3); }
MAD{sz}{cc}{sat} { return_opcode( 1, TRI_OP, MAD, 3); }
MAX{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MAX, 3); }
MIN{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MIN, 3); }
MOV{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, MOV, 3); }
MUL{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MUL, 3); }
MAD{sz}{cc}{sat} { return_common( true, MAD_OP, ir_binop_mul, 3); }
MAX{sz}{cc}{sat} { return_common( true, BIN_OP, ir_binop_max, 3); }
MIN{sz}{cc}{sat} { return_common( true, BIN_OP, ir_binop_min, 3); }
MOV{sz}{cc}{sat} { return_common( true, MOV_OP, ir_binop_add, 3); }
MUL{sz}{cc}{sat} { return_common( true, BIN_OP, ir_binop_mul, 3); }
PK2H { return_opcode(require_NV_fp, VECTOR_OP, PK2H, 4); }
PK2US { return_opcode(require_NV_fp, VECTOR_OP, PK2US, 5); }
PK4B { return_opcode(require_NV_fp, VECTOR_OP, PK4B, 4); }
PK4UB { return_opcode(require_NV_fp, VECTOR_OP, PK4UB, 5); }
POW{szf}{cc}{sat} { return_opcode( 1, BINSC_OP, POW, 3); }
PK2H { return_opcode(require_NV_fp, PACK_OP, 4); }
PK2US { return_opcode(require_NV_fp, PACK_OP, 5); }
PK4B { return_opcode(require_NV_fp, PACK_OP, 4); }
PK4UB { return_opcode(require_NV_fp, PACK_OP, 5); }
POW{szf}{cc}{sat} { return_common( true, BINSC_OP, ir_binop_pow, 3); }
RCP{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RCP, 3); }
RFL{szf}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, RFL, 3); }
RSQ{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RSQ, 3); }
RCP{szf}{cc}{sat} { return_common( true, SCALAR_OP, ir_unop_rcp, 3); }
RFL{szf}{cc}{sat} { return_opcode(require_NV_fp, RFL_OP, 3); }
RSQ{szf}{cc}{sat} { return_common( true, SCALAR_OP, ir_unop_rsq, 3); }
SCS{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
SEQ{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SEQ, 3); }
SFL{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SFL, 3); }
SGE{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SGE, 3); }
SGT{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SGT, 3); }
SIN{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
SLE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SLE, 3); }
SLT{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SLT, 3); }
SNE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SNE, 3); }
STR{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, STR, 3); }
SUB{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SUB, 3); }
SWZ{sat} { return_opcode( 1, SWZ, SWZ, 3); }
SCS{sat} { return_opcode(require_ARB_fp, SCS_OP, 3); }
SEQ{sz}{cc}{sat} { return_common(require_NV_fp, SET_OP, ir_binop_equal, 3); }
SFL{sz}{cc}{sat} { return_opcode(require_NV_fp, SFL_OP, 3); }
SGE{sz}{cc}{sat} { return_common( true, SET_OP, ir_binop_gequal, 3); }
SGT{sz}{cc}{sat} { return_common(require_NV_fp, SET_OP, ir_binop_greater, 3); }
SIN{szf}{cc}{sat} { return_common(require_ARB_fp, SCALAR_OP, ir_unop_sin, 3); }
SLE{sz}{cc}{sat} { return_common(require_NV_fp, SET_OP, ir_binop_lequal, 3); }
SLT{sz}{cc}{sat} { return_common( true, SET_OP, ir_binop_less, 3); }
SNE{sz}{cc}{sat} { return_common(require_NV_fp, SET_OP, ir_binop_nequal, 3); }
STR{sz}{cc}{sat} { return_opcode(require_NV_fp, STR_OP, 3); }
SUB{sz}{cc}{sat} { return_common( true, BIN_OP, ir_binop_sub, 3); }
SWZ{sat} { return_opcode( true, SWZ_OP, 3); }
TEX{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
TXB{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
TXD{cc}{sat} { return_opcode(require_NV_fp, TXD_OP, TXD, 3); }
TXP{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
TEX{cc}{sat} { return_opcode(require_ARB_fp, TEX_OP, 3); }
TXB{cc}{sat} { return_opcode(require_ARB_fp, TXB_OP, 3); }
TXD{cc}{sat} { return_opcode(require_NV_fp, TXD_OP, 3); }
TXP{cc}{sat} { return_opcode(require_ARB_fp, TXP_OP, 3); }
UP2H{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2H, 4); }
UP2US{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2US, 5); }
UP4B{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4B, 4); }
UP4UB{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4UB, 5); }
UP2H{cc}{sat} { return_opcode(require_NV_fp, UNPACK_OP, 4); }
UP2US{cc}{sat} { return_opcode(require_NV_fp, UNPACK_OP, 5); }
UP4B{cc}{sat} { return_opcode(require_NV_fp, UNPACK_OP, 4); }
UP4UB{cc}{sat} { return_opcode(require_NV_fp, UNPACK_OP, 5); }
X2D{szf}{cc}{sat} { return_opcode(require_NV_fp, TRI_OP, X2D, 3); }
XPD{sat} { return_opcode( 1, BIN_OP, XPD, 3); }
X2D{szf}{cc}{sat} { return_opcode(require_NV_fp, X2D_OP, 3); }
XPD{sat} { return_opcode( true, XPD_OP, 3); }
vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }

File diff suppressed because it is too large Load Diff

View File

@@ -36,12 +36,12 @@
int
_mesa_parse_instruction_suffix(const struct asm_parser_state *state,
const char *suffix,
struct prog_instruction *inst)
struct asm_opcode *inst)
{
inst->CondUpdate = 0;
inst->CondDst = 0;
inst->SaturateMode = SATURATE_OFF;
inst->Precision = FLOAT32;
inst->cond_update = 0;
inst->cond_dst = 0;
inst->saturate_mode = SATURATE_OFF;
inst->precision = FLOAT32;
/* The first possible suffix element is the precision specifier from
@@ -50,15 +50,15 @@ _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
if (state->option.NV_fragment) {
switch (suffix[0]) {
case 'H':
inst->Precision = FLOAT16;
inst->precision = FLOAT16;
suffix++;
break;
case 'R':
inst->Precision = FLOAT32;
inst->precision = FLOAT32;
suffix++;
break;
case 'X':
inst->Precision = FIXED12;
inst->precision = FIXED12;
suffix++;
break;
default:
@@ -71,7 +71,7 @@ _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
*/
if (state->option.NV_fragment) {
if (suffix[0] == 'C') {
inst->CondUpdate = 1;
inst->cond_update = 1;
suffix++;
}
}
@@ -82,7 +82,7 @@ _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
*/
if (state->mode == ARB_fragment) {
if (strcmp(suffix, "_SAT") == 0) {
inst->SaturateMode = SATURATE_ZERO_ONE;
inst->saturate_mode = SATURATE_ZERO_ONE;
suffix += 4;
}
}

View File

@@ -22,7 +22,10 @@
*/
#pragma once
#include <stdbool.h>
#include "main/config.h"
#include "main/mtypes.h"
#include "list.h"
struct gl_context;
@@ -45,7 +48,7 @@ struct asm_symbol {
/**
* One of PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, or PROGRAM_ENV_PARAM.
*/
unsigned param_binding_type;
gl_register_file param_binding_type;
/**
* Offset into the program_parameter_list where the tokens representing our
@@ -120,6 +123,60 @@ struct asm_src_register {
};
struct asm_opcode {
/**
* This should be 'enum ir_expression_operation', but it can't be. This
* file is included in C source, and the enum comes from a C++ header. The
* rules for enums in C and C++ are so broken that you can't declare an
* enum varaible without having seen the full enum declaration. Even after
* seeing it, the compiler is just going to allocate an int, so WTF?
*/
unsigned opcode;
/**
* Indicates that the instruction should update the condition code
* register.
*
* \since
* NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
* NV_vertex_program2_option.
*/
unsigned cond_update:1;
/**
* If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the
* condition code register that is to be updated.
*
* In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition
* code register 0 is available. In GL_NV_vertex_program3 mode, condition
* code registers 0 and 1 are available.
*
* \since
* NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
* NV_vertex_program2_option.
*/
unsigned cond_dst:1;
/**
* Saturate each value of the vectored result to the range [0,1] or the
* range [-1,1]. \c SSAT mode (i.e., saturation to the range [-1,1]) is
* only available in NV_fragment_program2 mode.
* Value is one of the SATURATE_* tokens.
*
* \since
* NV_fragment_program, NV_fragment_program_option, NV_vertex_program3.
*/
unsigned saturate_mode:2;
/**
* Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12.
*
* \since
* NV_fragment_program, NV_fragment_program_option.
*/
unsigned precision:3;
};
struct asm_instruction {
struct prog_instruction Base;
struct asm_instruction *next;
@@ -127,9 +184,16 @@ struct asm_instruction {
};
enum asm_program_target {
invalid_mode = 0,
ARB_vertex,
ARB_fragment
};
struct asm_parser_state {
struct gl_context *ctx;
struct gl_program *prog;
struct exec_list ir;
/**
* Per-program target limits
@@ -191,11 +255,7 @@ struct asm_parser_state {
*/
unsigned InputsBound;
enum {
invalid_mode = 0,
ARB_vertex,
ARB_fragment
} mode;
enum asm_program_target mode;
struct {
unsigned PositionInvariant:1;
@@ -233,6 +293,9 @@ typedef struct YYLTYPE {
#define YYLTYPE_IS_DECLARED 1
#define YYLTYPE_IS_TRIVIAL 1
#ifdef __cplusplus
extern "C" {
#endif
extern GLboolean _mesa_parse_arb_program(struct gl_context *ctx, GLenum target,
const GLubyte *str, GLsizei len, struct asm_parser_state *state);
@@ -281,7 +344,7 @@ extern int _mesa_ARBfp_parse_option(struct asm_parser_state *state,
* Non-zero on success, zero on failure.
*/
extern int _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
const char *suffix, struct prog_instruction *inst);
const char *suffix, struct asm_opcode *inst);
/**
* Parses a condition code name
@@ -296,4 +359,8 @@ extern int _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
*/
extern int _mesa_parse_cc(const char *s);
#ifdef __cplusplus
};
#endif
/*@}*/

View File

@@ -240,11 +240,9 @@ STATETRACKER_SOURCES = \
PROGRAM_SOURCES = \
program/arbprogparse.c \
program/hash_table.c \
program/lex.yy.c \
program/nvfragparse.c \
program/nvvertparse.c \
program/program.c \
program/program_parse.tab.c \
program/program_parse_extra.c \
program/prog_cache.c \
program/prog_execute.c \
@@ -262,6 +260,8 @@ PROGRAM_SOURCES = \
SHADER_CXX_SOURCES = \
program/program_lexer.cpp \
program/program_parse.cpp \
program/ir_to_mesa.cpp \
program/sampler.cpp