Compare commits
6 Commits
mesa-11.1.
...
useful
Author | SHA1 | Date | |
---|---|---|---|
|
d6db9143b6 | ||
|
9c0b233c44 | ||
|
364aa72824 | ||
|
d290ec228b | ||
|
c0906e06ee | ||
|
b6c49104ce |
@@ -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::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::int_type = & builtin_core_types[4];
|
||||||
const glsl_type *const glsl_type::ivec4_type = & builtin_core_types[7];
|
const glsl_type *const glsl_type::ivec4_type = & builtin_core_types[7];
|
||||||
const glsl_type *const glsl_type::float_type = & builtin_core_types[8];
|
const glsl_type *const glsl_type::float_type = & builtin_core_types[8];
|
||||||
|
@@ -450,6 +450,125 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
|
|||||||
return t;
|
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 *
|
const glsl_type *
|
||||||
glsl_type::field_type(const char *name) const
|
glsl_type::field_type(const char *name) const
|
||||||
|
@@ -155,6 +155,9 @@ struct glsl_type {
|
|||||||
static const glsl_type *const vec3_type;
|
static const glsl_type *const vec3_type;
|
||||||
static const glsl_type *const vec4_type;
|
static const glsl_type *const vec4_type;
|
||||||
static const glsl_type *const bool_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 mat2_type;
|
||||||
static const glsl_type *const mat2x3_type;
|
static const glsl_type *const mat2x3_type;
|
||||||
static const glsl_type *const mat2x4_type;
|
static const glsl_type *const mat2x4_type;
|
||||||
@@ -208,6 +211,13 @@ struct glsl_type {
|
|||||||
unsigned num_fields,
|
unsigned num_fields,
|
||||||
const char *name);
|
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
|
* 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[];
|
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.
|
* \name Methods to populate a symbol table with built-in types.
|
||||||
*
|
*
|
||||||
|
@@ -432,6 +432,7 @@ static const char *const operator_strs[] = {
|
|||||||
"dFdx",
|
"dFdx",
|
||||||
"dFdy",
|
"dFdy",
|
||||||
"noise",
|
"noise",
|
||||||
|
"lit",
|
||||||
"+",
|
"+",
|
||||||
"-",
|
"-",
|
||||||
"*",
|
"*",
|
||||||
|
@@ -822,10 +822,19 @@ enum ir_expression_operation {
|
|||||||
|
|
||||||
ir_unop_noise,
|
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.
|
* 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_add,
|
||||||
ir_binop_sub,
|
ir_binop_sub,
|
||||||
|
@@ -29,12 +29,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Operations for lower_instructions() */
|
/* Operations for lower_instructions() */
|
||||||
#define SUB_TO_ADD_NEG 0x01
|
#define SUB_TO_ADD_NEG (1U << 0)
|
||||||
#define DIV_TO_MUL_RCP 0x02
|
#define DIV_TO_MUL_RCP (1U << 1)
|
||||||
#define EXP_TO_EXP2 0x04
|
#define EXP_TO_EXP2 (1U << 2)
|
||||||
#define POW_TO_EXP2 0x08
|
#define EXP_TO_POW (1U << 3)
|
||||||
#define LOG_TO_LOG2 0x10
|
#define POW_TO_EXP2 (1U << 4)
|
||||||
#define MOD_TO_FRACT 0x20
|
#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);
|
bool do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations);
|
||||||
|
|
||||||
|
@@ -301,6 +301,11 @@ ir_validate::visit_leave(ir_expression *ir)
|
|||||||
assert(ir->operands[0]->type == ir->type);
|
assert(ir->operands[0]->type == ir->type);
|
||||||
break;
|
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:
|
case ir_unop_noise:
|
||||||
/* XXX what can we assert here? */
|
/* XXX what can we assert here? */
|
||||||
break;
|
break;
|
||||||
|
@@ -33,9 +33,11 @@
|
|||||||
* - SUB_TO_ADD_NEG
|
* - SUB_TO_ADD_NEG
|
||||||
* - DIV_TO_MUL_RCP
|
* - DIV_TO_MUL_RCP
|
||||||
* - EXP_TO_EXP2
|
* - EXP_TO_EXP2
|
||||||
|
* - EXP_TO_POW
|
||||||
* - POW_TO_EXP2
|
* - POW_TO_EXP2
|
||||||
* - LOG_TO_LOG2
|
* - LOG_TO_LOG2
|
||||||
* - MOD_TO_FRACT
|
* - MOD_TO_FRACT
|
||||||
|
* - LIT_TO_POW_FLAT
|
||||||
*
|
*
|
||||||
* SUB_TO_ADD_NEG:
|
* SUB_TO_ADD_NEG:
|
||||||
* ---------------
|
* ---------------
|
||||||
@@ -62,6 +64,12 @@
|
|||||||
* do have base 2 versions, so this pass converts exp and log to exp2
|
* do have base 2 versions, so this pass converts exp and log to exp2
|
||||||
* and log2 operations.
|
* 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:
|
* POW_TO_EXP2:
|
||||||
* -----------
|
* -----------
|
||||||
* Many older GPUs don't have an x**y instruction. For these GPUs, convert
|
* 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
|
* 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
|
* 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.
|
* 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 */
|
#include "main/core.h" /* for M_LOG2E */
|
||||||
@@ -97,8 +116,10 @@ private:
|
|||||||
void div_to_mul_rcp(ir_expression *);
|
void div_to_mul_rcp(ir_expression *);
|
||||||
void mod_to_fract(ir_expression *);
|
void mod_to_fract(ir_expression *);
|
||||||
void exp_to_exp2(ir_expression *);
|
void exp_to_exp2(ir_expression *);
|
||||||
|
void exp_to_pow(ir_expression *);
|
||||||
void pow_to_exp2(ir_expression *);
|
void pow_to_exp2(ir_expression *);
|
||||||
void log_to_log2(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;
|
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
|
void
|
||||||
lower_instructions_visitor::pow_to_exp2(ir_expression *ir)
|
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;
|
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
|
ir_visitor_status
|
||||||
lower_instructions_visitor::visit_leave(ir_expression *ir)
|
lower_instructions_visitor::visit_leave(ir_expression *ir)
|
||||||
{
|
{
|
||||||
switch (ir->operation) {
|
switch (ir->operation) {
|
||||||
|
case ir_unop_lit:
|
||||||
|
if (lowering(LIT_TO_POW_FLAT))
|
||||||
|
lit_to_pow_flat(ir);
|
||||||
|
break;
|
||||||
|
|
||||||
case ir_binop_sub:
|
case ir_binop_sub:
|
||||||
if (lowering(SUB_TO_ADD_NEG))
|
if (lowering(SUB_TO_ADD_NEG))
|
||||||
sub_to_add_neg(ir);
|
sub_to_add_neg(ir);
|
||||||
@@ -261,7 +411,9 @@ lower_instructions_visitor::visit_leave(ir_expression *ir)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ir_unop_exp:
|
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);
|
exp_to_exp2(ir);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -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
|
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 > $@
|
$(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
|
program/program_parse.cpp program/program_parse.tab.h: program/program_parse.y
|
||||||
bison -v -d --output=program/program_parse.tab.c $<
|
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=$@ $<
|
flex --never-interactive --outfile=$@ $<
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
@@ -100,7 +100,8 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
|
|||||||
DIV_TO_MUL_RCP |
|
DIV_TO_MUL_RCP |
|
||||||
SUB_TO_ADD_NEG |
|
SUB_TO_ADD_NEG |
|
||||||
EXP_TO_EXP2 |
|
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,
|
/* Pre-gen6 HW can only nest if-statements 16 deep. Beyond this,
|
||||||
* if-statements need to be flattened.
|
* if-statements need to be flattened.
|
||||||
|
@@ -1195,6 +1195,10 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ir_unop_lit:
|
||||||
|
emit(ir, OPCODE_LIT, result_dst, op[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
case ir_binop_add:
|
case ir_binop_add:
|
||||||
emit(ir, OPCODE_ADD, result_dst, op[0], op[1]);
|
emit(ir, OPCODE_ADD, result_dst, op[0], op[1]);
|
||||||
break;
|
break;
|
||||||
|
@@ -21,11 +21,17 @@
|
|||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
* DEALINGS IN THE SOFTWARE.
|
* DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
#include "main/glheader.h"
|
#include "main/glheader.h"
|
||||||
#include "main/imports.h"
|
#include "main/imports.h"
|
||||||
#include "program/prog_instruction.h"
|
#include "program/prog_instruction.h"
|
||||||
#include "program/prog_statevars.h"
|
#include "program/prog_statevars.h"
|
||||||
#include "program/symbol_table.h"
|
#include "program/symbol_table.h"
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "glsl_types.h"
|
||||||
|
#include "ir.h"
|
||||||
#include "program/program_parser.h"
|
#include "program/program_parser.h"
|
||||||
#include "program/program_parse.tab.h"
|
#include "program/program_parse.tab.h"
|
||||||
|
|
||||||
@@ -60,19 +66,34 @@
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
#define return_opcode(condition, token, opcode, len) \
|
#define return_opcode(condition, token, len) \
|
||||||
do { \
|
do { \
|
||||||
if (condition && \
|
if (condition && \
|
||||||
_mesa_parse_instruction_suffix(yyextra, \
|
_mesa_parse_instruction_suffix(yyextra, \
|
||||||
yytext + len, \
|
yytext + len, \
|
||||||
& yylval->temp_inst)) { \
|
& yylval->opcode)) { \
|
||||||
yylval->temp_inst.Opcode = OPCODE_ ## opcode; \
|
yylval->opcode.opcode = 0; \
|
||||||
return token; \
|
return token; \
|
||||||
} else { \
|
} else { \
|
||||||
return handle_ident(yyextra, yytext, yylval); \
|
return handle_ident(yyextra, yytext, yylval); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} 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, \
|
#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
|
||||||
SWIZZLE_NIL, SWIZZLE_NIL)
|
SWIZZLE_NIL, SWIZZLE_NIL)
|
||||||
|
|
||||||
@@ -182,74 +203,76 @@ OUTPUT { return OUTPUT; }
|
|||||||
PARAM { return PARAM; }
|
PARAM { return PARAM; }
|
||||||
TEMP { yylval->integer = at_temp; return TEMP; }
|
TEMP { yylval->integer = at_temp; return TEMP; }
|
||||||
|
|
||||||
ABS{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, ABS, 3); }
|
ABS{sz}{cc}{sat} { return_common( true, VECTOR_OP, ir_unop_abs, 3); }
|
||||||
ADD{sz}{cc}{sat} { return_opcode( 1, BIN_OP, ADD, 3); }
|
ADD{sz}{cc}{sat} { return_common( true, BIN_OP, ir_binop_add, 3); }
|
||||||
ARL { return_opcode(require_ARB_vp, ARL, ARL, 3); }
|
ARL { return_opcode(require_ARB_vp, ARL, 3); }
|
||||||
|
|
||||||
CMP{sat} { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
|
CMP{sat} { return_opcode(require_ARB_fp, CMP_OP, 3); }
|
||||||
COS{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, COS, 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); }
|
DDX{szf}{cc}{sat} { return_common(require_NV_fp, VECTOR_OP, ir_unop_dFdx, 3); }
|
||||||
DDY{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDY, 3); }
|
DDY{szf}{cc}{sat} { return_common(require_NV_fp, VECTOR_OP, ir_unop_dFdy, 3); }
|
||||||
DP3{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP3, 3); }
|
DP3{sz}{cc}{sat} { return_opcode( true, DP3_OP, 3); }
|
||||||
DP4{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP4, 3); }
|
DP4{sz}{cc}{sat} { return_opcode( true, DP4_OP, 3); }
|
||||||
DPH{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DPH, 3); }
|
DPH{sz}{cc}{sat} { return_opcode( true, DPH_OP, 3); }
|
||||||
DST{szf}{cc}{sat} { return_opcode( 1, BIN_OP, DST, 3); }
|
DST{szf}{cc}{sat} { return_opcode( true, DST_OP, 3); }
|
||||||
|
|
||||||
EX2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, EX2, 3); }
|
EX2{szf}{cc}{sat} { return_common( true, SCALAR_OP, ir_unop_exp, 3); }
|
||||||
EXP { return_opcode(require_ARB_vp, SCALAR_OP, 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); }
|
FLR{sz}{cc}{sat} { return_common( true, VECTOR_OP, ir_unop_floor, 3); }
|
||||||
FRC{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FRC, 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); }
|
LIT{szf}{cc}{sat} { return_common( true, VECTOR_OP, ir_unop_lit, 3); }
|
||||||
LG2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, LG2, 3); }
|
LG2{szf}{cc}{sat} { return_common( true, SCALAR_OP, ir_unop_log, 3); }
|
||||||
LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
|
/* FINISHME: Somehow communicate that this is the low precision version. */
|
||||||
LRP{sz}{cc}{sat} { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
|
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); }
|
MAD{sz}{cc}{sat} { return_common( true, MAD_OP, ir_binop_mul, 3); }
|
||||||
MAX{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MAX, 3); }
|
MAX{sz}{cc}{sat} { return_common( true, BIN_OP, ir_binop_max, 3); }
|
||||||
MIN{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MIN, 3); }
|
MIN{sz}{cc}{sat} { return_common( true, BIN_OP, ir_binop_min, 3); }
|
||||||
MOV{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, MOV, 3); }
|
MOV{sz}{cc}{sat} { return_common( true, MOV_OP, ir_binop_add, 3); }
|
||||||
MUL{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MUL, 3); }
|
MUL{sz}{cc}{sat} { return_common( true, BIN_OP, ir_binop_mul, 3); }
|
||||||
|
|
||||||
PK2H { return_opcode(require_NV_fp, VECTOR_OP, PK2H, 4); }
|
PK2H { return_opcode(require_NV_fp, PACK_OP, 4); }
|
||||||
PK2US { return_opcode(require_NV_fp, VECTOR_OP, PK2US, 5); }
|
PK2US { return_opcode(require_NV_fp, PACK_OP, 5); }
|
||||||
PK4B { return_opcode(require_NV_fp, VECTOR_OP, PK4B, 4); }
|
PK4B { return_opcode(require_NV_fp, PACK_OP, 4); }
|
||||||
PK4UB { return_opcode(require_NV_fp, VECTOR_OP, PK4UB, 5); }
|
PK4UB { return_opcode(require_NV_fp, PACK_OP, 5); }
|
||||||
POW{szf}{cc}{sat} { return_opcode( 1, BINSC_OP, POW, 3); }
|
POW{szf}{cc}{sat} { return_common( true, BINSC_OP, ir_binop_pow, 3); }
|
||||||
|
|
||||||
RCP{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RCP, 3); }
|
RCP{szf}{cc}{sat} { return_common( true, SCALAR_OP, ir_unop_rcp, 3); }
|
||||||
RFL{szf}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, RFL, 3); }
|
RFL{szf}{cc}{sat} { return_opcode(require_NV_fp, RFL_OP, 3); }
|
||||||
RSQ{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RSQ, 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); }
|
SCS{sat} { return_opcode(require_ARB_fp, SCS_OP, 3); }
|
||||||
SEQ{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SEQ, 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, BIN_OP, SFL, 3); }
|
SFL{sz}{cc}{sat} { return_opcode(require_NV_fp, SFL_OP, 3); }
|
||||||
SGE{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SGE, 3); }
|
SGE{sz}{cc}{sat} { return_common( true, SET_OP, ir_binop_gequal, 3); }
|
||||||
SGT{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SGT, 3); }
|
SGT{sz}{cc}{sat} { return_common(require_NV_fp, SET_OP, ir_binop_greater, 3); }
|
||||||
SIN{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
|
SIN{szf}{cc}{sat} { return_common(require_ARB_fp, SCALAR_OP, ir_unop_sin, 3); }
|
||||||
SLE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SLE, 3); }
|
SLE{sz}{cc}{sat} { return_common(require_NV_fp, SET_OP, ir_binop_lequal, 3); }
|
||||||
SLT{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SLT, 3); }
|
SLT{sz}{cc}{sat} { return_common( true, SET_OP, ir_binop_less, 3); }
|
||||||
SNE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SNE, 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, BIN_OP, STR, 3); }
|
STR{sz}{cc}{sat} { return_opcode(require_NV_fp, STR_OP, 3); }
|
||||||
SUB{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SUB, 3); }
|
SUB{sz}{cc}{sat} { return_common( true, BIN_OP, ir_binop_sub, 3); }
|
||||||
SWZ{sat} { return_opcode( 1, SWZ, SWZ, 3); }
|
SWZ{sat} { return_opcode( true, SWZ_OP, 3); }
|
||||||
|
|
||||||
TEX{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
|
TEX{cc}{sat} { return_opcode(require_ARB_fp, TEX_OP, 3); }
|
||||||
TXB{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
|
TXB{cc}{sat} { return_opcode(require_ARB_fp, TXB_OP, 3); }
|
||||||
TXD{cc}{sat} { return_opcode(require_NV_fp, TXD_OP, TXD, 3); }
|
TXD{cc}{sat} { return_opcode(require_NV_fp, TXD_OP, 3); }
|
||||||
TXP{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
|
TXP{cc}{sat} { return_opcode(require_ARB_fp, TXP_OP, 3); }
|
||||||
|
|
||||||
UP2H{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2H, 4); }
|
UP2H{cc}{sat} { return_opcode(require_NV_fp, UNPACK_OP, 4); }
|
||||||
UP2US{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2US, 5); }
|
UP2US{cc}{sat} { return_opcode(require_NV_fp, UNPACK_OP, 5); }
|
||||||
UP4B{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4B, 4); }
|
UP4B{cc}{sat} { return_opcode(require_NV_fp, UNPACK_OP, 4); }
|
||||||
UP4UB{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4UB, 5); }
|
UP4UB{cc}{sat} { return_opcode(require_NV_fp, UNPACK_OP, 5); }
|
||||||
|
|
||||||
X2D{szf}{cc}{sat} { return_opcode(require_NV_fp, TRI_OP, X2D, 3); }
|
X2D{szf}{cc}{sat} { return_opcode(require_NV_fp, X2D_OP, 3); }
|
||||||
XPD{sat} { return_opcode( 1, BIN_OP, XPD, 3); }
|
XPD{sat} { return_opcode( true, XPD_OP, 3); }
|
||||||
|
|
||||||
vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
|
vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
|
||||||
fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
|
fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -36,12 +36,12 @@
|
|||||||
int
|
int
|
||||||
_mesa_parse_instruction_suffix(const struct asm_parser_state *state,
|
_mesa_parse_instruction_suffix(const struct asm_parser_state *state,
|
||||||
const char *suffix,
|
const char *suffix,
|
||||||
struct prog_instruction *inst)
|
struct asm_opcode *inst)
|
||||||
{
|
{
|
||||||
inst->CondUpdate = 0;
|
inst->cond_update = 0;
|
||||||
inst->CondDst = 0;
|
inst->cond_dst = 0;
|
||||||
inst->SaturateMode = SATURATE_OFF;
|
inst->saturate_mode = SATURATE_OFF;
|
||||||
inst->Precision = FLOAT32;
|
inst->precision = FLOAT32;
|
||||||
|
|
||||||
|
|
||||||
/* The first possible suffix element is the precision specifier from
|
/* 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) {
|
if (state->option.NV_fragment) {
|
||||||
switch (suffix[0]) {
|
switch (suffix[0]) {
|
||||||
case 'H':
|
case 'H':
|
||||||
inst->Precision = FLOAT16;
|
inst->precision = FLOAT16;
|
||||||
suffix++;
|
suffix++;
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
inst->Precision = FLOAT32;
|
inst->precision = FLOAT32;
|
||||||
suffix++;
|
suffix++;
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
inst->Precision = FIXED12;
|
inst->precision = FIXED12;
|
||||||
suffix++;
|
suffix++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -71,7 +71,7 @@ _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
|
|||||||
*/
|
*/
|
||||||
if (state->option.NV_fragment) {
|
if (state->option.NV_fragment) {
|
||||||
if (suffix[0] == 'C') {
|
if (suffix[0] == 'C') {
|
||||||
inst->CondUpdate = 1;
|
inst->cond_update = 1;
|
||||||
suffix++;
|
suffix++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
|
|||||||
*/
|
*/
|
||||||
if (state->mode == ARB_fragment) {
|
if (state->mode == ARB_fragment) {
|
||||||
if (strcmp(suffix, "_SAT") == 0) {
|
if (strcmp(suffix, "_SAT") == 0) {
|
||||||
inst->SaturateMode = SATURATE_ZERO_ONE;
|
inst->saturate_mode = SATURATE_ZERO_ONE;
|
||||||
suffix += 4;
|
suffix += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,10 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include "main/config.h"
|
#include "main/config.h"
|
||||||
|
#include "main/mtypes.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
struct gl_context;
|
struct gl_context;
|
||||||
|
|
||||||
@@ -45,7 +48,7 @@ struct asm_symbol {
|
|||||||
/**
|
/**
|
||||||
* One of PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, or PROGRAM_ENV_PARAM.
|
* 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
|
* 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 asm_instruction {
|
||||||
struct prog_instruction Base;
|
struct prog_instruction Base;
|
||||||
struct asm_instruction *next;
|
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 asm_parser_state {
|
||||||
struct gl_context *ctx;
|
struct gl_context *ctx;
|
||||||
struct gl_program *prog;
|
struct gl_program *prog;
|
||||||
|
struct exec_list ir;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Per-program target limits
|
* Per-program target limits
|
||||||
@@ -191,11 +255,7 @@ struct asm_parser_state {
|
|||||||
*/
|
*/
|
||||||
unsigned InputsBound;
|
unsigned InputsBound;
|
||||||
|
|
||||||
enum {
|
enum asm_program_target mode;
|
||||||
invalid_mode = 0,
|
|
||||||
ARB_vertex,
|
|
||||||
ARB_fragment
|
|
||||||
} mode;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
unsigned PositionInvariant:1;
|
unsigned PositionInvariant:1;
|
||||||
@@ -233,6 +293,9 @@ typedef struct YYLTYPE {
|
|||||||
#define YYLTYPE_IS_DECLARED 1
|
#define YYLTYPE_IS_DECLARED 1
|
||||||
#define YYLTYPE_IS_TRIVIAL 1
|
#define YYLTYPE_IS_TRIVIAL 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
extern GLboolean _mesa_parse_arb_program(struct gl_context *ctx, GLenum target,
|
extern GLboolean _mesa_parse_arb_program(struct gl_context *ctx, GLenum target,
|
||||||
const GLubyte *str, GLsizei len, struct asm_parser_state *state);
|
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.
|
* Non-zero on success, zero on failure.
|
||||||
*/
|
*/
|
||||||
extern int _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
|
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
|
* 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);
|
extern int _mesa_parse_cc(const char *s);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
@@ -240,11 +240,9 @@ STATETRACKER_SOURCES = \
|
|||||||
PROGRAM_SOURCES = \
|
PROGRAM_SOURCES = \
|
||||||
program/arbprogparse.c \
|
program/arbprogparse.c \
|
||||||
program/hash_table.c \
|
program/hash_table.c \
|
||||||
program/lex.yy.c \
|
|
||||||
program/nvfragparse.c \
|
program/nvfragparse.c \
|
||||||
program/nvvertparse.c \
|
program/nvvertparse.c \
|
||||||
program/program.c \
|
program/program.c \
|
||||||
program/program_parse.tab.c \
|
|
||||||
program/program_parse_extra.c \
|
program/program_parse_extra.c \
|
||||||
program/prog_cache.c \
|
program/prog_cache.c \
|
||||||
program/prog_execute.c \
|
program/prog_execute.c \
|
||||||
@@ -262,6 +260,8 @@ PROGRAM_SOURCES = \
|
|||||||
|
|
||||||
|
|
||||||
SHADER_CXX_SOURCES = \
|
SHADER_CXX_SOURCES = \
|
||||||
|
program/program_lexer.cpp \
|
||||||
|
program/program_parse.cpp \
|
||||||
program/ir_to_mesa.cpp \
|
program/ir_to_mesa.cpp \
|
||||||
program/sampler.cpp
|
program/sampler.cpp
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user