i965: Remove the old ARB_fragment_program backend.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -74,13 +74,7 @@ i965_C_FILES = \
|
||||
brw_vs_surface_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_pass0.c \
|
||||
brw_wm_pass1.c \
|
||||
brw_wm_pass2.c \
|
||||
brw_wm_sampler_state.c \
|
||||
brw_wm_state.c \
|
||||
brw_wm_surface_state.c \
|
||||
|
@@ -39,52 +39,6 @@
|
||||
|
||||
#include "glsl/ralloc.h"
|
||||
|
||||
/** Return number of src args for given instruction */
|
||||
GLuint brw_wm_nr_args( GLuint opcode )
|
||||
{
|
||||
switch (opcode) {
|
||||
case WM_FRONTFACING:
|
||||
case WM_PIXELXY:
|
||||
return 0;
|
||||
case WM_CINTERP:
|
||||
case WM_WPOSXY:
|
||||
case WM_DELTAXY:
|
||||
return 1;
|
||||
case WM_LINTERP:
|
||||
case WM_PIXELW:
|
||||
return 2;
|
||||
case WM_FB_WRITE:
|
||||
case WM_PINTERP:
|
||||
return 3;
|
||||
default:
|
||||
assert(opcode < MAX_OPCODE);
|
||||
return _mesa_num_inst_src_regs(opcode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLuint brw_wm_is_scalar_result( GLuint opcode )
|
||||
{
|
||||
switch (opcode) {
|
||||
case OPCODE_COS:
|
||||
case OPCODE_EX2:
|
||||
case OPCODE_LG2:
|
||||
case OPCODE_POW:
|
||||
case OPCODE_RCP:
|
||||
case OPCODE_RSQ:
|
||||
case OPCODE_SIN:
|
||||
case OPCODE_DP2:
|
||||
case OPCODE_DP3:
|
||||
case OPCODE_DP4:
|
||||
case OPCODE_DPH:
|
||||
case OPCODE_DST:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a bitfield where bit n is set if barycentric interpolation mode n
|
||||
* (see enum brw_wm_barycentric_interp_mode) is needed by the fragment shader.
|
||||
@@ -273,15 +227,7 @@ bool do_wm_prog(struct brw_context *brw,
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
void *instruction = c->instruction;
|
||||
void *prog_instructions = c->prog_instructions;
|
||||
void *vreg = c->vreg;
|
||||
void *refs = c->refs;
|
||||
memset(c, 0, sizeof(*brw->wm.compile_data));
|
||||
c->instruction = instruction;
|
||||
c->prog_instructions = prog_instructions;
|
||||
c->vreg = vreg;
|
||||
c->refs = refs;
|
||||
}
|
||||
|
||||
/* Allocate the references to the uniforms that will end up in the
|
||||
@@ -308,7 +254,6 @@ bool do_wm_prog(struct brw_context *brw,
|
||||
memcpy(&c->key, key, sizeof(*key));
|
||||
|
||||
c->fp = fp;
|
||||
c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
|
||||
|
||||
brw_init_compile(brw, &c->func, c);
|
||||
|
||||
|
@@ -40,8 +40,6 @@
|
||||
#include "brw_eu.h"
|
||||
#include "brw_program.h"
|
||||
|
||||
#define SATURATE (1<<5)
|
||||
|
||||
/* A big lookup table is used to figure out which and how many
|
||||
* additional regs will inserted before the main payload in the WM
|
||||
* program execution. These mainly relate to depth and stencil
|
||||
@@ -78,112 +76,6 @@ struct brw_wm_prog_key {
|
||||
struct brw_sampler_prog_key_data tex;
|
||||
};
|
||||
|
||||
|
||||
/* A bit of a glossary:
|
||||
*
|
||||
* brw_wm_value: A computed value or program input. Values are
|
||||
* constant, they are created once and are never modified. When a
|
||||
* fragment program register is written or overwritten, new values are
|
||||
* created fresh, preserving the rule that values are constant.
|
||||
*
|
||||
* brw_wm_ref: A reference to a value. Wherever a value used is by an
|
||||
* instruction or as a program output, that is tracked with an
|
||||
* instance of this struct. All references to a value occur after it
|
||||
* is created. After the last reference, a value is dead and can be
|
||||
* discarded.
|
||||
*
|
||||
* brw_wm_grf: Represents a physical hardware register. May be either
|
||||
* empty or hold a value. Register allocation is the process of
|
||||
* assigning values to grf registers. This occurs in pass2 and the
|
||||
* brw_wm_grf struct is not used before that.
|
||||
*
|
||||
* Fragment program registers: These are time-varying constructs that
|
||||
* are hard to reason about and which we translate away in pass0. A
|
||||
* single fragment program register element (eg. temp[0].x) will be
|
||||
* translated to one or more brw_wm_value structs, one for each time
|
||||
* that temp[0].x is written to during the program.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* Used in pass2 to track register allocation.
|
||||
*/
|
||||
struct brw_wm_grf {
|
||||
struct brw_wm_value *value;
|
||||
GLuint nextuse;
|
||||
};
|
||||
|
||||
struct brw_wm_value {
|
||||
struct brw_reg hw_reg; /* emitted to this reg, may not always be there */
|
||||
struct brw_wm_ref *lastuse;
|
||||
struct brw_wm_grf *resident;
|
||||
GLuint contributes_to_output:1;
|
||||
GLuint spill_slot:16; /* if non-zero, spill immediately after calculation */
|
||||
};
|
||||
|
||||
struct brw_wm_ref {
|
||||
struct brw_reg hw_reg; /* nr filled in in pass2, everything else, pass0 */
|
||||
struct brw_wm_value *value;
|
||||
struct brw_wm_ref *prevuse;
|
||||
GLuint unspill_reg:7; /* unspill to reg */
|
||||
GLuint emitted:1;
|
||||
GLuint insn:24;
|
||||
};
|
||||
|
||||
struct brw_wm_constref {
|
||||
const struct brw_wm_ref *ref;
|
||||
GLfloat constval;
|
||||
};
|
||||
|
||||
|
||||
struct brw_wm_instruction {
|
||||
struct brw_wm_value *dst[4];
|
||||
struct brw_wm_ref *src[3][4];
|
||||
GLuint opcode:8;
|
||||
GLuint saturate:1;
|
||||
GLuint writemask:4;
|
||||
GLuint tex_unit:4; /* texture unit for TEX, TXD, TXP instructions */
|
||||
GLuint tex_idx:4; /* TEXTURE_1D,2D,3D,CUBE,RECT_INDEX source target */
|
||||
GLuint tex_shadow:1; /* do shadow comparison? */
|
||||
GLuint eot:1; /* End of thread indicator for FB_WRITE*/
|
||||
GLuint target:10; /* target binding table index for FB_WRITE*/
|
||||
};
|
||||
|
||||
|
||||
#define BRW_WM_MAX_INSN (MAX_PROGRAM_INSTRUCTIONS*3 + FRAG_ATTRIB_MAX + 3)
|
||||
#define BRW_WM_MAX_GRF 128 /* hardware limit */
|
||||
#define BRW_WM_MAX_VREG (BRW_WM_MAX_INSN * 4)
|
||||
#define BRW_WM_MAX_REF (BRW_WM_MAX_INSN * 12)
|
||||
#define BRW_WM_MAX_PARAM 256
|
||||
#define BRW_WM_MAX_CONST 256
|
||||
#define BRW_WM_MAX_SUBROUTINE 16
|
||||
|
||||
/* used in masks next to WRITEMASK_*. */
|
||||
#define SATURATE (1<<5)
|
||||
|
||||
|
||||
/* New opcodes to track internal operations required for WM unit.
|
||||
* These are added early so that the registers used can be tracked,
|
||||
* freed and reused like those of other instructions.
|
||||
*/
|
||||
#define WM_PIXELXY (MAX_OPCODE)
|
||||
#define WM_DELTAXY (MAX_OPCODE + 1)
|
||||
#define WM_PIXELW (MAX_OPCODE + 2)
|
||||
#define WM_LINTERP (MAX_OPCODE + 3)
|
||||
#define WM_PINTERP (MAX_OPCODE + 4)
|
||||
#define WM_CINTERP (MAX_OPCODE + 5)
|
||||
#define WM_WPOSXY (MAX_OPCODE + 6)
|
||||
#define WM_FB_WRITE (MAX_OPCODE + 7)
|
||||
#define WM_FRONTFACING (MAX_OPCODE + 8)
|
||||
#define MAX_WM_OPCODE (MAX_OPCODE + 9)
|
||||
|
||||
#define PROGRAM_PAYLOAD (PROGRAM_FILE_MAX)
|
||||
#define NUM_FILES (PROGRAM_PAYLOAD + 1)
|
||||
|
||||
#define PAYLOAD_DEPTH (FRAG_ATTRIB_MAX)
|
||||
#define PAYLOAD_W (FRAG_ATTRIB_MAX + 1)
|
||||
#define PAYLOAD_FP_REG_MAX (FRAG_ATTRIB_MAX + 2)
|
||||
|
||||
struct brw_wm_compile {
|
||||
struct brw_compile func;
|
||||
struct brw_wm_prog_key key;
|
||||
@@ -191,13 +83,6 @@ struct brw_wm_compile {
|
||||
|
||||
struct brw_fragment_program *fp;
|
||||
|
||||
GLfloat (*env_param)[4];
|
||||
|
||||
enum {
|
||||
START,
|
||||
PASS2_DONE
|
||||
} state;
|
||||
|
||||
uint8_t source_depth_reg;
|
||||
uint8_t source_w_reg;
|
||||
uint8_t aa_dest_stencil_reg;
|
||||
@@ -208,266 +93,17 @@ struct brw_wm_compile {
|
||||
GLuint source_depth_to_render_target:1;
|
||||
GLuint runtime_check_aads_emit:1;
|
||||
|
||||
/* Initial pass - translate fp instructions to fp instructions,
|
||||
* simplifying and adding instructions for interpolation and
|
||||
* framebuffer writes.
|
||||
*/
|
||||
struct prog_instruction *prog_instructions;
|
||||
GLuint nr_fp_insns;
|
||||
GLuint fp_temp;
|
||||
GLuint fp_interp_emitted;
|
||||
|
||||
struct prog_src_register pixel_xy;
|
||||
struct prog_src_register delta_xy;
|
||||
struct prog_src_register pixel_w;
|
||||
|
||||
|
||||
struct brw_wm_value *vreg;
|
||||
GLuint nr_vreg;
|
||||
|
||||
struct brw_wm_value creg[BRW_WM_MAX_PARAM];
|
||||
GLuint nr_creg;
|
||||
|
||||
struct {
|
||||
struct brw_wm_value depth[4]; /* includes r0/r1 */
|
||||
struct brw_wm_value input_interp[FRAG_ATTRIB_MAX];
|
||||
} payload;
|
||||
|
||||
|
||||
const struct brw_wm_ref *pass0_fp_reg[NUM_FILES][256][4];
|
||||
|
||||
struct brw_wm_ref undef_ref;
|
||||
struct brw_wm_value undef_value;
|
||||
|
||||
struct brw_wm_ref *refs;
|
||||
GLuint nr_refs;
|
||||
|
||||
struct brw_wm_instruction *instruction;
|
||||
GLuint nr_insns;
|
||||
|
||||
struct brw_wm_constref constref[BRW_WM_MAX_CONST];
|
||||
GLuint nr_constrefs;
|
||||
|
||||
struct brw_wm_grf pass2_grf[BRW_WM_MAX_GRF/2];
|
||||
|
||||
GLuint grf_limit;
|
||||
GLuint max_wm_grf;
|
||||
GLuint last_scratch;
|
||||
|
||||
GLuint cur_inst; /**< index of current instruction */
|
||||
|
||||
bool out_of_regs; /**< ran out of GRF registers? */
|
||||
|
||||
/** Mapping from Mesa registers to hardware registers */
|
||||
struct {
|
||||
bool inited;
|
||||
struct brw_reg reg;
|
||||
} wm_regs[NUM_FILES][256][4];
|
||||
|
||||
bool used_grf[BRW_WM_MAX_GRF];
|
||||
GLuint first_free_grf;
|
||||
struct brw_reg stack;
|
||||
struct brw_reg emit_mask_reg;
|
||||
GLuint tmp_regs[BRW_WM_MAX_GRF];
|
||||
GLuint tmp_index;
|
||||
GLuint tmp_max;
|
||||
GLuint subroutines[BRW_WM_MAX_SUBROUTINE];
|
||||
GLuint dispatch_width;
|
||||
|
||||
/** we may need up to 3 constants per instruction (if use_const_buffer) */
|
||||
struct {
|
||||
GLint index;
|
||||
struct brw_reg reg;
|
||||
} current_const[3];
|
||||
};
|
||||
|
||||
|
||||
/** Bits for prog_instruction::Aux field */
|
||||
#define INST_AUX_EOT 0x1
|
||||
#define INST_AUX_TARGET(T) (T << 1)
|
||||
#define INST_AUX_GET_TARGET(AUX) ((AUX) >> 1)
|
||||
|
||||
|
||||
GLuint brw_wm_nr_args( GLuint opcode );
|
||||
GLuint brw_wm_is_scalar_result( GLuint opcode );
|
||||
|
||||
void brw_wm_pass_fp( struct brw_wm_compile *c );
|
||||
void brw_wm_pass0( struct brw_wm_compile *c );
|
||||
void brw_wm_pass1( struct brw_wm_compile *c );
|
||||
void brw_wm_pass2( struct brw_wm_compile *c );
|
||||
void brw_wm_emit( struct brw_wm_compile *c );
|
||||
bool brw_wm_arg_can_be_immediate(enum prog_opcode, int arg);
|
||||
void brw_wm_print_value( struct brw_wm_compile *c,
|
||||
struct brw_wm_value *value );
|
||||
|
||||
void brw_wm_print_ref( struct brw_wm_compile *c,
|
||||
struct brw_wm_ref *ref );
|
||||
|
||||
void brw_wm_print_insn( struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *inst );
|
||||
|
||||
void brw_wm_print_program( struct brw_wm_compile *c,
|
||||
const char *stage );
|
||||
|
||||
void brw_wm_lookup_iz(struct intel_context *intel,
|
||||
struct brw_wm_compile *c);
|
||||
|
||||
bool brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c,
|
||||
struct gl_shader_program *prog);
|
||||
|
||||
/* brw_wm_emit.c */
|
||||
void emit_alu1(struct brw_compile *p,
|
||||
struct brw_instruction *(*func)(struct brw_compile *,
|
||||
struct brw_reg,
|
||||
struct brw_reg),
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0);
|
||||
void emit_alu2(struct brw_compile *p,
|
||||
struct brw_instruction *(*func)(struct brw_compile *,
|
||||
struct brw_reg,
|
||||
struct brw_reg,
|
||||
struct brw_reg),
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1);
|
||||
void emit_cinterp(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0);
|
||||
void emit_cmp(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1,
|
||||
const struct brw_reg *arg2);
|
||||
void emit_ddxy(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
bool is_ddx,
|
||||
const struct brw_reg *arg0,
|
||||
bool negate_value);
|
||||
void emit_delta_xy(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0);
|
||||
void emit_dp2(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1);
|
||||
void emit_dp3(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1);
|
||||
void emit_dp4(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1);
|
||||
void emit_dph(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1);
|
||||
void emit_fb_write(struct brw_wm_compile *c,
|
||||
struct brw_reg *arg0,
|
||||
struct brw_reg *arg1,
|
||||
struct brw_reg *arg2,
|
||||
GLuint target,
|
||||
GLuint eot);
|
||||
void emit_frontfacing(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask);
|
||||
void emit_linterp(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *deltas);
|
||||
void emit_lrp(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1,
|
||||
const struct brw_reg *arg2);
|
||||
void emit_mad(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1,
|
||||
const struct brw_reg *arg2);
|
||||
void emit_math1(struct brw_wm_compile *c,
|
||||
GLuint function,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0);
|
||||
void emit_math2(struct brw_wm_compile *c,
|
||||
GLuint function,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1);
|
||||
void emit_min(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1);
|
||||
void emit_max(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1);
|
||||
void emit_pinterp(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *deltas,
|
||||
const struct brw_reg *w);
|
||||
void emit_pixel_xy(struct brw_wm_compile *c,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask);
|
||||
void emit_pixel_w(struct brw_wm_compile *c,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *deltas);
|
||||
void emit_sop(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
GLuint cond,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1);
|
||||
void emit_sign(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0);
|
||||
void emit_tex(struct brw_wm_compile *c,
|
||||
struct brw_reg *dst,
|
||||
GLuint dst_flags,
|
||||
struct brw_reg *arg,
|
||||
struct brw_reg depth_payload,
|
||||
GLuint tex_idx,
|
||||
GLuint sampler,
|
||||
bool shadow);
|
||||
void emit_txb(struct brw_wm_compile *c,
|
||||
struct brw_reg *dst,
|
||||
GLuint dst_flags,
|
||||
struct brw_reg *arg,
|
||||
struct brw_reg depth_payload,
|
||||
GLuint tex_idx,
|
||||
GLuint sampler);
|
||||
void emit_wpos_xy(struct brw_wm_compile *c,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0);
|
||||
void emit_xpd(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1);
|
||||
|
||||
GLboolean brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
|
||||
struct gl_shader *brw_new_shader(struct gl_context *ctx, GLuint name, GLuint type);
|
||||
struct gl_shader_program *brw_new_shader_program(struct gl_context *ctx, GLuint name);
|
||||
|
@@ -1,174 +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"
|
||||
|
||||
|
||||
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 )
|
||||
printf("undef");
|
||||
else if( value - c->vreg >= 0 &&
|
||||
value - c->vreg < BRW_WM_MAX_VREG)
|
||||
printf("r%ld", (long) (value - c->vreg));
|
||||
else if (value - c->creg >= 0 &&
|
||||
value - c->creg < BRW_WM_MAX_PARAM)
|
||||
printf("c%ld", (long) (value - c->creg));
|
||||
else if (value - c->payload.input_interp >= 0 &&
|
||||
value - c->payload.input_interp < FRAG_ATTRIB_MAX)
|
||||
printf("i%ld", (long) (value - c->payload.input_interp));
|
||||
else if (value - c->payload.depth >= 0 &&
|
||||
value - c->payload.depth < FRAG_ATTRIB_MAX)
|
||||
printf("d%ld", (long) (value - c->payload.depth));
|
||||
else
|
||||
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)
|
||||
printf("UNSPILL(%x)/", ref->value->spill_slot);
|
||||
|
||||
if (c->state >= PASS2_DONE)
|
||||
brw_print_reg(ref->hw_reg);
|
||||
else {
|
||||
printf("%s", hw_reg.negate ? "-" : "");
|
||||
printf("%s", hw_reg.abs ? "abs/" : "");
|
||||
brw_wm_print_value(c, ref->value);
|
||||
if ((hw_reg.nr&1) || hw_reg.subnr) {
|
||||
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 )
|
||||
{
|
||||
GLuint i, arg;
|
||||
GLuint nr_args = brw_wm_nr_args(inst->opcode);
|
||||
|
||||
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)
|
||||
printf("/SPILL(%x)",inst->dst[i]->spill_slot);
|
||||
}
|
||||
else
|
||||
printf("#");
|
||||
if (i < 3)
|
||||
printf(",");
|
||||
}
|
||||
printf("]");
|
||||
|
||||
if (inst->writemask != WRITEMASK_XYZW)
|
||||
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:
|
||||
printf(" = PIXELXY");
|
||||
break;
|
||||
case WM_DELTAXY:
|
||||
printf(" = DELTAXY");
|
||||
break;
|
||||
case WM_PIXELW:
|
||||
printf(" = PIXELW");
|
||||
break;
|
||||
case WM_WPOSXY:
|
||||
printf(" = WPOSXY");
|
||||
break;
|
||||
case WM_PINTERP:
|
||||
printf(" = PINTERP");
|
||||
break;
|
||||
case WM_LINTERP:
|
||||
printf(" = LINTERP");
|
||||
break;
|
||||
case WM_CINTERP:
|
||||
printf(" = CINTERP");
|
||||
break;
|
||||
case WM_FB_WRITE:
|
||||
printf(" = FB_WRITE");
|
||||
break;
|
||||
case WM_FRONTFACING:
|
||||
printf(" = FRONTFACING");
|
||||
break;
|
||||
default:
|
||||
printf(" = %s", _mesa_opcode_string(inst->opcode));
|
||||
break;
|
||||
}
|
||||
|
||||
if (inst->saturate)
|
||||
printf("_SAT");
|
||||
|
||||
for (arg = 0; arg < nr_args; arg++) {
|
||||
|
||||
printf(" [");
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (inst->src[arg][i]) {
|
||||
brw_wm_print_ref(c, inst->src[arg][i]);
|
||||
}
|
||||
else
|
||||
printf("%%");
|
||||
|
||||
if (i < 3)
|
||||
printf(",");
|
||||
else
|
||||
printf("]");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void brw_wm_print_program( struct brw_wm_compile *c,
|
||||
const char *stage )
|
||||
{
|
||||
GLuint insn;
|
||||
|
||||
printf("%s:\n", stage);
|
||||
for (insn = 0; insn < c->nr_insns; insn++)
|
||||
brw_wm_print_insn(c, &c->instruction[insn]);
|
||||
printf("\n");
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,445 +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"
|
||||
#include "program/prog_parameter.h"
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
static struct brw_wm_ref *get_ref( struct brw_wm_compile *c )
|
||||
{
|
||||
assert(c->nr_refs < BRW_WM_MAX_REF);
|
||||
memset(&c->refs[c->nr_refs], 0, sizeof(*c->refs));
|
||||
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);
|
||||
memset(&c->vreg[c->nr_vreg], 0, sizeof(*c->vreg));
|
||||
return &c->vreg[c->nr_vreg++];
|
||||
}
|
||||
|
||||
/** return pointer to a newly allocated instruction */
|
||||
static struct brw_wm_instruction *get_instruction( struct brw_wm_compile *c )
|
||||
{
|
||||
assert(c->nr_insns < BRW_WM_MAX_INSN);
|
||||
memset(&c->instruction[c->nr_insns], 0, sizeof(*c->instruction));
|
||||
return &c->instruction[c->nr_insns++];
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
/** Init the "undef" register */
|
||||
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;
|
||||
}
|
||||
|
||||
/** Set a FP register to a value */
|
||||
static void pass0_set_fpreg_value( struct brw_wm_compile *c,
|
||||
GLuint file,
|
||||
GLuint idx,
|
||||
GLuint 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;
|
||||
}
|
||||
|
||||
/** Set a FP register to a ref */
|
||||
static void pass0_set_fpreg_ref( struct brw_wm_compile *c,
|
||||
GLuint file,
|
||||
GLuint idx,
|
||||
GLuint 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 GLfloat *param_ptr )
|
||||
{
|
||||
GLuint i = c->prog_data.nr_params++;
|
||||
|
||||
if (i >= BRW_WM_MAX_PARAM) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Return a ref to a constant/literal value */
|
||||
static const struct brw_wm_ref *get_const_ref( struct brw_wm_compile *c,
|
||||
const GLfloat *constval )
|
||||
{
|
||||
GLuint 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) {
|
||||
GLuint 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 {
|
||||
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,
|
||||
GLuint file,
|
||||
GLuint idx,
|
||||
GLuint 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, parameters 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 invariant:
|
||||
*/
|
||||
ref = get_const_ref(c, &plist->ParameterValues[idx][component].f);
|
||||
break;
|
||||
|
||||
case PROGRAM_STATE_VAR:
|
||||
case PROGRAM_UNIFORM:
|
||||
/* These may change from run to run:
|
||||
*/
|
||||
ref = get_param_ref(c, &plist->ParameterValues[idx][component].f );
|
||||
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,
|
||||
GLuint writemask )
|
||||
{
|
||||
const struct prog_dst_register *dst = &inst->DstReg;
|
||||
GLuint 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 const struct brw_wm_ref *get_fp_src_reg_ref( struct brw_wm_compile *c,
|
||||
struct prog_src_register src,
|
||||
GLuint i )
|
||||
{
|
||||
GLuint component = GET_SWZ(src.Swizzle,i);
|
||||
const struct brw_wm_ref *src_ref;
|
||||
static const GLfloat const_zero = 0.0;
|
||||
static const GLfloat 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,
|
||||
GLuint 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.Negate & (1 << i))
|
||||
newref->hw_reg.negate ^= 1;
|
||||
|
||||
if (src.Abs) {
|
||||
newref->hw_reg.negate = 0;
|
||||
newref->hw_reg.abs = 1;
|
||||
}
|
||||
|
||||
return newref;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
translate_insn(struct brw_wm_compile *c,
|
||||
const struct prog_instruction *inst)
|
||||
{
|
||||
struct brw_wm_instruction *out = get_instruction(c);
|
||||
GLuint writemask = inst->DstReg.WriteMask;
|
||||
GLuint nr_args = brw_wm_nr_args(inst->Opcode);
|
||||
GLuint 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;
|
||||
out->tex_shadow = inst->TexShadow;
|
||||
out->eot = inst->Aux & INST_AUX_EOT;
|
||||
out->target = INST_AUX_GET_TARGET(inst->Aux);
|
||||
|
||||
/* 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:
|
||||
*/
|
||||
pass0_set_dst(c, out, inst, writemask);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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;
|
||||
GLuint writemask = inst->DstReg.WriteMask;
|
||||
struct brw_wm_ref *refs[4];
|
||||
GLuint i;
|
||||
|
||||
/* Get the effect of a MOV by manipulating our register table:
|
||||
* First get all refs, then assign refs. This ensures that "in-place"
|
||||
* swizzles such as:
|
||||
* MOV t, t.xxyx
|
||||
* are handled correctly. Previously, these two steps were done in
|
||||
* one loop and the above case was incorrectly handled.
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
refs[i] = get_new_ref(c, inst->SrcReg[0], i, NULL);
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (writemask & (1 << i)) {
|
||||
pass0_set_fpreg_ref( c, dst->File, dst->Index, i, refs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialize payload "registers".
|
||||
*/
|
||||
static void pass0_init_payload( struct brw_wm_compile *c )
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
GLuint j = i >= (c->nr_payload_regs + 1) / 2 ? 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 )
|
||||
{
|
||||
GLuint 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 (unlikely(INTEL_DEBUG & DEBUG_WM)) {
|
||||
brw_wm_print_program(c, "pass0");
|
||||
}
|
||||
}
|
@@ -1,298 +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"
|
||||
|
||||
|
||||
static GLuint get_tracked_mask(struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *inst)
|
||||
{
|
||||
GLuint 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,
|
||||
GLuint arg,
|
||||
GLuint readmask)
|
||||
{
|
||||
GLuint 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 GLuint get_texcoord_mask( GLuint tex_idx )
|
||||
{
|
||||
switch (tex_idx) {
|
||||
case TEXTURE_1D_INDEX:
|
||||
return WRITEMASK_X;
|
||||
case TEXTURE_2D_INDEX:
|
||||
case TEXTURE_1D_ARRAY_INDEX:
|
||||
case TEXTURE_EXTERNAL_INDEX:
|
||||
return WRITEMASK_XY;
|
||||
case TEXTURE_3D_INDEX:
|
||||
case TEXTURE_2D_ARRAY_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 )
|
||||
{
|
||||
GLint insn;
|
||||
|
||||
for (insn = c->nr_insns-1; insn >= 0; insn--) {
|
||||
struct brw_wm_instruction *inst = &c->instruction[insn];
|
||||
GLuint writemask;
|
||||
GLuint 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->source_depth_to_render_target && c->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) {
|
||||
GLuint 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:
|
||||
case OPCODE_SSG:
|
||||
case OPCODE_SWZ:
|
||||
case OPCODE_TRUNC:
|
||||
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_DDX:
|
||||
case OPCODE_DDY:
|
||||
read0 = 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:
|
||||
case OPCODE_TXP:
|
||||
read0 = get_texcoord_mask(inst->tex_idx);
|
||||
|
||||
if (inst->tex_shadow)
|
||||
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_DP2:
|
||||
read0 = WRITEMASK_XY;
|
||||
read1 = WRITEMASK_XY;
|
||||
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_DST:
|
||||
case WM_FRONTFACING:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
track_arg(c, inst, 0, read0);
|
||||
track_arg(c, inst, 1, read1);
|
||||
track_arg(c, inst, 2, read2);
|
||||
}
|
||||
|
||||
if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
|
||||
brw_wm_print_program(c, "pass1");
|
||||
}
|
||||
}
|
@@ -1,359 +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"
|
||||
|
||||
|
||||
/* 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,
|
||||
GLuint 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 )
|
||||
{
|
||||
struct brw_context *brw = c->func.brw;
|
||||
struct intel_context *intel = &brw->intel;
|
||||
GLuint nr_interp_regs = 0;
|
||||
GLuint i = 0;
|
||||
GLuint j;
|
||||
|
||||
for (j = 0; j < c->grf_limit; j++)
|
||||
c->pass2_grf[j].nextuse = BRW_WM_MAX_INSN;
|
||||
|
||||
for (j = 0; j < (c->nr_payload_regs + 1) / 2; j++)
|
||||
prealloc_reg(c, &c->payload.depth[j], i++);
|
||||
|
||||
for (j = 0; j < c->nr_creg; j++)
|
||||
prealloc_reg(c, &c->creg[j], i++);
|
||||
|
||||
if (intel->gen >= 6) {
|
||||
for (unsigned int j = 0; j < FRAG_ATTRIB_MAX; j++) {
|
||||
if (c->fp->program.Base.InputsRead & BITFIELD64_BIT(j)) {
|
||||
nr_interp_regs++;
|
||||
prealloc_reg(c, &c->payload.input_interp[j], i++);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < VERT_RESULT_MAX; j++) {
|
||||
/* Point size is packed into the header, not as a general attribute */
|
||||
if (j == VERT_RESULT_PSIZ)
|
||||
continue;
|
||||
|
||||
if (c->key.vp_outputs_written & BITFIELD64_BIT(j)) {
|
||||
int fp_index = _mesa_vert_result_to_frag_attrib(j);
|
||||
|
||||
nr_interp_regs++;
|
||||
|
||||
/* The back color slot is skipped when the front color is
|
||||
* also written to. In addition, some slots can be
|
||||
* written in the vertex shader and not read in the
|
||||
* fragment shader. So the register number must always be
|
||||
* incremented, mapped or not.
|
||||
*/
|
||||
if (fp_index >= 0)
|
||||
prealloc_reg(c, &c->payload.input_interp[fp_index], i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
assert(nr_interp_regs >= 1);
|
||||
}
|
||||
|
||||
|
||||
c->prog_data.first_curbe_grf = ALIGN(c->nr_payload_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,
|
||||
GLuint thisinsn)
|
||||
{
|
||||
GLuint 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) {
|
||||
const 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 GLuint search_contiguous_regs(struct brw_wm_compile *c,
|
||||
GLuint nr,
|
||||
GLuint thisinsn)
|
||||
{
|
||||
struct brw_wm_grf *grf = c->pass2_grf;
|
||||
GLuint furthest = 0;
|
||||
GLuint reg = 0;
|
||||
GLuint 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++) {
|
||||
GLuint 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[],
|
||||
GLuint nr,
|
||||
GLuint thisinsn)
|
||||
{
|
||||
GLuint reg = search_contiguous_regs(c, nr, thisinsn);
|
||||
GLuint 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)
|
||||
{
|
||||
GLuint thisinsn = inst - c->instruction;
|
||||
GLuint 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.
|
||||
*/
|
||||
GLuint 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 )
|
||||
{
|
||||
GLuint insn;
|
||||
GLuint 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 (unlikely(INTEL_DEBUG & DEBUG_WM)) {
|
||||
brw_wm_print_program(c, "pass2");
|
||||
}
|
||||
|
||||
c->state = PASS2_DONE;
|
||||
|
||||
if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
|
||||
brw_wm_print_program(c, "pass2/done");
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user