mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 02:58:05 +02:00
nouveau: reindent shader pass0/pass2
if this gets rejected by the commit list, just ignore it.. nothing interesting to see here :)
This commit is contained in:
parent
c3ac270996
commit
50227f6fd2
2 changed files with 530 additions and 488 deletions
|
|
@ -188,7 +188,8 @@ pass0_create_subroutine(nouveauShader *nvs, const char *label)
|
|||
if (!nvs->program_tree)
|
||||
nvs->program_tree = &sub->header;
|
||||
else
|
||||
pass0_append_fragment(nvs->program_tree, &sub->header, 0);
|
||||
pass0_append_fragment(nvs->program_tree,
|
||||
&sub->header, 0);
|
||||
}
|
||||
|
||||
return sub;
|
||||
|
|
@ -196,162 +197,168 @@ pass0_create_subroutine(nouveauShader *nvs, const char *label)
|
|||
|
||||
static void
|
||||
pass0_make_reg(nouveauShader *nvs, nvsRegister *reg,
|
||||
nvsRegFile file, unsigned int index)
|
||||
nvsRegFile file, unsigned int index)
|
||||
{
|
||||
struct pass0_rec *rec = nvs->pass_rec;
|
||||
struct pass0_rec *rec = nvs->pass_rec;
|
||||
|
||||
/* defaults */
|
||||
*reg = nvr_unused;
|
||||
/* -1 == quick-and-dirty temp alloc */
|
||||
if (file == NVS_FILE_TEMP && index == -1) {
|
||||
index = rec->next_temp++;
|
||||
assert(index < NVS_MAX_TEMPS);
|
||||
}
|
||||
reg->file = file;
|
||||
reg->index = index;
|
||||
/* defaults */
|
||||
*reg = nvr_unused;
|
||||
/* -1 == quick-and-dirty temp alloc */
|
||||
if (file == NVS_FILE_TEMP && index == -1) {
|
||||
index = rec->next_temp++;
|
||||
assert(index < NVS_MAX_TEMPS);
|
||||
}
|
||||
reg->file = file;
|
||||
reg->index = index;
|
||||
}
|
||||
|
||||
static void
|
||||
pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i=0;i<4;i++)
|
||||
swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)];
|
||||
for (i=0;i<4;i++)
|
||||
swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)];
|
||||
}
|
||||
|
||||
static nvsOpcode
|
||||
pass0_make_opcode(enum prog_opcode op)
|
||||
{
|
||||
if (op > MAX_OPCODE)
|
||||
return NVS_OP_UNKNOWN;
|
||||
return _tx_mesa_opcode[op];
|
||||
if (op > MAX_OPCODE)
|
||||
return NVS_OP_UNKNOWN;
|
||||
return _tx_mesa_opcode[op];
|
||||
}
|
||||
|
||||
static nvsCond
|
||||
pass0_make_condmask(GLuint mesa)
|
||||
{
|
||||
if (mesa > COND_FL)
|
||||
return NVS_COND_UNKNOWN;
|
||||
return _tx_mesa_condmask[mesa];
|
||||
if (mesa > COND_FL)
|
||||
return NVS_COND_UNKNOWN;
|
||||
return _tx_mesa_condmask[mesa];
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
pass0_make_mask(GLuint mesa_mask)
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
unsigned int mask = 0;
|
||||
|
||||
if (mesa_mask & WRITEMASK_X) mask |= SMASK_X;
|
||||
if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y;
|
||||
if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z;
|
||||
if (mesa_mask & WRITEMASK_W) mask |= SMASK_W;
|
||||
if (mesa_mask & WRITEMASK_X) mask |= SMASK_X;
|
||||
if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y;
|
||||
if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z;
|
||||
if (mesa_mask & WRITEMASK_W) mask |= SMASK_W;
|
||||
|
||||
return mask;
|
||||
return mask;
|
||||
}
|
||||
|
||||
static nvsTexTarget
|
||||
pass0_make_tex_target(GLuint mesa)
|
||||
{
|
||||
switch (mesa) {
|
||||
case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D;
|
||||
case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D;
|
||||
case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D;
|
||||
case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE;
|
||||
case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT;
|
||||
default:
|
||||
return NVS_TEX_TARGET_UNKNOWN;
|
||||
}
|
||||
switch (mesa) {
|
||||
case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D;
|
||||
case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D;
|
||||
case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D;
|
||||
case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE;
|
||||
case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT;
|
||||
default:
|
||||
return NVS_TEX_TARGET_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg,
|
||||
struct prog_dst_register *dst)
|
||||
{
|
||||
struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp;
|
||||
nvsFixedReg sfr;
|
||||
struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp;
|
||||
nvsFixedReg sfr;
|
||||
|
||||
switch (dst->File) {
|
||||
case PROGRAM_OUTPUT:
|
||||
if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
|
||||
sfr = (dst->Index < VERT_RESULT_MAX) ?
|
||||
_tx_mesa_vp_dst_reg[dst->Index] : NVS_FR_UNKNOWN;
|
||||
} else {
|
||||
sfr = (dst->Index < FRAG_RESULT_MAX) ?
|
||||
_tx_mesa_fp_dst_reg[dst->Index] : NVS_FR_UNKNOWN;
|
||||
}
|
||||
pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr);
|
||||
break;
|
||||
case PROGRAM_TEMPORARY:
|
||||
pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index);
|
||||
break;
|
||||
case PROGRAM_ADDRESS:
|
||||
pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown dest file %d\n", dst->File);
|
||||
assert(0);
|
||||
}
|
||||
switch (dst->File) {
|
||||
case PROGRAM_OUTPUT:
|
||||
if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
|
||||
sfr = (dst->Index < VERT_RESULT_MAX) ?
|
||||
_tx_mesa_vp_dst_reg[dst->Index] :
|
||||
NVS_FR_UNKNOWN;
|
||||
} else {
|
||||
sfr = (dst->Index < FRAG_RESULT_MAX) ?
|
||||
_tx_mesa_fp_dst_reg[dst->Index] :
|
||||
NVS_FR_UNKNOWN;
|
||||
}
|
||||
pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr);
|
||||
break;
|
||||
case PROGRAM_TEMPORARY:
|
||||
pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index);
|
||||
break;
|
||||
case PROGRAM_ADDRESS:
|
||||
pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown dest file %d\n", dst->File);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src)
|
||||
{
|
||||
struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base;
|
||||
struct gl_program_parameter_list *p = mesa->Parameters;
|
||||
struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base;
|
||||
struct gl_program_parameter_list *p = mesa->Parameters;
|
||||
|
||||
*reg = nvr_unused;
|
||||
*reg = nvr_unused;
|
||||
|
||||
switch (src->File) {
|
||||
case PROGRAM_INPUT:
|
||||
reg->file = NVS_FILE_ATTRIB;
|
||||
if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
|
||||
reg->index = (src->Index < VERT_ATTRIB_MAX) ?
|
||||
_tx_mesa_vp_src_reg[src->Index] : NVS_FR_UNKNOWN;
|
||||
} else {
|
||||
reg->index = (src->Index < FRAG_ATTRIB_MAX) ?
|
||||
_tx_mesa_fp_src_reg[src->Index] : NVS_FR_UNKNOWN;
|
||||
}
|
||||
break;
|
||||
/* All const types seem to get shoved into here, not really sure why */
|
||||
case PROGRAM_STATE_VAR:
|
||||
switch (p->Parameters[src->Index].Type) {
|
||||
case PROGRAM_NAMED_PARAM:
|
||||
case PROGRAM_CONSTANT:
|
||||
nvs->params[src->Index].source_val = NULL;
|
||||
COPY_4V(nvs->params[src->Index].val, p->ParameterValues[src->Index]);
|
||||
break;
|
||||
case PROGRAM_STATE_VAR:
|
||||
nvs->params[src->Index].source_val = p->ParameterValues[src->Index];
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown parameter type %d\n",
|
||||
p->Parameters[src->Index].Type);
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
switch (src->File) {
|
||||
case PROGRAM_INPUT:
|
||||
reg->file = NVS_FILE_ATTRIB;
|
||||
if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
|
||||
reg->index = (src->Index < VERT_ATTRIB_MAX) ?
|
||||
_tx_mesa_vp_src_reg[src->Index] :
|
||||
NVS_FR_UNKNOWN;
|
||||
} else {
|
||||
reg->index = (src->Index < FRAG_ATTRIB_MAX) ?
|
||||
_tx_mesa_fp_src_reg[src->Index] :
|
||||
NVS_FR_UNKNOWN;
|
||||
}
|
||||
break;
|
||||
/* All const types seem to get shoved into here, not really sure why */
|
||||
case PROGRAM_STATE_VAR:
|
||||
switch (p->Parameters[src->Index].Type) {
|
||||
case PROGRAM_NAMED_PARAM:
|
||||
case PROGRAM_CONSTANT:
|
||||
nvs->params[src->Index].source_val = NULL;
|
||||
COPY_4V(nvs->params[src->Index].val,
|
||||
p->ParameterValues[src->Index]);
|
||||
break;
|
||||
case PROGRAM_STATE_VAR:
|
||||
nvs->params[src->Index].source_val =
|
||||
p->ParameterValues[src->Index];
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown parameter type %d\n",
|
||||
p->Parameters[src->Index].Type);
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (src->RelAddr) {
|
||||
reg->indexed = 1;
|
||||
reg->addr_reg = 0;
|
||||
reg->addr_comp = NVS_SWZ_X;
|
||||
} else
|
||||
reg->indexed = 0;
|
||||
reg->file = NVS_FILE_CONST;
|
||||
reg->index = src->Index;
|
||||
break;
|
||||
case PROGRAM_TEMPORARY:
|
||||
reg->file = NVS_FILE_TEMP;
|
||||
reg->index = src->Index;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown source type %d\n", src->File);
|
||||
assert(0);
|
||||
}
|
||||
if (src->RelAddr) {
|
||||
reg->indexed = 1;
|
||||
reg->addr_reg = 0;
|
||||
reg->addr_comp = NVS_SWZ_X;
|
||||
} else
|
||||
reg->indexed = 0;
|
||||
reg->file = NVS_FILE_CONST;
|
||||
reg->index = src->Index;
|
||||
break;
|
||||
case PROGRAM_TEMPORARY:
|
||||
reg->file = NVS_FILE_TEMP;
|
||||
reg->index = src->Index;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown source type %d\n", src->File);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* per-component negate handled elsewhere */
|
||||
reg->negate = src->NegateBase != 0;
|
||||
reg->abs = src->Abs;
|
||||
pass0_make_swizzle(reg->swizzle, src->Swizzle);
|
||||
/* per-component negate handled elsewhere */
|
||||
reg->negate = src->NegateBase != 0;
|
||||
reg->abs = src->Abs;
|
||||
pass0_make_swizzle(reg->swizzle, src->Swizzle);
|
||||
}
|
||||
|
||||
static nvsInstruction *
|
||||
|
|
@ -389,59 +396,66 @@ pass0_emit(nouveauShader *nvs, nvsFragmentHeader *parent, int fpos,
|
|||
|
||||
static void
|
||||
pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos,
|
||||
struct prog_src_register *src,
|
||||
struct prog_src_register *src,
|
||||
unsigned int sm1,
|
||||
unsigned int sm2)
|
||||
{
|
||||
static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 };
|
||||
struct pass0_rec *rec = nvs->pass_rec;
|
||||
int fixup_1, fixup_2;
|
||||
nvsRegister sr, dr = nvr_unused;
|
||||
nvsRegister sm1const, sm2const;
|
||||
static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 };
|
||||
struct pass0_rec *rec = nvs->pass_rec;
|
||||
int fixup_1, fixup_2;
|
||||
nvsRegister sr, dr = nvr_unused;
|
||||
nvsRegister sm1const, sm2const;
|
||||
|
||||
if (!rec->swzconst_done) {
|
||||
struct gl_program *prog = &nvs->mesa.vp.Base;
|
||||
rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, sc, 4);
|
||||
rec->swzconst_done = 1;
|
||||
COPY_4V(nvs->params[rec->swzconst_id].val, sc);
|
||||
}
|
||||
if (!rec->swzconst_done) {
|
||||
struct gl_program *prog = &nvs->mesa.vp.Base;
|
||||
rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters,
|
||||
sc, 4);
|
||||
rec->swzconst_done = 1;
|
||||
COPY_4V(nvs->params[rec->swzconst_id].val, sc);
|
||||
}
|
||||
|
||||
fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && sm2 != MAKE_SWIZZLE4(2,2,2,2));
|
||||
fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2));
|
||||
fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) &&
|
||||
sm2 != MAKE_SWIZZLE4(2,2,2,2));
|
||||
fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2));
|
||||
|
||||
if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) {
|
||||
/* We can't use more than one const in an instruction, so move the const
|
||||
* into a temp, and swizzle from there.
|
||||
*TODO: should just emit the swizzled const, instead of swizzling it
|
||||
* in the shader.. would need to reswizzle any state params when they
|
||||
* change however..
|
||||
*/
|
||||
pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
|
||||
pass0_make_src_reg(nvs, &sr, src);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused);
|
||||
pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index);
|
||||
} else {
|
||||
if (fixup_1)
|
||||
src->NegateBase = 0;
|
||||
pass0_make_src_reg(nvs, &sr, src);
|
||||
pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
|
||||
}
|
||||
if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) {
|
||||
/* We can't use more than one const in an instruction,
|
||||
* so move the const into a temp, and swizzle from there.
|
||||
*
|
||||
* TODO: should just emit the swizzled const, instead of
|
||||
* swizzling it in the shader.. would need to reswizzle
|
||||
* any state params when they change however..
|
||||
*/
|
||||
pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
|
||||
pass0_make_src_reg(nvs, &sr, src);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MOV,
|
||||
dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused);
|
||||
pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index);
|
||||
} else {
|
||||
if (fixup_1)
|
||||
src->NegateBase = 0;
|
||||
pass0_make_src_reg(nvs, &sr, src);
|
||||
pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
|
||||
}
|
||||
|
||||
pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id);
|
||||
pass0_make_swizzle(sm1const.swizzle, sm1);
|
||||
if (fixup_1 && fixup_2) {
|
||||
/* Any combination with SWIZZLE_ONE */
|
||||
pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id);
|
||||
pass0_make_swizzle(sm2const.swizzle, sm2);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const);
|
||||
} else {
|
||||
/* SWIZZLE_ZERO || arbitrary negate */
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused);
|
||||
}
|
||||
pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id);
|
||||
pass0_make_swizzle(sm1const.swizzle, sm1);
|
||||
if (fixup_1 && fixup_2) {
|
||||
/* Any combination with SWIZZLE_ONE */
|
||||
pass0_make_reg(nvs, &sm2const,
|
||||
NVS_FILE_CONST, rec->swzconst_id);
|
||||
pass0_make_swizzle(sm2const.swizzle, sm2);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MAD,
|
||||
dr, SMASK_ALL, 0, sr, sm1const, sm2const);
|
||||
} else {
|
||||
/* SWIZZLE_ZERO || arbitrary negate */
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MUL,
|
||||
dr, SMASK_ALL, 0, sr, sm1const, nvr_unused);
|
||||
}
|
||||
|
||||
src->File = PROGRAM_TEMPORARY;
|
||||
src->Index = dr.index;
|
||||
src->Swizzle = SWIZZLE_NOOP;
|
||||
src->File = PROGRAM_TEMPORARY;
|
||||
src->Index = dr.index;
|
||||
src->Swizzle = SWIZZLE_NOOP;
|
||||
}
|
||||
|
||||
#define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3))
|
||||
|
|
@ -449,81 +463,86 @@ static void
|
|||
pass0_check_sources(nvsPtr nvs, nvsFragmentHeader *parent, int fpos,
|
||||
struct prog_instruction *inst)
|
||||
{
|
||||
unsigned int insrc = -1, constsrc = -1;
|
||||
int i;
|
||||
unsigned int insrc = -1, constsrc = -1;
|
||||
int i;
|
||||
|
||||
for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) {
|
||||
struct prog_src_register *src = &inst->SrcReg[i];
|
||||
unsigned int sm_1 = 0, sm_2 = 0;
|
||||
nvsRegister sr, dr;
|
||||
int do_mov = 0, c;
|
||||
for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) {
|
||||
struct prog_src_register *src = &inst->SrcReg[i];
|
||||
unsigned int sm_1 = 0, sm_2 = 0;
|
||||
nvsRegister sr, dr;
|
||||
int do_mov = 0, c;
|
||||
|
||||
/* Build up swizzle masks as if we were going to use
|
||||
* "MAD new, src, const1, const2" to support arbitrary negation
|
||||
* and SWIZZLE_ZERO/SWIZZLE_ONE.
|
||||
*/
|
||||
for (c=0;c<4;c++) {
|
||||
if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) {
|
||||
SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */
|
||||
SET_SWZ(sm_2, c, SWIZZLE_Y);
|
||||
SET_SWZ(src->Swizzle, c, SWIZZLE_X);
|
||||
} else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) {
|
||||
SET_SWZ(sm_1, c, SWIZZLE_Y);
|
||||
if (src->NegateBase & (1<<c))
|
||||
SET_SWZ(sm_2, c, SWIZZLE_Z); /* -1.0 */
|
||||
else
|
||||
SET_SWZ(sm_2, c, SWIZZLE_X); /* 1.0 */
|
||||
SET_SWZ(src->Swizzle, c, SWIZZLE_X);
|
||||
} else {
|
||||
if (src->NegateBase & (1<<c))
|
||||
SET_SWZ(sm_1, c, SWIZZLE_Z); /* -[xyzw] */
|
||||
else
|
||||
SET_SWZ(sm_1, c, SWIZZLE_X); /* [xyzw] */
|
||||
SET_SWZ(sm_2, c, SWIZZLE_Y);
|
||||
}
|
||||
}
|
||||
/* Unless we're multiplying by 1.0 or -1.0 on all components, and we're
|
||||
* adding nothing to any component we have to emulate the swizzle.
|
||||
*/
|
||||
if ((sm_1 != MAKE_SWIZZLE4(0,0,0,0) && sm_1 != MAKE_SWIZZLE4(2,2,2,2)) ||
|
||||
sm_2 != MAKE_SWIZZLE4(1,1,1,1)) {
|
||||
pass0_fixup_swizzle(nvs, parent, fpos, src, sm_1, sm_2);
|
||||
/* The source is definitely in a temp now, so don't bother checking
|
||||
* for multiple ATTRIB/CONST regs.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
/* Build up swizzle masks as if we were going to use
|
||||
* "MAD new, src, const1, const2" to support arbitrary negation
|
||||
* and SWIZZLE_ZERO/SWIZZLE_ONE.
|
||||
*/
|
||||
for (c=0;c<4;c++) {
|
||||
if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) {
|
||||
SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */
|
||||
SET_SWZ(sm_2, c, SWIZZLE_Y);
|
||||
SET_SWZ(src->Swizzle, c, SWIZZLE_X);
|
||||
} else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) {
|
||||
SET_SWZ(sm_1, c, SWIZZLE_Y);
|
||||
if (src->NegateBase & (1<<c))
|
||||
SET_SWZ(sm_2, c, SWIZZLE_Z); /* -1.0 */
|
||||
else
|
||||
SET_SWZ(sm_2, c, SWIZZLE_X); /* 1.0 */
|
||||
SET_SWZ(src->Swizzle, c, SWIZZLE_X);
|
||||
} else {
|
||||
if (src->NegateBase & (1<<c))
|
||||
SET_SWZ(sm_1, c, SWIZZLE_Z); /* -[xyzw] */
|
||||
else
|
||||
SET_SWZ(sm_1, c, SWIZZLE_X); /*[xyzw]*/
|
||||
SET_SWZ(sm_2, c, SWIZZLE_Y);
|
||||
}
|
||||
}
|
||||
|
||||
/* HW can't use more than one ATTRIB or PARAM in a single instruction */
|
||||
switch (src->File) {
|
||||
case PROGRAM_INPUT:
|
||||
if (insrc != -1 && insrc != src->Index)
|
||||
do_mov = 1;
|
||||
else insrc = src->Index;
|
||||
break;
|
||||
case PROGRAM_STATE_VAR:
|
||||
if (constsrc != -1 && constsrc != src->Index)
|
||||
do_mov = 1;
|
||||
else constsrc = src->Index;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Unless we're multiplying by 1.0 or -1.0 on all components,
|
||||
* and we're adding nothing to any component we have to
|
||||
* emulate the swizzle.
|
||||
*/
|
||||
if ((sm_1 != MAKE_SWIZZLE4(0,0,0,0) &&
|
||||
sm_1 != MAKE_SWIZZLE4(2,2,2,2)) ||
|
||||
sm_2 != MAKE_SWIZZLE4(1,1,1,1)) {
|
||||
pass0_fixup_swizzle(nvs, parent, fpos, src, sm_1, sm_2);
|
||||
/* The source is definitely in a temp now, so don't
|
||||
* bother checking for multiple ATTRIB/CONST regs.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa instruction
|
||||
* to point at the temp.
|
||||
*/
|
||||
if (do_mov) {
|
||||
pass0_make_src_reg(nvs, &sr, src);
|
||||
pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0,
|
||||
sr, nvr_unused, nvr_unused);
|
||||
/* HW can't use more than one ATTRIB or PARAM in a single
|
||||
* instruction */
|
||||
switch (src->File) {
|
||||
case PROGRAM_INPUT:
|
||||
if (insrc != -1 && insrc != src->Index)
|
||||
do_mov = 1;
|
||||
else insrc = src->Index;
|
||||
break;
|
||||
case PROGRAM_STATE_VAR:
|
||||
if (constsrc != -1 && constsrc != src->Index)
|
||||
do_mov = 1;
|
||||
else constsrc = src->Index;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
src->File = PROGRAM_TEMPORARY;
|
||||
src->Index = dr.index;
|
||||
src->Swizzle= SWIZZLE_NOOP;
|
||||
}
|
||||
}
|
||||
/* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa
|
||||
* instruction to point at the temp.
|
||||
*/
|
||||
if (do_mov) {
|
||||
pass0_make_src_reg(nvs, &sr, src);
|
||||
pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MOV,
|
||||
dr, SMASK_ALL, 0,
|
||||
sr, nvr_unused, nvr_unused);
|
||||
|
||||
src->File = PROGRAM_TEMPORARY;
|
||||
src->Index = dr.index;
|
||||
src->Swizzle= SWIZZLE_NOOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
|
|
@ -531,138 +550,150 @@ pass0_emulate_instruction(nouveauShader *nvs,
|
|||
nvsFragmentHeader *parent, int fpos,
|
||||
struct prog_instruction *inst)
|
||||
{
|
||||
nvsFunc *shader = nvs->func;
|
||||
nvsRegister src[3], dest, temp;
|
||||
nvsInstruction *nvsinst;
|
||||
struct pass0_rec *rec = nvs->pass_rec;
|
||||
unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask);
|
||||
int i, sat;
|
||||
nvsFunc *shader = nvs->func;
|
||||
nvsRegister src[3], dest, temp;
|
||||
nvsInstruction *nvsinst;
|
||||
struct pass0_rec *rec = nvs->pass_rec;
|
||||
unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask);
|
||||
int i, sat;
|
||||
|
||||
sat = (inst->SaturateMode == SATURATE_ZERO_ONE);
|
||||
sat = (inst->SaturateMode == SATURATE_ZERO_ONE);
|
||||
|
||||
/* Build all the "real" regs for the instruction */
|
||||
for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++)
|
||||
pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]);
|
||||
if (inst->Opcode != OPCODE_KIL)
|
||||
pass0_make_dst_reg(nvs, &dest, &inst->DstReg);
|
||||
/* Build all the "real" regs for the instruction */
|
||||
for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++)
|
||||
pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]);
|
||||
if (inst->Opcode != OPCODE_KIL)
|
||||
pass0_make_dst_reg(nvs, &dest, &inst->DstReg);
|
||||
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_ABS:
|
||||
if (shader->caps & SCAP_SRC_ABS)
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dest, mask, sat,
|
||||
nvsAbs(src[0]), nvr_unused, nvr_unused);
|
||||
else
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MAX, dest, mask, sat,
|
||||
src[0], nvsNegate(src[0]), nvr_unused);
|
||||
break;
|
||||
case OPCODE_KIL:
|
||||
/* This is only in ARB shaders, so we don't have to worry
|
||||
* about clobbering a CC reg as they aren't supported anyway.
|
||||
*/
|
||||
/* MOVC0 temp, src */
|
||||
pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
|
||||
nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV, temp, SMASK_ALL, 0,
|
||||
src[0], nvr_unused, nvr_unused);
|
||||
nvsinst->cond_update = 1;
|
||||
nvsinst->cond_reg = 0;
|
||||
/* KIL_NV (LT0.xyzw) temp */
|
||||
nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL, nvr_unused, 0, 0,
|
||||
nvr_unused, nvr_unused, nvr_unused);
|
||||
nvsinst->cond = COND_LT;
|
||||
nvsinst->cond_reg = 0;
|
||||
nvsinst->cond_test = 1;
|
||||
pass0_make_swizzle(nvsinst->cond_swizzle, MAKE_SWIZZLE4(0,1,2,3));
|
||||
break;
|
||||
case OPCODE_LIT:
|
||||
break;
|
||||
case OPCODE_LRP:
|
||||
pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0,
|
||||
nvsNegate(src[0]), src[2], src[2]);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat,
|
||||
src[0], src[1], temp);
|
||||
break;
|
||||
case OPCODE_POW:
|
||||
if (shader->SupportsOpcode(shader, NVS_OP_LG2) &&
|
||||
shader->SupportsOpcode(shader, NVS_OP_EX2)) {
|
||||
pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
|
||||
/* LG2 temp.x, src0.c */
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0,
|
||||
nvsSwizzle(src[0], X, X, X, X),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
/* MUL temp.x, temp.x, src1.c */
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0,
|
||||
nvsSwizzle(temp, X, X, X, X),
|
||||
nvsSwizzle(src[1], X, X, X, X),
|
||||
nvr_unused);
|
||||
/* EX2 dest, temp.x */
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat,
|
||||
nvsSwizzle(temp, X, X, X, X),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
} else {
|
||||
/* can we use EXP/LOG instead of EX2/LG2?? */
|
||||
fprintf(stderr, "Implement POW for NV20 vtxprog!\n");
|
||||
return GL_FALSE;
|
||||
}
|
||||
break;
|
||||
case OPCODE_RSQ:
|
||||
if (rec->const_half.file != NVS_FILE_CONST) {
|
||||
GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 };
|
||||
pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST,
|
||||
_mesa_add_unnamed_constant(nvs->mesa.vp.Base.Parameters,
|
||||
const_half, 4));
|
||||
COPY_4V(nvs->params[rec->const_half.index].val, const_half);
|
||||
}
|
||||
pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0,
|
||||
nvsAbs(nvsSwizzle(src[0], X, X, X, X)),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0,
|
||||
nvsSwizzle(temp, X, X, X, X),
|
||||
nvsNegate(rec->const_half),
|
||||
nvr_unused);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat,
|
||||
nvsSwizzle(temp, X, X, X, X),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
break;
|
||||
case OPCODE_SCS:
|
||||
if (mask & SMASK_X)
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_COS, dest, SMASK_X, sat,
|
||||
nvsSwizzle(src[0], X, X, X, X),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
if (mask & SMASK_Y)
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_SIN, dest, SMASK_Y, sat,
|
||||
nvsSwizzle(src[0], X, X, X, X),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
break;
|
||||
case OPCODE_SUB:
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat,
|
||||
src[0], nvsNegate(src[1]), nvr_unused);
|
||||
break;
|
||||
case OPCODE_XPD:
|
||||
pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0,
|
||||
nvsSwizzle(src[0], Z, X, Y, Y),
|
||||
nvsSwizzle(src[1], Y, Z, X, X),
|
||||
nvr_unused);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat,
|
||||
nvsSwizzle(src[0], Y, Z, X, X),
|
||||
nvsSwizzle(src[1], Z, X, Y, Y),
|
||||
nvsNegate(temp));
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "hw doesn't support opcode \"%s\", and no emulation found\n",
|
||||
_mesa_opcode_string(inst->Opcode));
|
||||
return GL_FALSE;
|
||||
}
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_ABS:
|
||||
if (shader->caps & SCAP_SRC_ABS)
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MOV,
|
||||
dest, mask, sat,
|
||||
nvsAbs(src[0]), nvr_unused, nvr_unused);
|
||||
else
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MAX,
|
||||
dest, mask, sat,
|
||||
src[0], nvsNegate(src[0]), nvr_unused);
|
||||
break;
|
||||
case OPCODE_KIL:
|
||||
/* This is only in ARB shaders, so we don't have to worry
|
||||
* about clobbering a CC reg as they aren't supported anyway.
|
||||
*/
|
||||
/* MOVC0 temp, src */
|
||||
pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
|
||||
nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV,
|
||||
temp, SMASK_ALL, 0,
|
||||
src[0], nvr_unused, nvr_unused);
|
||||
nvsinst->cond_update = 1;
|
||||
nvsinst->cond_reg = 0;
|
||||
/* KIL_NV (LT0.xyzw) temp */
|
||||
nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL,
|
||||
nvr_unused, 0, 0,
|
||||
nvr_unused, nvr_unused, nvr_unused);
|
||||
nvsinst->cond = COND_LT;
|
||||
nvsinst->cond_reg = 0;
|
||||
nvsinst->cond_test = 1;
|
||||
pass0_make_swizzle(nvsinst->cond_swizzle,
|
||||
MAKE_SWIZZLE4(0,1,2,3));
|
||||
break;
|
||||
case OPCODE_LRP:
|
||||
pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0,
|
||||
nvsNegate(src[0]), src[2], src[2]);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat,
|
||||
src[0], src[1], temp);
|
||||
break;
|
||||
case OPCODE_POW:
|
||||
if (shader->SupportsOpcode(shader, NVS_OP_LG2) &&
|
||||
shader->SupportsOpcode(shader, NVS_OP_EX2)) {
|
||||
pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
|
||||
/* LG2 temp.x, src0.c */
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_LG2,
|
||||
temp, SMASK_X, 0,
|
||||
nvsSwizzle(src[0], X, X, X, X),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
/* MUL temp.x, temp.x, src1.c */
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MUL,
|
||||
temp, SMASK_X, 0,
|
||||
nvsSwizzle(temp, X, X, X, X),
|
||||
nvsSwizzle(src[1], X, X, X, X),
|
||||
nvr_unused);
|
||||
/* EX2 dest, temp.x */
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_EX2,
|
||||
dest, mask, sat,
|
||||
nvsSwizzle(temp, X, X, X, X),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
} else {
|
||||
/* can we use EXP/LOG instead of EX2/LG2?? */
|
||||
fprintf(stderr, "Implement POW for NV20 vtxprog!\n");
|
||||
return GL_FALSE;
|
||||
}
|
||||
break;
|
||||
case OPCODE_RSQ:
|
||||
if (rec->const_half.file != NVS_FILE_CONST) {
|
||||
GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 };
|
||||
pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST,
|
||||
_mesa_add_unnamed_constant(
|
||||
nvs->mesa.vp.Base.Parameters,
|
||||
const_half, 4));
|
||||
COPY_4V(nvs->params[rec->const_half.index].val,
|
||||
const_half);
|
||||
}
|
||||
pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0,
|
||||
nvsAbs(nvsSwizzle(src[0], X, X, X, X)),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0,
|
||||
nvsSwizzle(temp, X, X, X, X),
|
||||
nvsNegate(rec->const_half),
|
||||
nvr_unused);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat,
|
||||
nvsSwizzle(temp, X, X, X, X),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
break;
|
||||
case OPCODE_SCS:
|
||||
if (mask & SMASK_X)
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_COS,
|
||||
dest, SMASK_X, sat,
|
||||
nvsSwizzle(src[0], X, X, X, X),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
if (mask & SMASK_Y)
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_SIN,
|
||||
dest, SMASK_Y, sat,
|
||||
nvsSwizzle(src[0], X, X, X, X),
|
||||
nvr_unused,
|
||||
nvr_unused);
|
||||
break;
|
||||
case OPCODE_SUB:
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat,
|
||||
src[0], nvsNegate(src[1]), nvr_unused);
|
||||
break;
|
||||
case OPCODE_XPD:
|
||||
pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0,
|
||||
nvsSwizzle(src[0], Z, X, Y, Y),
|
||||
nvsSwizzle(src[1], Y, Z, X, X),
|
||||
nvr_unused);
|
||||
pass0_emit(nvs, parent, fpos, NVS_OP_MAD,
|
||||
dest, (mask & ~SMASK_W), sat,
|
||||
nvsSwizzle(src[0], Y, Z, X, X),
|
||||
nvsSwizzle(src[1], Z, X, Y, Y),
|
||||
nvsNegate(temp));
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE("hw doesn't support opcode \"%s\","
|
||||
"and no emulation found\n",
|
||||
_mesa_opcode_string(inst->Opcode));
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
|
|
|
|||
|
|
@ -41,130 +41,138 @@
|
|||
#include "nouveau_msg.h"
|
||||
|
||||
struct pass2_rec {
|
||||
/* Map nvsRegister temp ID onto hw temp ID */
|
||||
unsigned int temps[NVS_MAX_TEMPS];
|
||||
/* Track free hw registers */
|
||||
unsigned int hw_temps[NVS_MAX_TEMPS];
|
||||
/* Map nvsRegister temp ID onto hw temp ID */
|
||||
unsigned int temps[NVS_MAX_TEMPS];
|
||||
/* Track free hw registers */
|
||||
unsigned int hw_temps[NVS_MAX_TEMPS];
|
||||
};
|
||||
|
||||
static int
|
||||
pass2_alloc_hw_temp(nvsPtr nvs)
|
||||
{
|
||||
struct pass2_rec *rec = nvs->pass_rec;
|
||||
int i;
|
||||
struct pass2_rec *rec = nvs->pass_rec;
|
||||
int i;
|
||||
|
||||
for (i=0; i<nvs->func->MaxTemp; i++) {
|
||||
/* This is a *horrible* hack.. R0 is both temp0 and result.color
|
||||
* in NV30/40 fragprogs, we can use R0 as a temp before result is
|
||||
* written however..
|
||||
*/
|
||||
if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0)
|
||||
continue;
|
||||
for (i=0; i<nvs->func->MaxTemp; i++) {
|
||||
/* This is a *horrible* hack.. R0 is both temp0 and result.color
|
||||
* in NV30/40 fragprogs, we can use R0 as a temp before result
|
||||
* is written however..
|
||||
*/
|
||||
if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0)
|
||||
continue;
|
||||
if (rec->hw_temps[i] == 0) {
|
||||
rec->hw_temps[i] = 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (rec->hw_temps[i] == 0) {
|
||||
rec->hw_temps[i] = 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static nvsRegister
|
||||
pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg)
|
||||
{
|
||||
struct pass2_rec *rec = nvs->pass_rec;
|
||||
struct pass2_rec *rec = nvs->pass_rec;
|
||||
|
||||
if (reg.file == NVS_FILE_TEMP) {
|
||||
if (rec->temps[reg.index] == -1)
|
||||
rec->temps[reg.index] = pass2_alloc_hw_temp(nvs);
|
||||
reg.index = rec->temps[reg.index];
|
||||
}
|
||||
if (reg.file == NVS_FILE_TEMP) {
|
||||
if (rec->temps[reg.index] == -1)
|
||||
rec->temps[reg.index] = pass2_alloc_hw_temp(nvs);
|
||||
reg.index = rec->temps[reg.index];
|
||||
}
|
||||
|
||||
return reg;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static void
|
||||
pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst,
|
||||
struct _op_xlat *op, int slot)
|
||||
struct _op_xlat *op, int slot)
|
||||
{
|
||||
nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
|
||||
nvsFunc *shader = nvs->func;
|
||||
nvsRegister reg;
|
||||
int i;
|
||||
nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y,
|
||||
NVS_SWZ_Z, NVS_SWZ_W };
|
||||
nvsFunc *shader = nvs->func;
|
||||
nvsRegister reg;
|
||||
int i;
|
||||
|
||||
shader->SetOpcode(shader, op->NV, slot);
|
||||
if (inst->saturate ) shader->SetSaturate(shader);
|
||||
if (inst->cond_update) shader->SetCCUpdate(shader);
|
||||
if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond,
|
||||
inst->cond_reg,
|
||||
inst->cond_swizzle);
|
||||
else shader->SetCondition(shader, 0, NVS_COND_TR,
|
||||
0,
|
||||
default_swz);
|
||||
switch (inst->op) {
|
||||
case NVS_OP_TEX:
|
||||
case NVS_OP_TXB:
|
||||
case NVS_OP_TXL:
|
||||
case NVS_OP_TXP:
|
||||
case NVS_OP_TXD:
|
||||
shader->SetTexImageUnit(shader, inst->tex_unit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
shader->SetOpcode(shader, op->NV, slot);
|
||||
if (inst->saturate ) shader->SetSaturate(shader);
|
||||
if (inst->cond_update ) shader->SetCCUpdate(shader);
|
||||
if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond,
|
||||
inst->cond_reg,
|
||||
inst->cond_swizzle);
|
||||
else shader->SetCondition(shader, 0, NVS_COND_TR,
|
||||
0,
|
||||
default_swz);
|
||||
switch (inst->op) {
|
||||
case NVS_OP_TEX:
|
||||
case NVS_OP_TXB:
|
||||
case NVS_OP_TXL:
|
||||
case NVS_OP_TXP:
|
||||
case NVS_OP_TXD:
|
||||
shader->SetTexImageUnit(shader, inst->tex_unit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (op->srcpos[i] != -1) {
|
||||
reg = pass2_mangle_reg(nvs, inst, inst->src[i]);
|
||||
if (reg.file == NVS_FILE_ATTRIB)
|
||||
nvs->inputs_read |= (1 << reg.index);
|
||||
shader->SetSource(shader, ®, op->srcpos[i]);
|
||||
if (reg.file == NVS_FILE_CONST && shader->GetSourceConstVal) {
|
||||
int idx_slot = nvs->params[reg.index].hw_index_cnt++;
|
||||
nvs->params[reg.index].hw_index = realloc(
|
||||
nvs->params[reg.index].hw_index, sizeof(int) * idx_slot+1);
|
||||
nvs->params[reg.index].hw_index[idx_slot] = nvs->program_current + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (op->srcpos[i] != -1) {
|
||||
reg = pass2_mangle_reg(nvs, inst, inst->src[i]);
|
||||
|
||||
reg = pass2_mangle_reg(nvs, inst, inst->dest);
|
||||
if (reg.file == NVS_FILE_RESULT)
|
||||
nvs->outputs_written |= (1 << reg.index);
|
||||
shader->SetResult(shader, ®, inst->mask, slot);
|
||||
if (reg.file == NVS_FILE_ATTRIB)
|
||||
nvs->inputs_read |= (1 << reg.index);
|
||||
shader->SetSource(shader, ®, op->srcpos[i]);
|
||||
|
||||
if (reg.file == NVS_FILE_CONST &&
|
||||
shader->GetSourceConstVal) {
|
||||
int idx_slot =
|
||||
nvs->params[reg.index].hw_index_cnt++;
|
||||
nvs->params[reg.index].hw_index = realloc(
|
||||
nvs->params[reg.index].hw_index,
|
||||
sizeof(int) * idx_slot+1);
|
||||
nvs->params[reg.index].hw_index[idx_slot] =
|
||||
nvs->program_current + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reg = pass2_mangle_reg(nvs, inst, inst->dest);
|
||||
if (reg.file == NVS_FILE_RESULT)
|
||||
nvs->outputs_written |= (1 << reg.index);
|
||||
shader->SetResult(shader, ®, inst->mask, slot);
|
||||
}
|
||||
|
||||
static int
|
||||
pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last)
|
||||
{
|
||||
nvsFunc *shader = nvs->func;
|
||||
struct _op_xlat *op;
|
||||
unsigned int hw_inst[8];
|
||||
int slot;
|
||||
int instsz;
|
||||
int i;
|
||||
nvsFunc *shader = nvs->func;
|
||||
struct _op_xlat *op;
|
||||
unsigned int hw_inst[8];
|
||||
int slot;
|
||||
int instsz;
|
||||
int i;
|
||||
|
||||
shader->inst = hw_inst;
|
||||
shader->inst = hw_inst;
|
||||
|
||||
/* Assemble this instruction */
|
||||
if (!(op = shader->GetOPTXFromSOP(inst->op, &slot)))
|
||||
return 0;
|
||||
shader->InitInstruction(shader);
|
||||
pass2_add_instruction(nvs, inst, op, slot);
|
||||
if (last)
|
||||
shader->SetLastInst(shader);
|
||||
/* Assemble this instruction */
|
||||
if (!(op = shader->GetOPTXFromSOP(inst->op, &slot)))
|
||||
return 0;
|
||||
shader->InitInstruction(shader);
|
||||
pass2_add_instruction(nvs, inst, op, slot);
|
||||
if (last)
|
||||
shader->SetLastInst(shader);
|
||||
|
||||
instsz = shader->GetOffsetNext(nvs->func);
|
||||
if (nvs->program_size + instsz >= nvs->program_alloc_size) {
|
||||
nvs->program_alloc_size *= 2;
|
||||
nvs->program = realloc(nvs->program,
|
||||
nvs->program_alloc_size * sizeof(uint32_t));
|
||||
}
|
||||
instsz = shader->GetOffsetNext(nvs->func);
|
||||
if (nvs->program_size + instsz >= nvs->program_alloc_size) {
|
||||
nvs->program_alloc_size *= 2;
|
||||
nvs->program = realloc(nvs->program,
|
||||
nvs->program_alloc_size *
|
||||
sizeof(uint32_t));
|
||||
}
|
||||
|
||||
for (i=0; i<instsz; i++)
|
||||
nvs->program[nvs->program_current++] = hw_inst[i];
|
||||
nvs->program_size = nvs->program_current;
|
||||
return 1;
|
||||
for (i=0; i<instsz; i++)
|
||||
nvs->program[nvs->program_current++] = hw_inst[i];
|
||||
nvs->program_size = nvs->program_current;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
|
|
@ -198,53 +206,56 @@ pass2_translate(nvsPtr nvs, nvsFragmentHeader *f)
|
|||
GLboolean
|
||||
nouveau_shader_pass2(nvsPtr nvs)
|
||||
{
|
||||
struct pass2_rec *rec;
|
||||
int i;
|
||||
struct pass2_rec *rec;
|
||||
int i;
|
||||
|
||||
rec = calloc(1, sizeof(struct pass2_rec));
|
||||
for (i=0; i<NVS_MAX_TEMPS; i++)
|
||||
rec->temps[i] = -1;
|
||||
nvs->pass_rec = rec;
|
||||
rec = calloc(1, sizeof(struct pass2_rec));
|
||||
for (i=0; i<NVS_MAX_TEMPS; i++)
|
||||
rec->temps[i] = -1;
|
||||
nvs->pass_rec = rec;
|
||||
|
||||
/* Start off with allocating 4 uint32_t's for each inst, will be grown
|
||||
* if necessary..
|
||||
*/
|
||||
nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4;
|
||||
nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t));
|
||||
nvs->program_size = 0;
|
||||
nvs->program_current = 0;
|
||||
/* Start off with allocating 4 uint32_t's for each inst, will be grown
|
||||
* if necessary..
|
||||
*/
|
||||
nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4;
|
||||
nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t));
|
||||
nvs->program_size = 0;
|
||||
nvs->program_current = 0;
|
||||
|
||||
if (!pass2_translate(nvs, ((nvsSubroutine*)nvs->program_tree)->insn_head)) {
|
||||
free(nvs->program);
|
||||
nvs->program = NULL;
|
||||
return GL_FALSE;
|
||||
}
|
||||
if (!pass2_translate(nvs,
|
||||
((nvsSubroutine*)nvs->program_tree)->insn_head)) {
|
||||
free(nvs->program);
|
||||
nvs->program = NULL;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* Shrink allocated memory to only what we need */
|
||||
nvs->program = realloc(nvs->program, nvs->program_size * sizeof(uint32_t));
|
||||
nvs->program_alloc_size = nvs->program_size;
|
||||
/* Shrink allocated memory to only what we need */
|
||||
nvs->program = realloc(nvs->program,
|
||||
nvs->program_size * sizeof(uint32_t));
|
||||
nvs->program_alloc_size = nvs->program_size;
|
||||
|
||||
nvs->translated = 1;
|
||||
nvs->on_hardware = 0;
|
||||
nvs->translated = 1;
|
||||
nvs->on_hardware = 0;
|
||||
|
||||
if (NOUVEAU_DEBUG & DEBUG_SHADERS) {
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "----------------MESA PROGRAM target=%s, id=0x%x\n",
|
||||
_mesa_lookup_enum_by_nr(nvs->mesa.vp.Base.Target),
|
||||
nvs->mesa.vp.Base.Id);
|
||||
fflush(stdout); fflush(stderr);
|
||||
_mesa_print_program(&nvs->mesa.vp.Base);
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n");
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "----------------NV PROGRAM\n");
|
||||
fflush(stdout); fflush(stderr);
|
||||
nvsDisasmHWShader(nvs);
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n");
|
||||
fflush(stdout); fflush(stderr);
|
||||
}
|
||||
if (NOUVEAU_DEBUG & DEBUG_SHADERS) {
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "-----------MESA PROGRAM target=%s, id=0x%x\n",
|
||||
_mesa_lookup_enum_by_nr(
|
||||
nvs->mesa.vp.Base.Target),
|
||||
nvs->mesa.vp.Base.Id);
|
||||
fflush(stdout); fflush(stderr);
|
||||
_mesa_print_program(&nvs->mesa.vp.Base);
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n");
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "----------------NV PROGRAM\n");
|
||||
fflush(stdout); fflush(stderr);
|
||||
nvsDisasmHWShader(nvs);
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n");
|
||||
fflush(stdout); fflush(stderr);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue