mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-06 01:40:26 +01:00
mesa: glsl: various writemask/swizzle improvements and clean-ups
This commit is contained in:
parent
7218626cf5
commit
72e57b52f0
5 changed files with 81 additions and 70 deletions
|
|
@ -348,7 +348,7 @@ _mesa_add_varying(struct gl_program_parameter_list *paramList,
|
|||
return i;
|
||||
}
|
||||
else {
|
||||
assert(size == 4);
|
||||
/*assert(size == 4);*/
|
||||
i = _mesa_add_parameter(paramList, PROGRAM_VARYING, name,
|
||||
size, GL_NONE, NULL, NULL);
|
||||
return i;
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ reg_string(enum register_file f, GLint index, gl_prog_print_mode mode,
|
|||
const char *
|
||||
_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
|
||||
{
|
||||
static const char swz[] = "xyzw01?!";
|
||||
static const char swz[] = "xyzw01!?"; /* See SWIZZLE_x definitions */
|
||||
static char s[20];
|
||||
GLuint i = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1409,6 +1409,27 @@ slang_find_asm_info(const char *name)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the default swizzle mask for accessing a variable of the
|
||||
* given size (in floats). If size = 1, comp is used to identify
|
||||
* which component [0..3] of the register holds the variable.
|
||||
*/
|
||||
static GLuint
|
||||
_slang_var_swizzle(GLint size, GLint comp)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
return MAKE_SWIZZLE4(comp, comp, comp, comp);
|
||||
case 2:
|
||||
return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_NIL, SWIZZLE_NIL);
|
||||
case 3:
|
||||
return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_NIL);
|
||||
default:
|
||||
return SWIZZLE_XYZW;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Some write-masked assignments are simple, but others are hard.
|
||||
* Simple example:
|
||||
|
|
@ -3063,6 +3084,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
|||
int dbg = 0;
|
||||
const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
|
||||
const GLint texIndex = sampler_to_texture_index(var->type.specifier.type);
|
||||
const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
|
||||
|
||||
if (texIndex != -1) {
|
||||
/* This is a texture sampler variable...
|
||||
|
|
@ -3076,8 +3098,8 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
|||
}
|
||||
else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
|
||||
/* Uniform variable */
|
||||
const GLint size = _slang_sizeof_type_specifier(&var->type.specifier)
|
||||
* MAX2(var->array_len, 1);
|
||||
const GLint totalSize = size * MAX2(var->array_len, 1);
|
||||
const GLuint swizzle = _slang_var_swizzle(totalSize, 0);
|
||||
if (prog) {
|
||||
/* user-defined uniform */
|
||||
if (datatype == GL_NONE) {
|
||||
|
|
@ -3106,8 +3128,10 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
|||
}
|
||||
else {
|
||||
GLint uniformLoc = _mesa_add_uniform(prog->Parameters, varName,
|
||||
size, datatype);
|
||||
store = _slang_new_ir_storage(PROGRAM_UNIFORM, uniformLoc, size);
|
||||
totalSize, datatype);
|
||||
store = _slang_new_ir_storage_swz(PROGRAM_UNIFORM, uniformLoc,
|
||||
totalSize, swizzle);
|
||||
printf("GLOBAL USER UNIFORM %s size %d\n", varName, totalSize);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -3115,33 +3139,40 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
|||
/* We know it's a uniform, but don't allocate storage unless
|
||||
* it's really used.
|
||||
*/
|
||||
store = _slang_new_ir_storage(PROGRAM_STATE_VAR, -1, size);
|
||||
store = _slang_new_ir_storage_swz(PROGRAM_STATE_VAR, -1,
|
||||
totalSize, swizzle);
|
||||
}
|
||||
if (dbg) printf("UNIFORM (sz %d) ", size);
|
||||
if (dbg) printf("UNIFORM (sz %d) ", totalSize);
|
||||
}
|
||||
else if (var->type.qualifier == SLANG_QUAL_VARYING) {
|
||||
const GLint size = 4; /* XXX fix */
|
||||
if (prog) {
|
||||
/* user-defined varying */
|
||||
GLint varyingLoc = _mesa_add_varying(prog->Varying, varName, size);
|
||||
store = _slang_new_ir_storage(PROGRAM_VARYING, varyingLoc, size);
|
||||
GLuint swizzle = _slang_var_swizzle(size, 0);
|
||||
store = _slang_new_ir_storage_swz(PROGRAM_VARYING, varyingLoc,
|
||||
size, swizzle);
|
||||
}
|
||||
else {
|
||||
/* pre-defined varying, like gl_Color or gl_TexCoord */
|
||||
if (type == SLANG_UNIT_FRAGMENT_BUILTIN) {
|
||||
/* fragment program input */
|
||||
GLuint swizzle;
|
||||
GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB,
|
||||
&swizzle);
|
||||
assert(index >= 0);
|
||||
store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle);
|
||||
assert(index < FRAG_ATTRIB_MAX);
|
||||
store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index,
|
||||
size, swizzle);
|
||||
}
|
||||
else {
|
||||
/* vertex program output */
|
||||
GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
|
||||
GLuint swizzle = _slang_var_swizzle(size, 0);
|
||||
assert(index >= 0);
|
||||
assert(type == SLANG_UNIT_VERTEX_BUILTIN);
|
||||
store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
|
||||
assert(index < VERT_RESULT_MAX);
|
||||
assert(type == SLANG_UNIT_VERTEX_BUILTIN);
|
||||
store = _slang_new_ir_storage_swz(PROGRAM_OUTPUT, index,
|
||||
size, swizzle);
|
||||
}
|
||||
if (dbg) printf("V/F ");
|
||||
}
|
||||
|
|
@ -3150,7 +3181,6 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
|||
else if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE) {
|
||||
if (prog) {
|
||||
/* user-defined vertex attribute */
|
||||
const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
|
||||
const GLint attr = -1; /* unknown */
|
||||
GLint index = _mesa_add_attribute(prog->Attributes, varName,
|
||||
size, attr);
|
||||
|
|
@ -3163,7 +3193,6 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
|||
GLuint swizzle;
|
||||
GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB,
|
||||
&swizzle);
|
||||
GLint size = 4; /* XXX? */
|
||||
assert(index >= 0);
|
||||
store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle);
|
||||
}
|
||||
|
|
@ -3173,27 +3202,24 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
|||
GLuint swizzle = SWIZZLE_XYZW; /* silence compiler warning */
|
||||
GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB,
|
||||
&swizzle);
|
||||
GLint size = 4; /* XXX? */
|
||||
store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle);
|
||||
if (dbg) printf("INPUT ");
|
||||
}
|
||||
else if (var->type.qualifier == SLANG_QUAL_FIXEDOUTPUT) {
|
||||
if (type == SLANG_UNIT_VERTEX_BUILTIN) {
|
||||
GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
|
||||
GLint size = 4; /* XXX? */
|
||||
store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
|
||||
}
|
||||
else {
|
||||
GLint index = _slang_output_index(varName, GL_FRAGMENT_PROGRAM_ARB);
|
||||
GLint size = 4; /* XXX? */
|
||||
GLint specialSize = 4; /* treat all fragment outputs as float[4] */
|
||||
assert(type == SLANG_UNIT_FRAGMENT_BUILTIN);
|
||||
store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
|
||||
store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, specialSize);
|
||||
}
|
||||
if (dbg) printf("OUTPUT ");
|
||||
}
|
||||
else if (var->type.qualifier == SLANG_QUAL_CONST && !prog) {
|
||||
/* pre-defined global constant, like gl_MaxLights */
|
||||
const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
|
||||
store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
|
||||
if (dbg) printf("CONST ");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,21 +171,33 @@ free_temp_storage(slang_var_table *vt, slang_ir_node *n)
|
|||
|
||||
|
||||
/**
|
||||
* Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term).
|
||||
* Ex: fix_swizzle("zyNN") -> "zyyy"
|
||||
* XXX should put in the default component for the position...
|
||||
* Remove any SWIZZLE_NIL terms from given swizzle mask.
|
||||
* For a swizzle like .z??? generate .zzzz (replicate single component).
|
||||
* Else, for .wx?? generate .wxzw (insert default component for the position).
|
||||
*/
|
||||
static GLuint
|
||||
fix_swizzle(GLuint swizzle)
|
||||
{
|
||||
GLuint swz[4], i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
swz[i] = GET_SWZ(swizzle, i);
|
||||
if (swz[i] == SWIZZLE_NIL) {
|
||||
swz[i] = swz[i - 1];
|
||||
}
|
||||
GLuint c0 = GET_SWZ(swizzle, 0),
|
||||
c1 = GET_SWZ(swizzle, 1),
|
||||
c2 = GET_SWZ(swizzle, 2),
|
||||
c3 = GET_SWZ(swizzle, 3);
|
||||
if (c1 == SWIZZLE_NIL && c2 == SWIZZLE_NIL && c3 == SWIZZLE_NIL) {
|
||||
/* smear first component across all positions */
|
||||
c1 = c2 = c3 = c0;
|
||||
}
|
||||
return MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
|
||||
else {
|
||||
/* insert default swizzle components */
|
||||
if (c0 == SWIZZLE_NIL)
|
||||
c0 = SWIZZLE_X;
|
||||
if (c1 == SWIZZLE_NIL)
|
||||
c1 = SWIZZLE_Y;
|
||||
if (c2 == SWIZZLE_NIL)
|
||||
c2 = SWIZZLE_Z;
|
||||
if (c3 == SWIZZLE_NIL)
|
||||
c3 = SWIZZLE_W;
|
||||
}
|
||||
return MAKE_SWIZZLE4(c0, c1, c2, c3);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -216,6 +228,7 @@ storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st,
|
|||
|
||||
assert(size >= 1);
|
||||
assert(size <= 4);
|
||||
|
||||
if (size == 1) {
|
||||
GLuint comp = GET_SWZ(swizzle, 0);
|
||||
assert(comp < 4);
|
||||
|
|
@ -233,13 +246,6 @@ storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st,
|
|||
static void
|
||||
storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
|
||||
{
|
||||
static const GLuint defaultSwizzle[4] = {
|
||||
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
|
||||
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
|
||||
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
|
||||
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
|
||||
};
|
||||
const GLint size = st->Size;
|
||||
const GLboolean relAddr = st->RelAddr;
|
||||
GLint index = st->Index;
|
||||
GLuint swizzle = st->Swizzle;
|
||||
|
|
@ -250,7 +256,6 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
|
|||
index += st->Index;
|
||||
swizzle = _slang_swizzle_swizzle(st->Swizzle, swizzle);
|
||||
}
|
||||
swizzle = fix_swizzle(swizzle);
|
||||
|
||||
assert(st->File >= 0);
|
||||
assert(st->File < PROGRAM_UNDEFINED);
|
||||
|
|
@ -259,20 +264,14 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
|
|||
assert(index >= 0);
|
||||
src->Index = index;
|
||||
|
||||
assert(size >= 1);
|
||||
assert(size <= 4);
|
||||
swizzle = fix_swizzle(swizzle);
|
||||
assert(GET_SWZ(swizzle, 0) <= SWIZZLE_W);
|
||||
assert(GET_SWZ(swizzle, 1) <= SWIZZLE_W);
|
||||
assert(GET_SWZ(swizzle, 2) <= SWIZZLE_W);
|
||||
assert(GET_SWZ(swizzle, 3) <= SWIZZLE_W);
|
||||
src->Swizzle = swizzle;
|
||||
|
||||
src->RelAddr = relAddr;
|
||||
|
||||
if (swizzle != SWIZZLE_NOOP)
|
||||
src->Swizzle = swizzle;
|
||||
else
|
||||
src->Swizzle = defaultSwizzle[size - 1]; /*XXX really need this?*/
|
||||
|
||||
assert(GET_SWZ(src->Swizzle, 0) <= 3);
|
||||
assert(GET_SWZ(src->Swizzle, 1) <= 3);
|
||||
assert(GET_SWZ(src->Swizzle, 2) <= 3);
|
||||
assert(GET_SWZ(src->Swizzle, 3) <= 3);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -582,8 +581,7 @@ emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
|
|||
|
||||
/* result storage */
|
||||
if (!n->Store) {
|
||||
GLint size = n->Children[0]->Store
|
||||
? n->Children[0]->Store->Size : info->ResultSize;
|
||||
GLint size = info->ResultSize;
|
||||
if (!alloc_temp_storage(emitInfo, n, size))
|
||||
return NULL;
|
||||
#if 0000 /* this should work, but doesn't yet */
|
||||
|
|
@ -591,6 +589,8 @@ emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
|
|||
n->Writemask = WRITEMASK_XY;
|
||||
else if (size == 3)
|
||||
n->Writemask = WRITEMASK_XYZ;
|
||||
else if (size == 1)
|
||||
n->Writemask = WRITEMASK_X << GET_SWZ(n->Store->Swizzle,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -1045,10 +1045,9 @@ emit_move(slang_emit_info *emitInfo, slang_ir_node *n)
|
|||
assert(n->Children[0]->Store->Index >= 0);
|
||||
|
||||
/* use tighter writemask when possible */
|
||||
#if 0000 /* XXX enable this after more testing... */
|
||||
if (n->Writemask == WRITEMASK_XYZW)
|
||||
n->Writemask = inst->DstReg.WriteMask;
|
||||
#endif
|
||||
|
||||
storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
|
||||
return inst;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,20 +239,6 @@ _slang_free_ir_tree(slang_ir_node *n)
|
|||
|
||||
|
||||
|
||||
static const char *
|
||||
swizzle_string(GLuint swizzle)
|
||||
{
|
||||
static char s[6];
|
||||
GLuint i;
|
||||
s[0] = '.';
|
||||
for (i = 1; i < 5; i++) {
|
||||
s[i] = "xyzw"[GET_SWZ(swizzle, i-1)];
|
||||
}
|
||||
s[i] = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
writemask_string(GLuint writemask)
|
||||
{
|
||||
|
|
@ -410,7 +396,7 @@ _slang_print_ir_tree(const slang_ir_node *n, int indent)
|
|||
case IR_VAR:
|
||||
printf("VAR %s%s at %s store %p\n",
|
||||
(n->Var ? (char *) n->Var->a_name : "TEMP"),
|
||||
swizzle_string(n->Store->Swizzle),
|
||||
_mesa_swizzle_string(n->Store->Swizzle, 0, 0),
|
||||
storage_string(n->Store), (void*) n->Store);
|
||||
break;
|
||||
case IR_VAR_DECL:
|
||||
|
|
@ -437,7 +423,7 @@ _slang_print_ir_tree(const slang_ir_node *n, int indent)
|
|||
break;
|
||||
case IR_SWIZZLE:
|
||||
printf("SWIZZLE %s of (store %p) \n",
|
||||
swizzle_string(n->Store->Swizzle), (void*) n->Store);
|
||||
_mesa_swizzle_string(n->Store->Swizzle, 0, 0), (void*) n->Store);
|
||||
_slang_print_ir_tree(n->Children[0], indent + 3);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue