mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-28 19:00:13 +01:00
965: remove complex compiler for simple fragment programs.
Keep the simple compiler for complex fragment programs...
This commit is contained in:
parent
ea7c533d40
commit
06036bc8c4
6 changed files with 0 additions and 2545 deletions
|
|
@ -45,14 +45,8 @@ DRIVER_SOURCES = \
|
|||
brw_vs_state.c \
|
||||
brw_vtbl.c \
|
||||
brw_wm.c \
|
||||
brw_wm_debug.c \
|
||||
brw_wm_emit.c \
|
||||
brw_wm_fp.c \
|
||||
brw_wm_iz.c \
|
||||
brw_wm_glsl.c \
|
||||
brw_wm_pass0.c \
|
||||
brw_wm_pass1.c \
|
||||
brw_wm_pass2.c \
|
||||
brw_wm_sampler_state.c \
|
||||
brw_wm_state.c \
|
||||
brw_wm_surface_state.c
|
||||
|
|
|
|||
|
|
@ -1,172 +0,0 @@
|
|||
/*
|
||||
Copyright (C) Intel Corp. 2006. All Rights Reserved.
|
||||
Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
|
||||
develop this 3D driver.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**********************************************************************/
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_wm.h"
|
||||
|
||||
#if 0
|
||||
void brw_wm_print_value( struct brw_wm_compile *c,
|
||||
struct brw_wm_value *value )
|
||||
{
|
||||
assert(value);
|
||||
if (c->state >= PASS2_DONE)
|
||||
brw_print_reg(value->hw_reg);
|
||||
else if( value == &c->undef_value )
|
||||
_mesa_printf("undef");
|
||||
else if( value - c->vreg >= 0 &&
|
||||
value - c->vreg < BRW_WM_MAX_VREG)
|
||||
_mesa_printf("r%d", value - c->vreg);
|
||||
else if (value - c->creg >= 0 &&
|
||||
value - c->creg < BRW_WM_MAX_PARAM)
|
||||
_mesa_printf("c%d", value - c->creg);
|
||||
else if (value - c->payload.input_interp >= 0 &&
|
||||
value - c->payload.input_interp < FRAG_ATTRIB_MAX)
|
||||
_mesa_printf("i%d", value - c->payload.input_interp);
|
||||
else if (value - c->payload.depth >= 0 &&
|
||||
value - c->payload.depth < FRAG_ATTRIB_MAX)
|
||||
_mesa_printf("d%d", value - c->payload.depth);
|
||||
else
|
||||
_mesa_printf("?");
|
||||
}
|
||||
|
||||
void brw_wm_print_ref( struct brw_wm_compile *c,
|
||||
struct brw_wm_ref *ref )
|
||||
{
|
||||
struct brw_reg hw_reg = ref->hw_reg;
|
||||
|
||||
if (ref->unspill_reg)
|
||||
_mesa_printf("UNSPILL(%x)/", ref->value->spill_slot);
|
||||
|
||||
if (c->state >= PASS2_DONE)
|
||||
brw_print_reg(ref->hw_reg);
|
||||
else {
|
||||
_mesa_printf("%s", hw_reg.negate ? "-" : "");
|
||||
_mesa_printf("%s", hw_reg.abs ? "abs/" : "");
|
||||
brw_wm_print_value(c, ref->value);
|
||||
if ((hw_reg.nr&1) || hw_reg.subnr) {
|
||||
_mesa_printf("->%d.%d", (hw_reg.nr&1), hw_reg.subnr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void brw_wm_print_insn( struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *inst )
|
||||
{
|
||||
unsigned i, arg;
|
||||
unsigned nr_args = brw_wm_nr_args(inst->opcode);
|
||||
|
||||
_mesa_printf("[");
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (inst->dst[i]) {
|
||||
brw_wm_print_value(c, inst->dst[i]);
|
||||
if (inst->dst[i]->spill_slot)
|
||||
_mesa_printf("/SPILL(%x)",inst->dst[i]->spill_slot);
|
||||
}
|
||||
else
|
||||
_mesa_printf("#");
|
||||
if (i < 3)
|
||||
_mesa_printf(",");
|
||||
}
|
||||
_mesa_printf("]");
|
||||
|
||||
if (inst->writemask != WRITEMASK_XYZW)
|
||||
_mesa_printf(".%s%s%s%s",
|
||||
GET_BIT(inst->writemask, 0) ? "x" : "",
|
||||
GET_BIT(inst->writemask, 1) ? "y" : "",
|
||||
GET_BIT(inst->writemask, 2) ? "z" : "",
|
||||
GET_BIT(inst->writemask, 3) ? "w" : "");
|
||||
|
||||
switch (inst->opcode) {
|
||||
case WM_PIXELXY:
|
||||
_mesa_printf(" = PIXELXY");
|
||||
break;
|
||||
case WM_DELTAXY:
|
||||
_mesa_printf(" = DELTAXY");
|
||||
break;
|
||||
case WM_PIXELW:
|
||||
_mesa_printf(" = PIXELW");
|
||||
break;
|
||||
case WM_WPOSXY:
|
||||
_mesa_printf(" = WPOSXY");
|
||||
break;
|
||||
case WM_PINTERP:
|
||||
_mesa_printf(" = PINTERP");
|
||||
break;
|
||||
case WM_LINTERP:
|
||||
_mesa_printf(" = LINTERP");
|
||||
break;
|
||||
case WM_CINTERP:
|
||||
_mesa_printf(" = CINTERP");
|
||||
break;
|
||||
case WM_FB_WRITE:
|
||||
_mesa_printf(" = FB_WRITE");
|
||||
break;
|
||||
default:
|
||||
_mesa_printf(" = %s", _mesa_opcode_string(inst->opcode));
|
||||
break;
|
||||
}
|
||||
|
||||
if (inst->saturate)
|
||||
_mesa_printf("_SAT");
|
||||
|
||||
for (arg = 0; arg < nr_args; arg++) {
|
||||
|
||||
_mesa_printf(" [");
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (inst->src[arg][i]) {
|
||||
brw_wm_print_ref(c, inst->src[arg][i]);
|
||||
}
|
||||
else
|
||||
_mesa_printf("%%");
|
||||
|
||||
if (i < 3)
|
||||
_mesa_printf(",");
|
||||
else
|
||||
_mesa_printf("]");
|
||||
}
|
||||
}
|
||||
_mesa_printf("\n");
|
||||
}
|
||||
|
||||
void brw_wm_print_program( struct brw_wm_compile *c,
|
||||
const char *stage )
|
||||
{
|
||||
unsigned insn;
|
||||
|
||||
_mesa_printf("\n\n\n%s:\n", stage);
|
||||
for (insn = 0; insn < c->nr_insns; insn++)
|
||||
brw_wm_print_insn(c, &c->instruction[insn]);
|
||||
_mesa_printf("\n\n\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,466 +0,0 @@
|
|||
/*
|
||||
Copyright (C) Intel Corp. 2006. All Rights Reserved.
|
||||
Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
|
||||
develop this 3D driver.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**********************************************************************/
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_wm.h"
|
||||
|
||||
|
||||
#if 0
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
static struct brw_wm_ref *get_ref( struct brw_wm_compile *c )
|
||||
{
|
||||
assert(c->nr_refs < BRW_WM_MAX_REF);
|
||||
return &c->refs[c->nr_refs++];
|
||||
}
|
||||
|
||||
static struct brw_wm_value *get_value( struct brw_wm_compile *c)
|
||||
{
|
||||
assert(c->nr_refs < BRW_WM_MAX_VREG);
|
||||
return &c->vreg[c->nr_vreg++];
|
||||
}
|
||||
|
||||
static struct brw_wm_instruction *get_instruction( struct brw_wm_compile *c )
|
||||
{
|
||||
assert(c->nr_insns < BRW_WM_MAX_INSN);
|
||||
return &c->instruction[c->nr_insns++];
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
static void pass0_init_undef( struct brw_wm_compile *c)
|
||||
{
|
||||
struct brw_wm_ref *ref = &c->undef_ref;
|
||||
ref->value = &c->undef_value;
|
||||
ref->hw_reg = brw_vec8_grf(0, 0);
|
||||
ref->insn = 0;
|
||||
ref->prevuse = NULL;
|
||||
}
|
||||
|
||||
static void pass0_set_fpreg_value( struct brw_wm_compile *c,
|
||||
unsigned file,
|
||||
unsigned idx,
|
||||
unsigned component,
|
||||
struct brw_wm_value *value )
|
||||
{
|
||||
struct brw_wm_ref *ref = get_ref(c);
|
||||
ref->value = value;
|
||||
ref->hw_reg = brw_vec8_grf(0, 0);
|
||||
ref->insn = 0;
|
||||
ref->prevuse = NULL;
|
||||
c->pass0_fp_reg[file][idx][component] = ref;
|
||||
}
|
||||
|
||||
static void pass0_set_fpreg_ref( struct brw_wm_compile *c,
|
||||
unsigned file,
|
||||
unsigned idx,
|
||||
unsigned component,
|
||||
const struct brw_wm_ref *src_ref )
|
||||
{
|
||||
c->pass0_fp_reg[file][idx][component] = src_ref;
|
||||
}
|
||||
|
||||
static const struct brw_wm_ref *get_param_ref( struct brw_wm_compile *c,
|
||||
const float *param_ptr )
|
||||
{
|
||||
unsigned i = c->prog_data.nr_params++;
|
||||
|
||||
if (i >= BRW_WM_MAX_PARAM) {
|
||||
_mesa_printf("%s: out of params\n", __FUNCTION__);
|
||||
c->prog_data.error = 1;
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
struct brw_wm_ref *ref = get_ref(c);
|
||||
|
||||
c->prog_data.param[i] = param_ptr;
|
||||
c->nr_creg = (i+16)/16;
|
||||
|
||||
/* Push the offsets into hw_reg. These will be added to the
|
||||
* real register numbers once one is allocated in pass2.
|
||||
*/
|
||||
ref->hw_reg = brw_vec1_grf((i&8)?1:0, i%8);
|
||||
ref->value = &c->creg[i/16];
|
||||
ref->insn = 0;
|
||||
ref->prevuse = NULL;
|
||||
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const struct brw_wm_ref *get_const_ref( struct brw_wm_compile *c,
|
||||
const float *constval )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* Search for an existing const value matching the request:
|
||||
*/
|
||||
for (i = 0; i < c->nr_constrefs; i++) {
|
||||
if (c->constref[i].constval == *constval)
|
||||
return c->constref[i].ref;
|
||||
}
|
||||
|
||||
/* Else try to add a new one:
|
||||
*/
|
||||
if (c->nr_constrefs < BRW_WM_MAX_CONST) {
|
||||
unsigned i = c->nr_constrefs++;
|
||||
|
||||
/* A constant is a special type of parameter:
|
||||
*/
|
||||
c->constref[i].constval = *constval;
|
||||
c->constref[i].ref = get_param_ref(c, constval);
|
||||
|
||||
return c->constref[i].ref;
|
||||
}
|
||||
else {
|
||||
_mesa_printf("%s: out of constrefs\n", __FUNCTION__);
|
||||
c->prog_data.error = 1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Lookup our internal registers
|
||||
*/
|
||||
static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
|
||||
unsigned file,
|
||||
unsigned idx,
|
||||
unsigned component )
|
||||
{
|
||||
const struct brw_wm_ref *ref = c->pass0_fp_reg[file][idx][component];
|
||||
|
||||
if (!ref) {
|
||||
switch (file) {
|
||||
case PROGRAM_INPUT:
|
||||
case PROGRAM_PAYLOAD:
|
||||
case PROGRAM_TEMPORARY:
|
||||
case PROGRAM_OUTPUT:
|
||||
case PROGRAM_VARYING:
|
||||
break;
|
||||
|
||||
case PROGRAM_LOCAL_PARAM:
|
||||
ref = get_param_ref(c, &c->fp->program.Base.LocalParams[idx][component]);
|
||||
break;
|
||||
|
||||
case PROGRAM_ENV_PARAM:
|
||||
ref = get_param_ref(c, &c->env_param[idx][component]);
|
||||
break;
|
||||
|
||||
case PROGRAM_STATE_VAR:
|
||||
case PROGRAM_UNIFORM:
|
||||
case PROGRAM_CONSTANT:
|
||||
case PROGRAM_NAMED_PARAM: {
|
||||
struct gl_program_parameter_list *plist = c->fp->program.Base.Parameters;
|
||||
|
||||
/* There's something really hokey about parameters parsed in
|
||||
* arb programs - they all end up in here, whether they be
|
||||
* state values, paramters or constants. This duplicates the
|
||||
* structure above & also seems to subvert the limits set for
|
||||
* each type of constant/param.
|
||||
*/
|
||||
switch (plist->Parameters[idx].Type) {
|
||||
case PROGRAM_NAMED_PARAM:
|
||||
case PROGRAM_CONSTANT:
|
||||
/* These are invarient:
|
||||
*/
|
||||
ref = get_const_ref(c, &plist->ParameterValues[idx][component]);
|
||||
break;
|
||||
|
||||
case PROGRAM_STATE_VAR:
|
||||
case PROGRAM_UNIFORM:
|
||||
/* These may change from run to run:
|
||||
*/
|
||||
ref = get_param_ref(c, &plist->ParameterValues[idx][component] );
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
c->pass0_fp_reg[file][idx][component] = ref;
|
||||
}
|
||||
|
||||
if (!ref)
|
||||
ref = &c->undef_ref;
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Straight translation to internal instruction format
|
||||
*/
|
||||
|
||||
static void pass0_set_dst( struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *out,
|
||||
const struct prog_instruction *inst,
|
||||
unsigned writemask )
|
||||
{
|
||||
const struct prog_dst_register *dst = &inst->DstReg;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (writemask & (1<<i)) {
|
||||
out->dst[i] = get_value(c);
|
||||
|
||||
pass0_set_fpreg_value(c, dst->File, dst->Index, i, out->dst[i]);
|
||||
}
|
||||
}
|
||||
|
||||
out->writemask = writemask;
|
||||
}
|
||||
|
||||
|
||||
static void pass0_set_dst_scalar( struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *out,
|
||||
const struct prog_instruction *inst,
|
||||
unsigned writemask )
|
||||
{
|
||||
if (writemask) {
|
||||
const struct prog_dst_register *dst = &inst->DstReg;
|
||||
unsigned i;
|
||||
|
||||
/* Compute only the first (X) value:
|
||||
*/
|
||||
out->writemask = WRITEMASK_X;
|
||||
out->dst[0] = get_value(c);
|
||||
|
||||
/* Update our tracking register file for all the components in
|
||||
* writemask:
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (writemask & (1<<i)) {
|
||||
pass0_set_fpreg_value(c, dst->File, dst->Index, i, out->dst[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
out->writemask = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const struct brw_wm_ref *get_fp_src_reg_ref( struct brw_wm_compile *c,
|
||||
struct prog_src_register src,
|
||||
unsigned i )
|
||||
{
|
||||
unsigned component = GET_SWZ(src.Swizzle,i);
|
||||
const struct brw_wm_ref *src_ref;
|
||||
static const float const_zero = 0.0;
|
||||
static const float const_one = 1.0;
|
||||
|
||||
|
||||
if (component == SWIZZLE_ZERO)
|
||||
src_ref = get_const_ref(c, &const_zero);
|
||||
else if (component == SWIZZLE_ONE)
|
||||
src_ref = get_const_ref(c, &const_one);
|
||||
else
|
||||
src_ref = pass0_get_reg(c, src.File, src.Index, component);
|
||||
|
||||
return src_ref;
|
||||
}
|
||||
|
||||
|
||||
static struct brw_wm_ref *get_new_ref( struct brw_wm_compile *c,
|
||||
struct prog_src_register src,
|
||||
unsigned i,
|
||||
struct brw_wm_instruction *insn)
|
||||
{
|
||||
const struct brw_wm_ref *ref = get_fp_src_reg_ref(c, src, i);
|
||||
struct brw_wm_ref *newref = get_ref(c);
|
||||
|
||||
newref->value = ref->value;
|
||||
newref->hw_reg = ref->hw_reg;
|
||||
|
||||
if (insn) {
|
||||
newref->insn = insn - c->instruction;
|
||||
newref->prevuse = newref->value->lastuse;
|
||||
newref->value->lastuse = newref;
|
||||
}
|
||||
|
||||
if (src.NegateBase & (1<<i))
|
||||
newref->hw_reg.negate ^= 1;
|
||||
|
||||
if (src.Abs) {
|
||||
newref->hw_reg.negate = 0;
|
||||
newref->hw_reg.abs = 1;
|
||||
}
|
||||
|
||||
return newref;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct brw_wm_instruction *translate_insn( struct brw_wm_compile *c,
|
||||
const struct prog_instruction *inst )
|
||||
{
|
||||
struct brw_wm_instruction *out = get_instruction(c);
|
||||
unsigned writemask = inst->DstReg.WriteMask;
|
||||
unsigned nr_args = brw_wm_nr_args(inst->Opcode);
|
||||
unsigned i, j;
|
||||
|
||||
/* Copy some data out of the instruction
|
||||
*/
|
||||
out->opcode = inst->Opcode;
|
||||
out->saturate = (inst->SaturateMode != SATURATE_OFF);
|
||||
out->tex_unit = inst->TexSrcUnit;
|
||||
out->tex_idx = inst->TexSrcTarget;
|
||||
|
||||
/* Args:
|
||||
*/
|
||||
for (i = 0; i < nr_args; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
out->src[i][j] = get_new_ref(c, inst->SrcReg[i], j, out);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dst:
|
||||
*/
|
||||
if (brw_wm_is_scalar_result(out->opcode))
|
||||
pass0_set_dst_scalar(c, out, inst, writemask);
|
||||
else
|
||||
pass0_set_dst(c, out, inst, writemask);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Optimize moves and swizzles away:
|
||||
*/
|
||||
static void pass0_precalc_mov( struct brw_wm_compile *c,
|
||||
const struct prog_instruction *inst )
|
||||
{
|
||||
const struct prog_dst_register *dst = &inst->DstReg;
|
||||
unsigned writemask = inst->DstReg.WriteMask;
|
||||
unsigned i;
|
||||
|
||||
/* Get the effect of a MOV by manipulating our register table:
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (writemask & (1<<i)) {
|
||||
pass0_set_fpreg_ref( c, dst->File, dst->Index, i,
|
||||
get_new_ref(c, inst->SrcReg[0], i, NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialize payload "registers".
|
||||
*/
|
||||
static void pass0_init_payload( struct brw_wm_compile *c )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
unsigned j = i >= c->key.nr_depth_regs ? 0 : i;
|
||||
pass0_set_fpreg_value( c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i,
|
||||
&c->payload.depth[j] );
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This seems to be an alternative to the INTERP_WPOS stuff I do
|
||||
* elsewhere:
|
||||
*/
|
||||
if (c->key.source_depth_reg)
|
||||
pass0_set_fpreg_value(c, PROGRAM_INPUT, FRAG_ATTRIB_WPOS, 2,
|
||||
&c->payload.depth[c->key.source_depth_reg/2]);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < FRAG_ATTRIB_MAX; i++)
|
||||
pass0_set_fpreg_value( c, PROGRAM_PAYLOAD, i, 0,
|
||||
&c->payload.input_interp[i] );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* PASS 0
|
||||
*
|
||||
* Work forwards to give each calculated value a unique number. Where
|
||||
* an instruction produces duplicate values (eg DP3), all are given
|
||||
* the same number.
|
||||
*
|
||||
* Translate away swizzling and eliminate non-saturating moves.
|
||||
*/
|
||||
void brw_wm_pass0( struct brw_wm_compile *c )
|
||||
{
|
||||
unsigned insn;
|
||||
|
||||
c->nr_vreg = 0;
|
||||
c->nr_insns = 0;
|
||||
|
||||
pass0_init_undef(c);
|
||||
pass0_init_payload(c);
|
||||
|
||||
for (insn = 0; insn < c->nr_fp_insns; insn++) {
|
||||
const struct prog_instruction *inst = &c->prog_instructions[insn];
|
||||
|
||||
|
||||
/* Optimize away moves, otherwise emit translated instruction:
|
||||
*/
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_MOV:
|
||||
case OPCODE_SWZ:
|
||||
if (!inst->SaturateMode) {
|
||||
pass0_precalc_mov(c, inst);
|
||||
}
|
||||
else {
|
||||
translate_insn(c, inst);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
translate_insn(c, inst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (BRW_DEBUG & DEBUG_WM) {
|
||||
brw_wm_print_program(c, "pass0");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,277 +0,0 @@
|
|||
/*
|
||||
Copyright (C) Intel Corp. 2006. All Rights Reserved.
|
||||
Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
|
||||
develop this 3D driver.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**********************************************************************/
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_wm.h"
|
||||
|
||||
#if 0
|
||||
static unsigned get_tracked_mask(struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *inst)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (inst->writemask & (1<<i)) {
|
||||
if (!inst->dst[i]->contributes_to_output) {
|
||||
inst->writemask &= ~(1<<i);
|
||||
inst->dst[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inst->writemask;
|
||||
}
|
||||
|
||||
/* Remove a reference from a value's usage chain.
|
||||
*/
|
||||
static void unlink_ref(struct brw_wm_ref *ref)
|
||||
{
|
||||
struct brw_wm_value *value = ref->value;
|
||||
|
||||
if (ref == value->lastuse) {
|
||||
value->lastuse = ref->prevuse;
|
||||
} else {
|
||||
struct brw_wm_ref *i = value->lastuse;
|
||||
while (i->prevuse != ref) i = i->prevuse;
|
||||
i->prevuse = ref->prevuse;
|
||||
}
|
||||
}
|
||||
|
||||
static void track_arg(struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *inst,
|
||||
unsigned arg,
|
||||
unsigned readmask)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct brw_wm_ref *ref = inst->src[arg][i];
|
||||
if (ref) {
|
||||
if (readmask & (1<<i))
|
||||
ref->value->contributes_to_output = 1;
|
||||
else {
|
||||
unlink_ref(ref);
|
||||
inst->src[arg][i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned get_texcoord_mask( unsigned tex_idx )
|
||||
{
|
||||
switch (tex_idx) {
|
||||
case TEXTURE_1D_INDEX: return WRITEMASK_X;
|
||||
case TEXTURE_2D_INDEX: return WRITEMASK_XY;
|
||||
case TEXTURE_3D_INDEX: return WRITEMASK_XYZ;
|
||||
case TEXTURE_CUBE_INDEX: return WRITEMASK_XYZ;
|
||||
case TEXTURE_RECT_INDEX: return WRITEMASK_XY;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Step two: Basically this is dead code elimination.
|
||||
*
|
||||
* Iterate backwards over instructions, noting which values
|
||||
* contribute to the final result. Adjust writemasks to only
|
||||
* calculate these values.
|
||||
*/
|
||||
void brw_wm_pass1( struct brw_wm_compile *c )
|
||||
{
|
||||
int insn;
|
||||
|
||||
for (insn = c->nr_insns-1; insn >= 0; insn--) {
|
||||
struct brw_wm_instruction *inst = &c->instruction[insn];
|
||||
unsigned writemask;
|
||||
unsigned read0, read1, read2;
|
||||
|
||||
if (inst->opcode == OPCODE_KIL) {
|
||||
track_arg(c, inst, 0, WRITEMASK_XYZW); /* All args contribute to final */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inst->opcode == WM_FB_WRITE) {
|
||||
track_arg(c, inst, 0, WRITEMASK_XYZW);
|
||||
track_arg(c, inst, 1, WRITEMASK_XYZW);
|
||||
if (c->key.source_depth_to_render_target &&
|
||||
c->key.computes_depth)
|
||||
track_arg(c, inst, 2, WRITEMASK_Z);
|
||||
else
|
||||
track_arg(c, inst, 2, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Lookup all the registers which were written by this
|
||||
* instruction and get a mask of those that contribute to the output:
|
||||
*/
|
||||
writemask = get_tracked_mask(c, inst);
|
||||
if (!writemask) {
|
||||
unsigned arg;
|
||||
for (arg = 0; arg < 3; arg++)
|
||||
track_arg(c, inst, arg, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
read0 = 0;
|
||||
read1 = 0;
|
||||
read2 = 0;
|
||||
|
||||
/* Mark all inputs which contribute to the marked outputs:
|
||||
*/
|
||||
switch (inst->opcode) {
|
||||
case OPCODE_ABS:
|
||||
case OPCODE_FLR:
|
||||
case OPCODE_FRC:
|
||||
case OPCODE_MOV:
|
||||
read0 = writemask;
|
||||
break;
|
||||
|
||||
case OPCODE_SUB:
|
||||
case OPCODE_SLT:
|
||||
case OPCODE_SLE:
|
||||
case OPCODE_SGE:
|
||||
case OPCODE_SGT:
|
||||
case OPCODE_SEQ:
|
||||
case OPCODE_SNE:
|
||||
case OPCODE_ADD:
|
||||
case OPCODE_MAX:
|
||||
case OPCODE_MIN:
|
||||
case OPCODE_MUL:
|
||||
read0 = writemask;
|
||||
read1 = writemask;
|
||||
break;
|
||||
|
||||
case OPCODE_MAD:
|
||||
case OPCODE_CMP:
|
||||
case OPCODE_LRP:
|
||||
read0 = writemask;
|
||||
read1 = writemask;
|
||||
read2 = writemask;
|
||||
break;
|
||||
|
||||
case OPCODE_XPD:
|
||||
if (writemask & WRITEMASK_X) read0 |= WRITEMASK_YZ;
|
||||
if (writemask & WRITEMASK_Y) read0 |= WRITEMASK_XZ;
|
||||
if (writemask & WRITEMASK_Z) read0 |= WRITEMASK_XY;
|
||||
read1 = read0;
|
||||
break;
|
||||
|
||||
case OPCODE_COS:
|
||||
case OPCODE_EX2:
|
||||
case OPCODE_LG2:
|
||||
case OPCODE_RCP:
|
||||
case OPCODE_RSQ:
|
||||
case OPCODE_SIN:
|
||||
case OPCODE_SCS:
|
||||
case WM_CINTERP:
|
||||
case WM_PIXELXY:
|
||||
read0 = WRITEMASK_X;
|
||||
break;
|
||||
|
||||
case OPCODE_POW:
|
||||
read0 = WRITEMASK_X;
|
||||
read1 = WRITEMASK_X;
|
||||
break;
|
||||
|
||||
case OPCODE_TEX:
|
||||
read0 = get_texcoord_mask(inst->tex_idx);
|
||||
|
||||
if (c->key.shadowtex_mask & (1<<inst->tex_unit))
|
||||
read0 |= WRITEMASK_Z;
|
||||
break;
|
||||
|
||||
case OPCODE_TXB:
|
||||
/* Shadow ignored for txb.
|
||||
*/
|
||||
read0 = get_texcoord_mask(inst->tex_idx) | WRITEMASK_W;
|
||||
break;
|
||||
|
||||
case WM_WPOSXY:
|
||||
read0 = writemask & WRITEMASK_XY;
|
||||
break;
|
||||
|
||||
case WM_DELTAXY:
|
||||
read0 = writemask & WRITEMASK_XY;
|
||||
read1 = WRITEMASK_X;
|
||||
break;
|
||||
|
||||
case WM_PIXELW:
|
||||
read0 = WRITEMASK_X;
|
||||
read1 = WRITEMASK_XY;
|
||||
break;
|
||||
|
||||
case WM_LINTERP:
|
||||
read0 = WRITEMASK_X;
|
||||
read1 = WRITEMASK_XY;
|
||||
break;
|
||||
|
||||
case WM_PINTERP:
|
||||
read0 = WRITEMASK_X; /* interpolant */
|
||||
read1 = WRITEMASK_XY; /* deltas */
|
||||
read2 = WRITEMASK_W; /* pixel w */
|
||||
break;
|
||||
|
||||
case OPCODE_DP3:
|
||||
read0 = WRITEMASK_XYZ;
|
||||
read1 = WRITEMASK_XYZ;
|
||||
break;
|
||||
|
||||
case OPCODE_DPH:
|
||||
read0 = WRITEMASK_XYZ;
|
||||
read1 = WRITEMASK_XYZW;
|
||||
break;
|
||||
|
||||
case OPCODE_DP4:
|
||||
read0 = WRITEMASK_XYZW;
|
||||
read1 = WRITEMASK_XYZW;
|
||||
break;
|
||||
|
||||
case OPCODE_LIT:
|
||||
read0 = WRITEMASK_XYW;
|
||||
break;
|
||||
|
||||
case OPCODE_SWZ:
|
||||
case OPCODE_DST:
|
||||
case OPCODE_TXP:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
track_arg(c, inst, 0, read0);
|
||||
track_arg(c, inst, 1, read1);
|
||||
track_arg(c, inst, 2, read2);
|
||||
}
|
||||
|
||||
if (BRW_DEBUG & DEBUG_WM) {
|
||||
brw_wm_print_program(c, "pass1");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,335 +0,0 @@
|
|||
/*
|
||||
Copyright (C) Intel Corp. 2006. All Rights Reserved.
|
||||
Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
|
||||
develop this 3D driver.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**********************************************************************/
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_wm.h"
|
||||
|
||||
#if 0
|
||||
/* Use these to force spilling so that that functionality can be
|
||||
* tested with known-good examples rather than having to construct new
|
||||
* tests.
|
||||
*/
|
||||
#define TEST_PAYLOAD_SPILLS 0
|
||||
#define TEST_DST_SPILLS 0
|
||||
|
||||
static void spill_value(struct brw_wm_compile *c,
|
||||
struct brw_wm_value *value);
|
||||
|
||||
static void prealloc_reg(struct brw_wm_compile *c,
|
||||
struct brw_wm_value *value,
|
||||
unsigned reg)
|
||||
{
|
||||
if (value->lastuse) {
|
||||
/* Set nextuse to zero, it will be corrected by
|
||||
* update_register_usage().
|
||||
*/
|
||||
c->pass2_grf[reg].value = value;
|
||||
c->pass2_grf[reg].nextuse = 0;
|
||||
|
||||
value->resident = &c->pass2_grf[reg];
|
||||
value->hw_reg = brw_vec8_grf(reg*2, 0);
|
||||
|
||||
if (TEST_PAYLOAD_SPILLS)
|
||||
spill_value(c, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialize all the register values. Do the initial setup
|
||||
* calculations for interpolants.
|
||||
*/
|
||||
static void init_registers( struct brw_wm_compile *c )
|
||||
{
|
||||
unsigned inputs = FRAG_BIT_WPOS | c->fp_interp_emitted;
|
||||
unsigned nr_interp_regs = 0;
|
||||
unsigned i = 0;
|
||||
unsigned j;
|
||||
|
||||
for (j = 0; j < c->grf_limit; j++)
|
||||
c->pass2_grf[j].nextuse = BRW_WM_MAX_INSN;
|
||||
|
||||
for (j = 0; j < c->key.nr_depth_regs; j++)
|
||||
prealloc_reg(c, &c->payload.depth[j], i++);
|
||||
|
||||
for (j = 0; j < c->nr_creg; j++)
|
||||
prealloc_reg(c, &c->creg[j], i++);
|
||||
|
||||
for (j = 0; j < FRAG_ATTRIB_MAX; j++)
|
||||
if (inputs & (1<<j)) {
|
||||
nr_interp_regs++;
|
||||
prealloc_reg(c, &c->payload.input_interp[j], i++);
|
||||
}
|
||||
|
||||
assert(nr_interp_regs >= 1);
|
||||
|
||||
c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
|
||||
c->prog_data.urb_read_length = nr_interp_regs * 2;
|
||||
c->prog_data.curb_read_length = c->nr_creg * 2;
|
||||
|
||||
c->max_wm_grf = i * 2;
|
||||
}
|
||||
|
||||
|
||||
/* Update the nextuse value for each register in our file.
|
||||
*/
|
||||
static void update_register_usage(struct brw_wm_compile *c,
|
||||
unsigned thisinsn)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i < c->grf_limit; i++) {
|
||||
struct brw_wm_grf *grf = &c->pass2_grf[i];
|
||||
|
||||
/* Only search those which can change:
|
||||
*/
|
||||
if (grf->nextuse < thisinsn) {
|
||||
struct brw_wm_ref *ref = grf->value->lastuse;
|
||||
|
||||
/* Has last use of value been passed?
|
||||
*/
|
||||
if (ref->insn < thisinsn) {
|
||||
grf->value->resident = 0;
|
||||
grf->value = 0;
|
||||
grf->nextuse = BRW_WM_MAX_INSN;
|
||||
}
|
||||
else {
|
||||
/* Else loop through chain to update:
|
||||
*/
|
||||
while (ref->prevuse && ref->prevuse->insn >= thisinsn)
|
||||
ref = ref->prevuse;
|
||||
|
||||
grf->nextuse = ref->insn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void spill_value(struct brw_wm_compile *c,
|
||||
struct brw_wm_value *value)
|
||||
{
|
||||
/* Allocate a spill slot. Note that allocations start from 0x40 -
|
||||
* the first slot is reserved to mean "undef" in brw_wm_emit.c
|
||||
*/
|
||||
if (!value->spill_slot) {
|
||||
c->last_scratch += 0x40;
|
||||
value->spill_slot = c->last_scratch;
|
||||
}
|
||||
|
||||
/* The spill will be done in brw_wm_emit.c immediately after the
|
||||
* value is calculated, so we can just take this reg without any
|
||||
* further work.
|
||||
*/
|
||||
value->resident->value = NULL;
|
||||
value->resident->nextuse = BRW_WM_MAX_INSN;
|
||||
value->resident = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Search for contiguous region with the most distant nearest
|
||||
* member. Free regs count as very distant.
|
||||
*
|
||||
* TODO: implement spill-to-reg so that we can rearrange discontigous
|
||||
* free regs and then spill the oldest non-free regs in sequence.
|
||||
* This would mean inserting instructions in this pass.
|
||||
*/
|
||||
static unsigned search_contiguous_regs(struct brw_wm_compile *c,
|
||||
unsigned nr,
|
||||
unsigned thisinsn)
|
||||
{
|
||||
struct brw_wm_grf *grf = c->pass2_grf;
|
||||
unsigned furthest = 0;
|
||||
unsigned reg = 0;
|
||||
unsigned i, j;
|
||||
|
||||
/* Start search at 1: r0 is special and can't be used or spilled.
|
||||
*/
|
||||
for (i = 1; i < c->grf_limit && furthest < BRW_WM_MAX_INSN; i++) {
|
||||
unsigned group_nextuse = BRW_WM_MAX_INSN;
|
||||
|
||||
for (j = 0; j < nr; j++) {
|
||||
if (grf[i+j].nextuse < group_nextuse)
|
||||
group_nextuse = grf[i+j].nextuse;
|
||||
}
|
||||
|
||||
if (group_nextuse > furthest) {
|
||||
furthest = group_nextuse;
|
||||
reg = i;
|
||||
}
|
||||
}
|
||||
|
||||
assert(furthest != thisinsn);
|
||||
|
||||
/* Any non-empty regs will need to be spilled:
|
||||
*/
|
||||
for (j = 0; j < nr; j++)
|
||||
if (grf[reg+j].value)
|
||||
spill_value(c, grf[reg+j].value);
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static void alloc_contiguous_dest(struct brw_wm_compile *c,
|
||||
struct brw_wm_value *dst[],
|
||||
unsigned nr,
|
||||
unsigned thisinsn)
|
||||
{
|
||||
unsigned reg = search_contiguous_regs(c, nr, thisinsn);
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (!dst[i]) {
|
||||
/* Need to grab a dummy value in TEX case. Don't introduce
|
||||
* it into the tracking scheme.
|
||||
*/
|
||||
dst[i] = &c->vreg[c->nr_vreg++];
|
||||
}
|
||||
else {
|
||||
assert(!dst[i]->resident);
|
||||
assert(c->pass2_grf[reg+i].nextuse != thisinsn);
|
||||
|
||||
c->pass2_grf[reg+i].value = dst[i];
|
||||
c->pass2_grf[reg+i].nextuse = thisinsn;
|
||||
|
||||
dst[i]->resident = &c->pass2_grf[reg+i];
|
||||
}
|
||||
|
||||
dst[i]->hw_reg = brw_vec8_grf((reg+i)*2, 0);
|
||||
}
|
||||
|
||||
if ((reg+nr)*2 > c->max_wm_grf)
|
||||
c->max_wm_grf = (reg+nr) * 2;
|
||||
}
|
||||
|
||||
|
||||
static void load_args(struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *inst)
|
||||
{
|
||||
unsigned thisinsn = inst - c->instruction;
|
||||
unsigned i,j;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
struct brw_wm_ref *ref = inst->src[i][j];
|
||||
|
||||
if (ref) {
|
||||
if (!ref->value->resident) {
|
||||
/* Need to bring the value in from scratch space. The code for
|
||||
* this will be done in brw_wm_emit.c, here we just do the
|
||||
* register allocation and mark the ref as requiring a fill.
|
||||
*/
|
||||
unsigned reg = search_contiguous_regs(c, 1, thisinsn);
|
||||
|
||||
c->pass2_grf[reg].value = ref->value;
|
||||
c->pass2_grf[reg].nextuse = thisinsn;
|
||||
|
||||
ref->value->resident = &c->pass2_grf[reg];
|
||||
|
||||
/* Note that a fill is required:
|
||||
*/
|
||||
ref->unspill_reg = reg*2;
|
||||
}
|
||||
|
||||
/* Adjust the hw_reg to point at the value's current location:
|
||||
*/
|
||||
assert(ref->value == ref->value->resident->value);
|
||||
ref->hw_reg.nr += (ref->value->resident - c->pass2_grf) * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Step 3: Work forwards once again. Perform register allocations,
|
||||
* taking into account instructions like TEX which require contiguous
|
||||
* result registers. Where necessary spill registers to scratch space
|
||||
* and reload later.
|
||||
*/
|
||||
void brw_wm_pass2( struct brw_wm_compile *c )
|
||||
{
|
||||
unsigned insn;
|
||||
unsigned i;
|
||||
|
||||
init_registers(c);
|
||||
|
||||
for (insn = 0; insn < c->nr_insns; insn++) {
|
||||
struct brw_wm_instruction *inst = &c->instruction[insn];
|
||||
|
||||
/* Update registers' nextuse values:
|
||||
*/
|
||||
update_register_usage(c, insn);
|
||||
|
||||
/* May need to unspill some args.
|
||||
*/
|
||||
load_args(c, inst);
|
||||
|
||||
/* Allocate registers to hold results:
|
||||
*/
|
||||
switch (inst->opcode) {
|
||||
case OPCODE_TEX:
|
||||
case OPCODE_TXB:
|
||||
case OPCODE_TXP:
|
||||
alloc_contiguous_dest(c, inst->dst, 4, insn);
|
||||
break;
|
||||
|
||||
default:
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (inst->writemask & (1<<i)) {
|
||||
assert(inst->dst[i]);
|
||||
alloc_contiguous_dest(c, &inst->dst[i], 1, insn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (TEST_DST_SPILLS && inst->opcode != WM_PIXELXY)
|
||||
for (i = 0; i < 4; i++)
|
||||
if (inst->dst[i])
|
||||
spill_value(c, inst->dst[i]);
|
||||
|
||||
}
|
||||
|
||||
if (BRW_DEBUG & DEBUG_WM) {
|
||||
brw_wm_print_program(c, "pass2");
|
||||
}
|
||||
|
||||
c->state = PASS2_DONE;
|
||||
|
||||
if (BRW_DEBUG & DEBUG_WM) {
|
||||
brw_wm_print_program(c, "pass2/done");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue