i965g: work in progress on fragment shaders
This commit is contained in:
@@ -132,6 +132,8 @@ struct brw_depth_stencil_state {
|
||||
struct brw_cc2 cc2;
|
||||
struct brw_cc3 cc3;
|
||||
struct brw_cc7 cc7;
|
||||
|
||||
unsigned iz_lookup;
|
||||
};
|
||||
|
||||
|
||||
@@ -164,7 +166,10 @@ struct brw_fragment_shader {
|
||||
const struct tgsi_token *tokens;
|
||||
struct tgsi_shader_info info;
|
||||
|
||||
GLboolean isGLSL;
|
||||
unsigned iz_lookup;
|
||||
|
||||
boolean uses_depth:1;
|
||||
boolean has_flow_control:1;
|
||||
|
||||
unsigned id;
|
||||
struct brw_winsys_buffer *const_buffer; /** Program constant buffer/surface */
|
||||
@@ -194,6 +199,7 @@ struct brw_fragment_shader {
|
||||
#define PIPE_NEW_COLOR_BUFFERS 0x40000
|
||||
#define PIPE_NEW_QUERY 0x80000
|
||||
#define PIPE_NEW_SCISSOR 0x100000
|
||||
#define PIPE_NEW_BOUND_TEXTURES 0x200000
|
||||
|
||||
|
||||
|
||||
@@ -487,7 +493,7 @@ struct brw_context
|
||||
const struct brw_rasterizer_state *rast;
|
||||
const struct brw_depth_stencil_state *zstencil;
|
||||
|
||||
const struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
|
||||
const struct brw_texture *texture[PIPE_MAX_SAMPLERS];
|
||||
const struct pipe_sampler *sampler[PIPE_MAX_SAMPLERS];
|
||||
unsigned num_textures;
|
||||
unsigned num_samplers;
|
||||
|
||||
@@ -150,22 +150,22 @@ const GLuint *brw_get_program( struct brw_compile *p,
|
||||
/**
|
||||
* For each OPCODE_BGNSUB we create one of these.
|
||||
*/
|
||||
struct brw_glsl_label
|
||||
struct brw_eu_label
|
||||
{
|
||||
GLuint label; /**< the label number */
|
||||
GLuint position; /**< the position of the brw instruction for this label */
|
||||
struct brw_glsl_label *next; /**< next in linked list */
|
||||
struct brw_eu_label *next; /**< next in linked list */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* For each OPCODE_CAL we create one of these.
|
||||
*/
|
||||
struct brw_glsl_call
|
||||
struct brw_eu_call
|
||||
{
|
||||
GLuint call_inst_pos; /**< location of the CAL instruction */
|
||||
GLuint label;
|
||||
struct brw_glsl_call *next; /**< next in linked list */
|
||||
struct brw_eu_call *next; /**< next in linked list */
|
||||
};
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ struct brw_glsl_call
|
||||
void
|
||||
brw_save_label(struct brw_compile *c, unsigned l, GLuint position)
|
||||
{
|
||||
struct brw_glsl_label *label = CALLOC_STRUCT(brw_glsl_label);
|
||||
struct brw_eu_label *label = CALLOC_STRUCT(brw_eu_label);
|
||||
label->label = l;
|
||||
label->position = position;
|
||||
label->next = c->first_label;
|
||||
@@ -189,7 +189,7 @@ brw_save_label(struct brw_compile *c, unsigned l, GLuint position)
|
||||
void
|
||||
brw_save_call(struct brw_compile *c, GLuint label, GLuint call_pos)
|
||||
{
|
||||
struct brw_glsl_call *call = CALLOC_STRUCT(brw_glsl_call);
|
||||
struct brw_eu_call *call = CALLOC_STRUCT(brw_eu_call);
|
||||
call->call_inst_pos = call_pos;
|
||||
call->label = label;
|
||||
call->next = c->first_call;
|
||||
@@ -203,7 +203,7 @@ brw_save_call(struct brw_compile *c, GLuint label, GLuint call_pos)
|
||||
static GLuint
|
||||
brw_lookup_label(struct brw_compile *c, unsigned l)
|
||||
{
|
||||
const struct brw_glsl_label *label;
|
||||
const struct brw_eu_label *label;
|
||||
for (label = c->first_label; label; label = label->next) {
|
||||
if (l == label->label) {
|
||||
return label->position;
|
||||
@@ -221,7 +221,7 @@ brw_lookup_label(struct brw_compile *c, unsigned l)
|
||||
void
|
||||
brw_resolve_cals(struct brw_compile *c)
|
||||
{
|
||||
const struct brw_glsl_call *call;
|
||||
const struct brw_eu_call *call;
|
||||
|
||||
for (call = c->first_call; call; call = call->next) {
|
||||
const GLuint sub_loc = brw_lookup_label(c, call->label);
|
||||
@@ -235,7 +235,7 @@ brw_resolve_cals(struct brw_compile *c)
|
||||
|
||||
/* free linked list of calls */
|
||||
{
|
||||
struct brw_glsl_call *call, *next;
|
||||
struct brw_eu_call *call, *next;
|
||||
for (call = c->first_call; call; call = next) {
|
||||
next = call->next;
|
||||
FREE(call);
|
||||
@@ -245,7 +245,7 @@ brw_resolve_cals(struct brw_compile *c)
|
||||
|
||||
/* free linked list of labels */
|
||||
{
|
||||
struct brw_glsl_label *label, *next;
|
||||
struct brw_eu_label *label, *next;
|
||||
for (label = c->first_label; label; label = next) {
|
||||
next = label->next;
|
||||
FREE(label);
|
||||
|
||||
@@ -109,8 +109,8 @@ struct brw_indirect {
|
||||
};
|
||||
|
||||
|
||||
struct brw_glsl_label;
|
||||
struct brw_glsl_call;
|
||||
struct brw_eu_label;
|
||||
struct brw_eu_call;
|
||||
|
||||
|
||||
|
||||
@@ -130,8 +130,8 @@ struct brw_compile {
|
||||
GLboolean single_program_flow;
|
||||
struct brw_context *brw;
|
||||
|
||||
struct brw_glsl_label *first_label; /**< linked list of labels */
|
||||
struct brw_glsl_call *first_call; /**< linked list of CALs */
|
||||
struct brw_eu_label *first_label; /**< linked list of labels */
|
||||
struct brw_eu_call *first_call; /**< linked list of CALs */
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
#include "brw_context.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
/* XXX: Fixme - include this to get IZ_ defines
|
||||
*/
|
||||
#include "brw_wm.h"
|
||||
|
||||
static unsigned brw_translate_compare_func(unsigned func)
|
||||
{
|
||||
switch (func) {
|
||||
@@ -55,13 +59,9 @@ static unsigned translate_stencil_op(unsigned op)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
brw_create_depth_stencil_state( struct pipe_context *pipe,
|
||||
const struct pipe_depth_stencil_alpha_state *templ )
|
||||
static void create_bcc_state( struct brw_depth_stencil_state *zstencil,
|
||||
const struct pipe_depth_stencil_alpha_state *templ )
|
||||
{
|
||||
struct brw_depth_stencil_state *zstencil = CALLOC_STRUCT(brw_depth_stencil_state);
|
||||
|
||||
if (templ->stencil[0].enabled) {
|
||||
zstencil->cc0.stencil_enable = 1;
|
||||
zstencil->cc0.stencil_func =
|
||||
@@ -108,6 +108,36 @@ brw_create_depth_stencil_state( struct pipe_context *pipe,
|
||||
zstencil->cc2.depth_test_function = brw_translate_compare_func(templ->depth.func);
|
||||
zstencil->cc2.depth_write_enable = templ->depth.writemask;
|
||||
}
|
||||
}
|
||||
|
||||
static void create_wm_iz_state( struct brw_depth_stencil_state *zstencil )
|
||||
{
|
||||
if (zstencil->cc3.alpha_test)
|
||||
zstencil->iz_lookup |= IZ_PS_KILL_ALPHATEST_BIT;
|
||||
|
||||
if (zstencil->cc2.depth_test)
|
||||
zstencil->iz_lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
|
||||
|
||||
if (zstencil->cc2.depth_write_enable)
|
||||
zstencil->iz_lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
|
||||
|
||||
if (zstencil->cc0.stencil_enable)
|
||||
zstencil->iz_lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
|
||||
|
||||
if (zstencil->cc0.stencil_write_enable)
|
||||
zstencil->iz_lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
brw_create_depth_stencil_state( struct pipe_context *pipe,
|
||||
const struct pipe_depth_stencil_alpha_state *templ )
|
||||
{
|
||||
struct brw_depth_stencil_state *zstencil = CALLOC_STRUCT(brw_depth_stencil_state);
|
||||
|
||||
create_bcc_state( zstencil, templ );
|
||||
create_wm_iz_state( zstencil );
|
||||
|
||||
return (void *)zstencil;
|
||||
}
|
||||
|
||||
@@ -64,3 +64,21 @@ calculate_line_stipple_rast()
|
||||
bls.bits1.inverse_repeat_count = tmpi;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
calculate_wm_lookup()
|
||||
{
|
||||
if (rast->fill_cw == PIPE_POLYGON_MODE_LINE &&
|
||||
rast->fill_ccw == PIPE_POLYGON_MODE_LINE) {
|
||||
line_aa = AA_ALWAYS;
|
||||
}
|
||||
else if (rast->fill_cw == PIPE_POLYGON_MODE_LINE ||
|
||||
rast->fill_ccw == PIPE_POLYGON_MODE_LINE) {
|
||||
line_aa = AA_SOMETIMES;
|
||||
}
|
||||
else {
|
||||
line_aa = AA_NEVER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ struct brw_rasterizer_state {
|
||||
*/
|
||||
struct brw_clip_prog_key clip_key;
|
||||
struct brw_line_stipple bls;
|
||||
unsigned unfilled_aa_line;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
* as flow conditionals, loops, subroutines.
|
||||
* Some GLSL shaders may use these features, others might not.
|
||||
*/
|
||||
GLboolean brw_wm_is_glsl(const struct brw_fragment_shader *fp)
|
||||
GLboolean brw_wm_has_flow_control(const struct brw_fragment_shader *fp)
|
||||
{
|
||||
return (fp->info.insn_count[TGSI_OPCODE_ARL] > 0 ||
|
||||
fp->info.insn_count[TGSI_OPCODE_IF] > 0 ||
|
||||
@@ -144,7 +144,7 @@ static void brwProgramStringNotify( struct brw_context *brw,
|
||||
if (newFP == curFP)
|
||||
brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
|
||||
newFP->id = brw->program_id++;
|
||||
newFP->isGLSL = brw_wm_is_glsl(fprog);
|
||||
newFP->has_flow_control = brw_wm_has_flow_control(fprog);
|
||||
}
|
||||
else if (target == GL_VERTEX_PROGRAM_ARB) {
|
||||
struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
|
||||
|
||||
@@ -64,6 +64,13 @@ struct brw_buffer
|
||||
boolean is_user_buffer;
|
||||
};
|
||||
|
||||
struct brw_texture
|
||||
{
|
||||
struct pipe_texture base;
|
||||
|
||||
ubyte shader_swizzle;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Cast wrappers
|
||||
|
||||
@@ -1013,8 +1013,6 @@ static struct brw_reg get_arg( struct brw_vs_compile *c,
|
||||
src->SrcRegister.SwizzleZ,
|
||||
src->SrcRegister.SwizzleW);
|
||||
|
||||
/* Note this is ok for non-swizzle instructions:
|
||||
*/
|
||||
reg.negate = src->SrcRegister.Negate ? 1 : 0;
|
||||
|
||||
/* XXX: abs, absneg
|
||||
|
||||
@@ -28,14 +28,17 @@
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
#include "pipe/p_error.h"
|
||||
|
||||
#include "tgsi/tgsi_info.h"
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_screen.h"
|
||||
#include "brw_util.h"
|
||||
#include "brw_wm.h"
|
||||
#include "brw_state.h"
|
||||
#include "brw_debug.h"
|
||||
#include "brw_pipe_rast.h"
|
||||
|
||||
|
||||
/** Return number of src args for given instruction */
|
||||
@@ -85,12 +88,12 @@ GLuint brw_wm_is_scalar_result( GLuint opcode )
|
||||
|
||||
|
||||
/**
|
||||
* Do GPU code generation for non-GLSL shader. non-GLSL shaders have
|
||||
* no flow control instructions so we can more readily do SSA-style
|
||||
* optimizations.
|
||||
* Do GPU code generation for shaders without flow control. Shaders
|
||||
* without flow control instructions can more readily be analysed for
|
||||
* SSA-style optimizations.
|
||||
*/
|
||||
static void
|
||||
brw_wm_non_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c)
|
||||
brw_wm_linear_shader_emit(struct brw_context *brw, struct brw_wm_compile *c)
|
||||
{
|
||||
/* Augment fragment program. Add instructions for pre- and
|
||||
* post-fragment-program tasks such as interpolation and fogging.
|
||||
@@ -136,7 +139,7 @@ brw_wm_non_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c)
|
||||
* Depending on the instructions used (i.e. flow control instructions)
|
||||
* we'll use one of two code generators.
|
||||
*/
|
||||
static void do_wm_prog( struct brw_context *brw,
|
||||
static int do_wm_prog( struct brw_context *brw,
|
||||
struct brw_fragment_shader *fp,
|
||||
struct brw_wm_prog_key *key)
|
||||
{
|
||||
@@ -153,7 +156,7 @@ static void do_wm_prog( struct brw_context *brw,
|
||||
* without triggering a segfault, no way to signal,
|
||||
* so just return.
|
||||
*/
|
||||
return;
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else {
|
||||
memset(c, 0, sizeof(*brw->wm.compile_data));
|
||||
@@ -166,19 +169,19 @@ static void do_wm_prog( struct brw_context *brw,
|
||||
brw_init_compile(brw, &c->func);
|
||||
|
||||
/* temporary sanity check assertion */
|
||||
assert(fp->isGLSL == brw_wm_is_glsl(&c->fp->program));
|
||||
assert(fp->has_flow_control == brw_wm_has_flow_control(c->fp));
|
||||
|
||||
/*
|
||||
* Shader which use GLSL features such as flow control are handled
|
||||
* differently from "simple" shaders.
|
||||
*/
|
||||
if (fp->isGLSL) {
|
||||
if (fp->has_flow_control) {
|
||||
c->dispatch_width = 8;
|
||||
brw_wm_glsl_emit(brw, c);
|
||||
brw_wm_branching_shader_emit(brw, c);
|
||||
}
|
||||
else {
|
||||
c->dispatch_width = 16;
|
||||
brw_wm_non_glsl_emit(brw, c);
|
||||
brw_wm_linear_shader_emit(brw, c);
|
||||
}
|
||||
|
||||
if (BRW_DEBUG & DEBUG_WM)
|
||||
@@ -195,6 +198,8 @@ static void do_wm_prog( struct brw_context *brw,
|
||||
program, program_size,
|
||||
&c->prog_data,
|
||||
&brw->wm.prog_data );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -202,71 +207,36 @@ static void do_wm_prog( struct brw_context *brw,
|
||||
static void brw_wm_populate_key( struct brw_context *brw,
|
||||
struct brw_wm_prog_key *key )
|
||||
{
|
||||
/* BRW_NEW_FRAGMENT_PROGRAM */
|
||||
const struct brw_fragment_program *fp = brw->curr.fragment_shader;
|
||||
GLboolean uses_depth = (fp->program.Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) != 0;
|
||||
GLuint lookup = 0;
|
||||
GLuint line_aa;
|
||||
GLuint i;
|
||||
unsigned lookup, line_aa;
|
||||
unsigned i;
|
||||
|
||||
memset(key, 0, sizeof(*key));
|
||||
|
||||
/* Build the index for table lookup
|
||||
/* PIPE_NEW_FRAGMENT_SHADER
|
||||
* PIPE_NEW_DEPTH_STENCIL_ALPHA
|
||||
*/
|
||||
/* _NEW_COLOR */
|
||||
if (fp->program.UsesKill ||
|
||||
ctx->Color.AlphaEnabled)
|
||||
lookup |= IZ_PS_KILL_ALPHATEST_BIT;
|
||||
lookup = (brw->curr.zstencil->iz_lookup |
|
||||
brw->curr.fragment_shader->iz_lookup);
|
||||
|
||||
if (fp->program.Base.OutputsWritten & (1<<FRAG_RESULT_DEPTH))
|
||||
lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
|
||||
|
||||
/* _NEW_DEPTH */
|
||||
if (ctx->Depth.Test)
|
||||
lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
|
||||
|
||||
if (ctx->Depth.Test &&
|
||||
ctx->Depth.Mask) /* ?? */
|
||||
lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
|
||||
|
||||
/* _NEW_STENCIL */
|
||||
if (ctx->Stencil._Enabled) {
|
||||
lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
|
||||
|
||||
if (ctx->Stencil.WriteMask[0] ||
|
||||
ctx->Stencil.WriteMask[ctx->Stencil._BackFace])
|
||||
lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
|
||||
}
|
||||
|
||||
line_aa = AA_NEVER;
|
||||
|
||||
/* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */
|
||||
if (ctx->Line.SmoothFlag) {
|
||||
if (brw->intel.reduced_primitive == GL_LINES) {
|
||||
line_aa = AA_ALWAYS;
|
||||
}
|
||||
else if (brw->intel.reduced_primitive == GL_TRIANGLES) {
|
||||
if (ctx->Polygon.FrontMode == GL_LINE) {
|
||||
line_aa = AA_SOMETIMES;
|
||||
|
||||
if (ctx->Polygon.BackMode == GL_LINE ||
|
||||
(ctx->Polygon.CullFlag &&
|
||||
ctx->Polygon.CullFaceMode == GL_BACK))
|
||||
line_aa = AA_ALWAYS;
|
||||
}
|
||||
else if (ctx->Polygon.BackMode == GL_LINE) {
|
||||
line_aa = AA_SOMETIMES;
|
||||
|
||||
if ((ctx->Polygon.CullFlag &&
|
||||
ctx->Polygon.CullFaceMode == GL_FRONT))
|
||||
line_aa = AA_ALWAYS;
|
||||
}
|
||||
}
|
||||
/* PIPE_NEW_RAST
|
||||
* BRW_NEW_REDUCED_PRIMITIVE
|
||||
*/
|
||||
switch (brw->reduced_primitive) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
line_aa = AA_NEVER;
|
||||
break;
|
||||
case PIPE_PRIM_LINES:
|
||||
line_aa = AA_ALWAYS;
|
||||
break;
|
||||
default:
|
||||
line_aa = brw->curr.rast->unfilled_aa_line;
|
||||
break;
|
||||
}
|
||||
|
||||
brw_wm_lookup_iz(line_aa,
|
||||
lookup,
|
||||
uses_depth,
|
||||
brw->curr.fragment_shader->uses_depth,
|
||||
key);
|
||||
|
||||
/* Revisit this, figure out if it's really useful, and either push
|
||||
@@ -276,54 +246,39 @@ static void brw_wm_populate_key( struct brw_context *brw,
|
||||
key->proj_attrib_mask = ~0; /*brw->wm.input_size_masks[4-1];*/
|
||||
|
||||
/* PIPE_NEW_RAST */
|
||||
key->flat_shade = brw->rast.flat_shade;
|
||||
key->flat_shade = brw->curr.rast->templ.flatshade;
|
||||
|
||||
/* This can be determined by looking at the INTERP mode each input decl.
|
||||
*/
|
||||
key->linear_color = 0;
|
||||
key->linear_attrib_mask = 0;
|
||||
|
||||
/* _NEW_TEXTURE */
|
||||
for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
|
||||
if (i < brw->nr_textures) {
|
||||
const struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
|
||||
const struct gl_texture_object *t = unit->_Current;
|
||||
const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
|
||||
/* PIPE_NEW_BOUND_TEXTURES */
|
||||
for (i = 0; i < brw->curr.num_textures; i++) {
|
||||
const struct brw_texture *tex = brw->curr.texture[i];
|
||||
|
||||
if (img->InternalFormat == GL_YCBCR_MESA) {
|
||||
key->yuvtex_mask |= 1 << i;
|
||||
if (img->TexFormat->MesaFormat == MESA_FORMAT_YCBCR)
|
||||
key->yuvtex_swap_mask |= 1 << i;
|
||||
}
|
||||
if (tex->base.format == PIPE_FORMAT_YCBCR)
|
||||
key->yuvtex_mask |= 1 << i;
|
||||
|
||||
key->tex_swizzles[i] = t->_Swizzle;
|
||||
|
||||
if (0)
|
||||
key->shadowtex_mask |= 1<<i;
|
||||
}
|
||||
else {
|
||||
key->tex_swizzles[i] = SWIZZLE_NOOP;
|
||||
}
|
||||
}
|
||||
if (tex->base.format == PIPE_FORMAT_YCBCR_REV)
|
||||
key->yuvtex_swap_mask |= 1 << i;
|
||||
|
||||
|
||||
/* _NEW_FRAMEBUFFER */
|
||||
if (brw->intel.driDrawable != NULL) {
|
||||
key->drawable_height = brw->fb.cbufs[0].height;
|
||||
/* XXX: shadow texture
|
||||
*/
|
||||
/* key->shadowtex_mask |= 1<<i; */
|
||||
}
|
||||
|
||||
/* CACHE_NEW_VS_PROG */
|
||||
key->vp_nr_outputs_written = brw->vs.prog_data->nr_outputs_written;
|
||||
key->vp_nr_outputs = brw->vs.prog_data->nr_outputs;
|
||||
|
||||
/* The unique fragment program ID */
|
||||
key->program_string_id = fp->id;
|
||||
key->program_string_id = brw->curr.fragment_shader->id;
|
||||
}
|
||||
|
||||
|
||||
static void brw_prepare_wm_prog(struct brw_context *brw)
|
||||
static int brw_prepare_wm_prog(struct brw_context *brw)
|
||||
{
|
||||
struct brw_wm_prog_key key;
|
||||
struct brw_fragment_program *fp = (struct brw_fragment_program *)
|
||||
brw->fragment_program;
|
||||
struct brw_fragment_shader *fs = brw->curr.fragment_shader;
|
||||
|
||||
brw_wm_populate_key(brw, &key);
|
||||
|
||||
@@ -335,23 +290,19 @@ static void brw_prepare_wm_prog(struct brw_context *brw)
|
||||
NULL, 0,
|
||||
&brw->wm.prog_data);
|
||||
if (brw->wm.prog_bo == NULL)
|
||||
do_wm_prog(brw, fp, &key);
|
||||
return do_wm_prog(brw, fs, &key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_wm_prog = {
|
||||
.dirty = {
|
||||
.mesa = (_NEW_COLOR |
|
||||
_NEW_DEPTH |
|
||||
_NEW_HINT |
|
||||
_NEW_STENCIL |
|
||||
_NEW_POLYGON |
|
||||
_NEW_LINE |
|
||||
_NEW_LIGHT |
|
||||
_NEW_BUFFERS |
|
||||
_NEW_TEXTURE),
|
||||
.brw = (BRW_NEW_FRAGMENT_PROGRAM |
|
||||
BRW_NEW_WM_INPUT_DIMENSIONS |
|
||||
.mesa = (PIPE_NEW_FRAGMENT_SHADER |
|
||||
PIPE_NEW_DEPTH_STENCIL_ALPHA |
|
||||
PIPE_NEW_RAST |
|
||||
PIPE_NEW_BOUND_TEXTURES),
|
||||
.brw = (BRW_NEW_WM_INPUT_DIMENSIONS |
|
||||
BRW_NEW_REDUCED_PRIMITIVE),
|
||||
.cache = CACHE_NEW_VS_PROG,
|
||||
},
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
#ifndef BRW_WM_H
|
||||
#define BRW_WM_H
|
||||
|
||||
#include "tgsi/tgsi_ureg.h"
|
||||
#include "tgsi/tgsi_ureg_parse.h"
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
|
||||
@@ -59,8 +56,8 @@
|
||||
#define AA_ALWAYS 2
|
||||
|
||||
struct brw_wm_prog_key {
|
||||
unsigned proj_attrib_mask; /**< one bit per fragment program attribute */
|
||||
unsigned linear_attrib_mask:1; /**< linear interpolation vs perspective interp */
|
||||
unsigned proj_attrib_mask; /**< one bit per fragment program attribute */
|
||||
unsigned linear_attrib_mask; /**< linear interpolation vs perspective interp */
|
||||
|
||||
GLuint source_depth_reg:3;
|
||||
GLuint aa_dest_stencil_reg:3;
|
||||
@@ -75,11 +72,10 @@ struct brw_wm_prog_key {
|
||||
GLuint yuvtex_mask:16;
|
||||
GLuint yuvtex_swap_mask:16; /* UV swaped */
|
||||
|
||||
GLuint tex_swizzles[BRW_MAX_TEX_UNIT];
|
||||
GLuint vp_nr_outputs:6;
|
||||
GLuint nr_cbufs:3;
|
||||
|
||||
GLuint program_string_id:32;
|
||||
|
||||
GLuint vp_nr_outputs_written;
|
||||
GLuint program_string_id;
|
||||
};
|
||||
|
||||
|
||||
@@ -146,9 +142,8 @@ struct brw_wm_instruction {
|
||||
GLuint opcode:8;
|
||||
GLuint saturate:1;
|
||||
GLuint writemask:4;
|
||||
GLuint tex_unit:4; /* texture unit for TEX, TXD, TXP instructions */
|
||||
GLuint tex_idx:3; /* TEXTURE_1D,2D,3D,CUBE,RECT_INDEX source target */
|
||||
GLuint tex_shadow:1; /* do shadow comparison? */
|
||||
GLuint tex_unit:4; /* texture/sampler unit for texture instructions */
|
||||
GLuint tex_target:4; /* TGSI_TEXTURE_x for texture instructions*/
|
||||
GLuint eot:1; /* End of thread indicator for FB_WRITE*/
|
||||
GLuint target:10; /* target binding table index for FB_WRITE*/
|
||||
};
|
||||
@@ -180,15 +175,17 @@ struct brw_wm_instruction {
|
||||
#define WM_FRONTFACING (MAX_OPCODE + 8)
|
||||
#define MAX_WM_OPCODE (MAX_OPCODE + 9)
|
||||
|
||||
#define PROGRAM_PAYLOAD (TGSI_FILE_COUNT)
|
||||
#define PAYLOAD_DEPTH (FRAG_ATTRIB_MAX)
|
||||
#define BRW_FILE_PAYLOAD (TGSI_FILE_COUNT)
|
||||
#define PAYLOAD_DEPTH (FRAG_ATTRIB_MAX) /* ?? */
|
||||
|
||||
struct brw_passfp_program;
|
||||
|
||||
struct brw_wm_compile {
|
||||
struct brw_compile func;
|
||||
struct brw_wm_prog_key key;
|
||||
struct brw_wm_prog_data prog_data;
|
||||
|
||||
struct brw_fragment_program *fp;
|
||||
struct brw_fragment_shader *fp;
|
||||
|
||||
GLfloat (*env_param)[4];
|
||||
|
||||
@@ -201,15 +198,7 @@ struct brw_wm_compile {
|
||||
* simplifying and adding instructions for interpolation and
|
||||
* framebuffer writes.
|
||||
*/
|
||||
struct ureg_instruction prog_instructions[BRW_WM_MAX_INSN];
|
||||
GLuint nr_fp_insns;
|
||||
GLuint fp_temp;
|
||||
GLuint fp_interp_emitted;
|
||||
GLuint fp_fragcolor_emitted;
|
||||
|
||||
struct ureg_src pixel_xy;
|
||||
struct ureg_src delta_xy;
|
||||
struct ureg_src pixel_w;
|
||||
struct brw_passfp_program *pass_fp;
|
||||
|
||||
|
||||
struct brw_wm_value vreg[BRW_WM_MAX_VREG];
|
||||
@@ -298,8 +287,8 @@ void brw_wm_lookup_iz( GLuint line_aa,
|
||||
GLboolean ps_uses_depth,
|
||||
struct brw_wm_prog_key *key );
|
||||
|
||||
//GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp);
|
||||
void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c);
|
||||
GLboolean brw_wm_has_flow_control(const struct brw_fragment_shader *fp);
|
||||
void brw_wm_branching_shader_emit(struct brw_context *brw, struct brw_wm_compile *c);
|
||||
|
||||
void emit_ddxy(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "tgsi/tgsi_info.h"
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_wm.h"
|
||||
@@ -49,10 +50,10 @@ void brw_wm_print_value( struct brw_wm_compile *c,
|
||||
value - c->creg < BRW_WM_MAX_PARAM)
|
||||
debug_printf("c%d", value - c->creg);
|
||||
else if (value - c->payload.input_interp >= 0 &&
|
||||
value - c->payload.input_interp < FRAG_ATTRIB_MAX)
|
||||
value - c->payload.input_interp < PIPE_MAX_SHADER_INPUTS)
|
||||
debug_printf("i%d", value - c->payload.input_interp);
|
||||
else if (value - c->payload.depth >= 0 &&
|
||||
value - c->payload.depth < FRAG_ATTRIB_MAX)
|
||||
value - c->payload.depth < PIPE_MAX_SHADER_INPUTS)
|
||||
debug_printf("d%d", value - c->payload.depth);
|
||||
else
|
||||
debug_printf("?");
|
||||
@@ -100,10 +101,10 @@ void brw_wm_print_insn( struct brw_wm_compile *c,
|
||||
|
||||
if (inst->writemask != BRW_WRITEMASK_XYZW)
|
||||
debug_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" : "");
|
||||
(inst->writemask & BRW_WRITEMASK_X) ? "x" : "",
|
||||
(inst->writemask & BRW_WRITEMASK_Y) ? "y" : "",
|
||||
(inst->writemask & BRW_WRITEMASK_Z) ? "z" : "",
|
||||
(inst->writemask & BRW_WRITEMASK_W) ? "w" : "");
|
||||
|
||||
switch (inst->opcode) {
|
||||
case WM_PIXELXY:
|
||||
@@ -134,7 +135,7 @@ void brw_wm_print_insn( struct brw_wm_compile *c,
|
||||
debug_printf(" = FRONTFACING");
|
||||
break;
|
||||
default:
|
||||
debug_printf(" = %s", _mesa_opcode_string(inst->opcode));
|
||||
debug_printf(" = %s", tgsi_get_opcode_info(inst->opcode)->mnemonic);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,13 @@
|
||||
* Authors:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "util/u_math.h"
|
||||
#include "tgsi/tgsi_info.h"
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_wm.h"
|
||||
#include "brw_debug.h"
|
||||
|
||||
/* Not quite sure how correct this is - need to understand horiz
|
||||
* vs. vertical strides a little better.
|
||||
@@ -45,15 +48,15 @@ static INLINE struct brw_reg sechalf( struct brw_reg reg )
|
||||
|
||||
/* Payload R0:
|
||||
*
|
||||
* R0.0 -- pixel mask, one bit for each of 4 pixels in 4 tiles,
|
||||
* R0.0 -- pixel mask, one bit for each of 4 pixels in 4 quads,
|
||||
* corresponding to each of the 16 execution channels.
|
||||
* R0.1..8 -- ?
|
||||
* R1.0 -- triangle vertex 0.X
|
||||
* R1.1 -- triangle vertex 0.Y
|
||||
* R1.2 -- tile 0 x,y coords (2 packed uwords)
|
||||
* R1.3 -- tile 1 x,y coords (2 packed uwords)
|
||||
* R1.4 -- tile 2 x,y coords (2 packed uwords)
|
||||
* R1.5 -- tile 3 x,y coords (2 packed uwords)
|
||||
* R1.2 -- quad 0 x,y coords (2 packed uwords)
|
||||
* R1.3 -- quad 1 x,y coords (2 packed uwords)
|
||||
* R1.4 -- quad 2 x,y coords (2 packed uwords)
|
||||
* R1.5 -- quad 3 x,y coords (2 packed uwords)
|
||||
* R1.6 -- ?
|
||||
* R1.7 -- ?
|
||||
* R1.8 -- ?
|
||||
@@ -134,11 +137,17 @@ static void emit_wpos_xy(struct brw_wm_compile *c,
|
||||
/* XXX: is this needed any more, or is this a NOOP?
|
||||
*/
|
||||
if (mask & BRW_WRITEMASK_Y) {
|
||||
#if 0
|
||||
/* Y' = height - 1 - Y */
|
||||
brw_ADD(p,
|
||||
dst[1],
|
||||
negate(retype(arg0[1], BRW_REGISTER_TYPE_W)),
|
||||
brw_imm_d(c->key.drawable_height - 1));
|
||||
#else
|
||||
brw_MOV(p,
|
||||
dst[0],
|
||||
retype(arg0[0], BRW_REGISTER_TYPE_W));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,28 +288,28 @@ static void emit_frontfacing( struct brw_compile *p,
|
||||
/* For OPCODE_DDX and OPCODE_DDY, per channel of output we've got input
|
||||
* looking like:
|
||||
*
|
||||
* arg0: ss0.tl ss0.tr ss0.bl ss0.br ss1.tl ss1.tr ss1.bl ss1.br
|
||||
* arg0: q0.tl q0.tr q0.bl q0.br q1.tl q1.tr q1.bl q1.br
|
||||
*
|
||||
* and we're trying to produce:
|
||||
*
|
||||
* DDX DDY
|
||||
* dst: (ss0.tr - ss0.tl) (ss0.tl - ss0.bl)
|
||||
* (ss0.tr - ss0.tl) (ss0.tr - ss0.br)
|
||||
* (ss0.br - ss0.bl) (ss0.tl - ss0.bl)
|
||||
* (ss0.br - ss0.bl) (ss0.tr - ss0.br)
|
||||
* (ss1.tr - ss1.tl) (ss1.tl - ss1.bl)
|
||||
* (ss1.tr - ss1.tl) (ss1.tr - ss1.br)
|
||||
* (ss1.br - ss1.bl) (ss1.tl - ss1.bl)
|
||||
* (ss1.br - ss1.bl) (ss1.tr - ss1.br)
|
||||
* dst: (q0.tr - q0.tl) (q0.tl - q0.bl)
|
||||
* (q0.tr - q0.tl) (q0.tr - q0.br)
|
||||
* (q0.br - q0.bl) (q0.tl - q0.bl)
|
||||
* (q0.br - q0.bl) (q0.tr - q0.br)
|
||||
* (q1.tr - q1.tl) (q1.tl - q1.bl)
|
||||
* (q1.tr - q1.tl) (q1.tr - q1.br)
|
||||
* (q1.br - q1.bl) (q1.tl - q1.bl)
|
||||
* (q1.br - q1.bl) (q1.tr - q1.br)
|
||||
*
|
||||
* and add another set of two more subspans if in 16-pixel dispatch mode.
|
||||
* and add two more quads if in 16-pixel dispatch mode.
|
||||
*
|
||||
* For DDX, it ends up being easy: width = 2, horiz=0 gets us the same result
|
||||
* for each pair, and vertstride = 2 jumps us 2 elements after processing a
|
||||
* pair. But for DDY, it's harder, as we want to produce the pairs swizzled
|
||||
* between each other. We could probably do it like ddx and swizzle the right
|
||||
* order later, but bail for now and just produce
|
||||
* ((ss0.tl - ss0.bl)x4 (ss1.tl - ss1.bl)x4)
|
||||
* ((q0.tl - q0.bl)x4 (q1.tl - q1.bl)x4)
|
||||
*/
|
||||
void emit_ddxy(struct brw_compile *p,
|
||||
const struct brw_reg *dst,
|
||||
@@ -611,12 +620,12 @@ static void emit_dp3( struct brw_compile *p,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1 )
|
||||
{
|
||||
int dst_chan = _mesa_ffs(mask & BRW_WRITEMASK_XYZW) - 1;
|
||||
int dst_chan = ffs(mask & BRW_WRITEMASK_XYZW) - 1;
|
||||
|
||||
if (!(mask & BRW_WRITEMASK_XYZW))
|
||||
return; /* Do not emit dead code */
|
||||
|
||||
assert(is_power_of_two(mask & BRW_WRITEMASK_XYZW));
|
||||
assert(util_is_power_of_two(mask & BRW_WRITEMASK_XYZW));
|
||||
|
||||
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
|
||||
brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
|
||||
@@ -633,12 +642,12 @@ static void emit_dp4( struct brw_compile *p,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1 )
|
||||
{
|
||||
int dst_chan = _mesa_ffs(mask & BRW_WRITEMASK_XYZW) - 1;
|
||||
int dst_chan = ffs(mask & BRW_WRITEMASK_XYZW) - 1;
|
||||
|
||||
if (!(mask & BRW_WRITEMASK_XYZW))
|
||||
return; /* Do not emit dead code */
|
||||
|
||||
assert(is_power_of_two(mask & BRW_WRITEMASK_XYZW));
|
||||
assert(util_is_power_of_two(mask & BRW_WRITEMASK_XYZW));
|
||||
|
||||
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
|
||||
brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
|
||||
@@ -656,12 +665,12 @@ static void emit_dph( struct brw_compile *p,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1 )
|
||||
{
|
||||
const int dst_chan = _mesa_ffs(mask & BRW_WRITEMASK_XYZW) - 1;
|
||||
const int dst_chan = ffs(mask & BRW_WRITEMASK_XYZW) - 1;
|
||||
|
||||
if (!(mask & BRW_WRITEMASK_XYZW))
|
||||
return; /* Do not emit dead code */
|
||||
|
||||
assert(is_power_of_two(mask & BRW_WRITEMASK_XYZW));
|
||||
assert(util_is_power_of_two(mask & BRW_WRITEMASK_XYZW));
|
||||
|
||||
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
|
||||
brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
|
||||
@@ -704,12 +713,12 @@ static void emit_math1( struct brw_compile *p,
|
||||
GLuint mask,
|
||||
const struct brw_reg *arg0 )
|
||||
{
|
||||
int dst_chan = _mesa_ffs(mask & BRW_WRITEMASK_XYZW) - 1;
|
||||
int dst_chan = ffs(mask & BRW_WRITEMASK_XYZW) - 1;
|
||||
|
||||
if (!(mask & BRW_WRITEMASK_XYZW))
|
||||
return; /* Do not emit dead code */
|
||||
|
||||
assert(is_power_of_two(mask & BRW_WRITEMASK_XYZW));
|
||||
assert(util_is_power_of_two(mask & BRW_WRITEMASK_XYZW));
|
||||
|
||||
brw_MOV(p, brw_message_reg(2), arg0[0]);
|
||||
|
||||
@@ -732,12 +741,12 @@ static void emit_math2( struct brw_compile *p,
|
||||
const struct brw_reg *arg0,
|
||||
const struct brw_reg *arg1)
|
||||
{
|
||||
int dst_chan = _mesa_ffs(mask & BRW_WRITEMASK_XYZW) - 1;
|
||||
int dst_chan = ffs(mask & BRW_WRITEMASK_XYZW) - 1;
|
||||
|
||||
if (!(mask & BRW_WRITEMASK_XYZW))
|
||||
return; /* Do not emit dead code */
|
||||
|
||||
assert(is_power_of_two(mask & BRW_WRITEMASK_XYZW));
|
||||
assert(util_is_power_of_two(mask & BRW_WRITEMASK_XYZW));
|
||||
|
||||
brw_push_insn_state(p);
|
||||
|
||||
@@ -790,21 +799,32 @@ static void emit_tex( struct brw_wm_compile *c,
|
||||
GLuint i, nr;
|
||||
GLuint emit;
|
||||
GLuint msg_type;
|
||||
GLboolean shadow = FALSE;
|
||||
|
||||
/* How many input regs are there?
|
||||
*/
|
||||
switch (inst->tex_idx) {
|
||||
case TEXTURE_1D_INDEX:
|
||||
switch (inst->tex_target) {
|
||||
case TGSI_TEXTURE_1D:
|
||||
emit = BRW_WRITEMASK_X;
|
||||
nr = 1;
|
||||
break;
|
||||
case TEXTURE_2D_INDEX:
|
||||
case TEXTURE_RECT_INDEX:
|
||||
case TGSI_TEXTURE_SHADOW1D:
|
||||
emit = BRW_WRITEMASK_XW;
|
||||
nr = 4;
|
||||
shadow = TRUE;
|
||||
break;
|
||||
case TGSI_TEXTURE_2D:
|
||||
emit = BRW_WRITEMASK_XY;
|
||||
nr = 2;
|
||||
break;
|
||||
case TEXTURE_3D_INDEX:
|
||||
case TEXTURE_CUBE_INDEX:
|
||||
case TGSI_TEXTURE_SHADOW2D:
|
||||
case TGSI_TEXTURE_SHADOWRECT:
|
||||
emit = BRW_WRITEMASK_XYW;
|
||||
nr = 4;
|
||||
shadow = TRUE;
|
||||
break;
|
||||
case TGSI_TEXTURE_3D:
|
||||
case TGSI_TEXTURE_CUBE:
|
||||
emit = BRW_WRITEMASK_XYZ;
|
||||
nr = 3;
|
||||
break;
|
||||
@@ -813,11 +833,6 @@ static void emit_tex( struct brw_wm_compile *c,
|
||||
abort();
|
||||
}
|
||||
|
||||
if (inst->tex_shadow) {
|
||||
nr = 4;
|
||||
emit |= BRW_WRITEMASK_W;
|
||||
}
|
||||
|
||||
msgLength = 1;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
@@ -832,12 +847,12 @@ static void emit_tex( struct brw_wm_compile *c,
|
||||
responseLength = 8; /* always */
|
||||
|
||||
if (BRW_IS_IGDNG(p->brw)) {
|
||||
if (inst->tex_shadow)
|
||||
if (shadow)
|
||||
msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE_IGDNG;
|
||||
else
|
||||
msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_IGDNG;
|
||||
} else {
|
||||
if (inst->tex_shadow)
|
||||
if (shadow)
|
||||
msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
|
||||
else
|
||||
msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
|
||||
@@ -870,20 +885,23 @@ static void emit_txb( struct brw_wm_compile *c,
|
||||
GLuint msg_type;
|
||||
/* Shadow ignored for txb.
|
||||
*/
|
||||
switch (inst->tex_idx) {
|
||||
case TEXTURE_1D_INDEX:
|
||||
switch (inst->tex_target) {
|
||||
case TGSI_TEXTURE_1D:
|
||||
case TGSI_TEXTURE_SHADOW1D:
|
||||
brw_MOV(p, brw_message_reg(2), arg[0]);
|
||||
brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
|
||||
brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
|
||||
break;
|
||||
case TEXTURE_2D_INDEX:
|
||||
case TEXTURE_RECT_INDEX:
|
||||
case TGSI_TEXTURE_2D:
|
||||
case TGSI_TEXTURE_RECT:
|
||||
case TGSI_TEXTURE_SHADOW2D:
|
||||
case TGSI_TEXTURE_SHADOWRECT:
|
||||
brw_MOV(p, brw_message_reg(2), arg[0]);
|
||||
brw_MOV(p, brw_message_reg(4), arg[1]);
|
||||
brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
|
||||
break;
|
||||
case TEXTURE_3D_INDEX:
|
||||
case TEXTURE_CUBE_INDEX:
|
||||
case TGSI_TEXTURE_3D:
|
||||
case TGSI_TEXTURE_CUBE:
|
||||
brw_MOV(p, brw_message_reg(2), arg[0]);
|
||||
brw_MOV(p, brw_message_reg(4), arg[1]);
|
||||
brw_MOV(p, brw_message_reg(6), arg[2]);
|
||||
@@ -976,10 +994,10 @@ static void emit_kil( struct brw_wm_compile *c,
|
||||
}
|
||||
}
|
||||
|
||||
/* KIL_NV kills the pixels that are currently executing, not based on a test
|
||||
/* KILLP kills the pixels that are currently executing, not based on a test
|
||||
* of the arguments.
|
||||
*/
|
||||
static void emit_kil_nv( struct brw_wm_compile *c )
|
||||
static void emit_killp( struct brw_wm_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_reg r0uw = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
|
||||
@@ -1259,7 +1277,7 @@ void brw_wm_emit( struct brw_wm_compile *c )
|
||||
*/
|
||||
spill_values(c, c->payload.depth, 4);
|
||||
spill_values(c, c->creg, c->nr_creg);
|
||||
spill_values(c, c->payload.input_interp, FRAG_ATTRIB_MAX);
|
||||
spill_values(c, c->payload.input_interp, PIPE_MAX_SHADER_INPUTS);
|
||||
|
||||
|
||||
for (insn = 0; insn < c->nr_insns; insn++) {
|
||||
@@ -1328,89 +1346,89 @@ void brw_wm_emit( struct brw_wm_compile *c )
|
||||
|
||||
/* Straightforward arithmetic:
|
||||
*/
|
||||
case OPCODE_ADD:
|
||||
case TGSI_OPCODE_ADD:
|
||||
emit_alu2(p, brw_ADD, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
|
||||
case OPCODE_FRC:
|
||||
case TGSI_OPCODE_FRC:
|
||||
emit_alu1(p, brw_FRC, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_FLR:
|
||||
case TGSI_OPCODE_FLR:
|
||||
emit_alu1(p, brw_RNDD, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_DDX:
|
||||
case TGSI_OPCODE_DDX:
|
||||
emit_ddxy(p, dst, dst_flags, GL_TRUE, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_DDY:
|
||||
case TGSI_OPCODE_DDY:
|
||||
emit_ddxy(p, dst, dst_flags, GL_FALSE, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_DP3:
|
||||
case TGSI_OPCODE_DP3:
|
||||
emit_dp3(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
|
||||
case OPCODE_DP4:
|
||||
case TGSI_OPCODE_DP4:
|
||||
emit_dp4(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
|
||||
case OPCODE_DPH:
|
||||
case TGSI_OPCODE_DPH:
|
||||
emit_dph(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
|
||||
case OPCODE_TRUNC:
|
||||
case TGSI_OPCODE_TRUNC:
|
||||
emit_trunc(p, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_LRP:
|
||||
case TGSI_OPCODE_LRP:
|
||||
emit_lrp(p, dst, dst_flags, args[0], args[1], args[2]);
|
||||
break;
|
||||
|
||||
case OPCODE_MAD:
|
||||
case TGSI_OPCODE_MAD:
|
||||
emit_mad(p, dst, dst_flags, args[0], args[1], args[2]);
|
||||
break;
|
||||
|
||||
case OPCODE_MOV:
|
||||
case TGSI_OPCODE_MOV:
|
||||
emit_alu1(p, brw_MOV, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_MUL:
|
||||
case TGSI_OPCODE_MUL:
|
||||
emit_alu2(p, brw_MUL, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
|
||||
case OPCODE_XPD:
|
||||
case TGSI_OPCODE_XPD:
|
||||
emit_xpd(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
|
||||
/* Higher math functions:
|
||||
*/
|
||||
case OPCODE_RCP:
|
||||
case TGSI_OPCODE_RCP:
|
||||
emit_math1(p, BRW_MATH_FUNCTION_INV, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_RSQ:
|
||||
case TGSI_OPCODE_RSQ:
|
||||
emit_math1(p, BRW_MATH_FUNCTION_RSQ, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_SIN:
|
||||
case TGSI_OPCODE_SIN:
|
||||
emit_math1(p, BRW_MATH_FUNCTION_SIN, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_COS:
|
||||
case TGSI_OPCODE_COS:
|
||||
emit_math1(p, BRW_MATH_FUNCTION_COS, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_EX2:
|
||||
case TGSI_OPCODE_EX2:
|
||||
emit_math1(p, BRW_MATH_FUNCTION_EXP, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_LG2:
|
||||
case TGSI_OPCODE_LG2:
|
||||
emit_math1(p, BRW_MATH_FUNCTION_LOG, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_SCS:
|
||||
case TGSI_OPCODE_SCS:
|
||||
/* There is an scs math function, but it would need some
|
||||
* fixup for 16-element execution.
|
||||
*/
|
||||
@@ -1420,71 +1438,70 @@ void brw_wm_emit( struct brw_wm_compile *c )
|
||||
emit_math1(p, BRW_MATH_FUNCTION_SIN, dst+1, (dst_flags&SATURATE)|BRW_WRITEMASK_X, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_POW:
|
||||
case TGSI_OPCODE_POW:
|
||||
emit_math2(p, BRW_MATH_FUNCTION_POW, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
|
||||
/* Comparisons:
|
||||
*/
|
||||
case OPCODE_CMP:
|
||||
case TGSI_OPCODE_CMP:
|
||||
emit_cmp(p, dst, dst_flags, args[0], args[1], args[2]);
|
||||
break;
|
||||
|
||||
case OPCODE_MAX:
|
||||
case TGSI_OPCODE_MAX:
|
||||
emit_max(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
|
||||
case OPCODE_MIN:
|
||||
case TGSI_OPCODE_MIN:
|
||||
emit_min(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
|
||||
case OPCODE_SLT:
|
||||
case TGSI_OPCODE_SLT:
|
||||
emit_slt(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
|
||||
case OPCODE_SLE:
|
||||
case TGSI_OPCODE_SLE:
|
||||
emit_sle(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_SGT:
|
||||
case TGSI_OPCODE_SGT:
|
||||
emit_sgt(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_SGE:
|
||||
case TGSI_OPCODE_SGE:
|
||||
emit_sge(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_SEQ:
|
||||
case TGSI_OPCODE_SEQ:
|
||||
emit_seq(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_SNE:
|
||||
case TGSI_OPCODE_SNE:
|
||||
emit_sne(p, dst, dst_flags, args[0], args[1]);
|
||||
break;
|
||||
|
||||
case OPCODE_LIT:
|
||||
case TGSI_OPCODE_LIT:
|
||||
emit_lit(p, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
/* Texturing operations:
|
||||
*/
|
||||
case OPCODE_TEX:
|
||||
case TGSI_OPCODE_TEX:
|
||||
emit_tex(c, inst, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_TXB:
|
||||
case TGSI_OPCODE_TXB:
|
||||
emit_txb(c, inst, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_KIL:
|
||||
case TGSI_OPCODE_KIL:
|
||||
emit_kil(c, args[0]);
|
||||
break;
|
||||
|
||||
case OPCODE_KIL_NV:
|
||||
emit_kil_nv(c);
|
||||
case TGSI_OPCODE_KILP:
|
||||
emit_killp(c);
|
||||
break;
|
||||
|
||||
default:
|
||||
debug_printf("Unsupported opcode %i (%s) in fragment shader\n",
|
||||
inst->opcode, inst->opcode < MAX_OPCODE ?
|
||||
_mesa_opcode_string(inst->opcode) :
|
||||
"unknown");
|
||||
inst->opcode,
|
||||
tgsi_get_opcode_info(inst->opcode)->mnemonic);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -332,7 +332,7 @@ static void prealloc_reg(struct brw_wm_compile *c)
|
||||
for (j = 0; j < 4; j++)
|
||||
set_reg(c, PROGRAM_PAYLOAD, fp_input, j, reg);
|
||||
}
|
||||
if (c->key.vp_outputs_written & (1 << i)) {
|
||||
if (c->key.nr_vp_outputs > i) {
|
||||
reg_index += 2;
|
||||
}
|
||||
}
|
||||
@@ -1670,7 +1670,7 @@ get_argument_regs(struct brw_wm_compile *c,
|
||||
}
|
||||
}
|
||||
|
||||
static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
|
||||
static void brw_wm_emit_branching_shader(struct brw_context *brw, struct brw_wm_compile *c)
|
||||
{
|
||||
#define MAX_IF_DEPTH 32
|
||||
#define MAX_LOOP_DEPTH 32
|
||||
@@ -1943,20 +1943,20 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
|
||||
* Do GPU code generation for shaders that use GLSL features such as
|
||||
* flow control. Other shaders will be compiled with the
|
||||
*/
|
||||
void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c)
|
||||
void brw_wm_branching_shader_emit(struct brw_context *brw, struct brw_wm_compile *c)
|
||||
{
|
||||
if (BRW_DEBUG & DEBUG_WM) {
|
||||
debug_printf("brw_wm_glsl_emit:\n");
|
||||
debug_printf("%s:\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
/* initial instruction translation/simplification */
|
||||
brw_wm_pass_fp(c);
|
||||
|
||||
/* actual code generation */
|
||||
brw_wm_emit_glsl(brw, c);
|
||||
brw_wm_emit_branching_shader(brw, c);
|
||||
|
||||
if (BRW_DEBUG & DEBUG_WM) {
|
||||
brw_wm_print_program(c, "brw_wm_glsl_emit done");
|
||||
brw_wm_print_program(c, "brw_wm_branching_shader_emit done");
|
||||
}
|
||||
|
||||
c->prog_data.total_grf = num_grf_used(c);
|
||||
|
||||
@@ -168,54 +168,20 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
|
||||
|
||||
if (!ref) {
|
||||
switch (file) {
|
||||
case PROGRAM_INPUT:
|
||||
case PROGRAM_PAYLOAD:
|
||||
case PROGRAM_TEMPORARY:
|
||||
case PROGRAM_OUTPUT:
|
||||
case PROGRAM_VARYING:
|
||||
case TGSI_FILE_INPUT:
|
||||
case TGSI_FILE_TEMPORARY:
|
||||
case TGSI_FILE_OUTPUT:
|
||||
case BRW_FILE_PAYLOAD:
|
||||
/* should already be done?? */
|
||||
break;
|
||||
|
||||
case PROGRAM_LOCAL_PARAM:
|
||||
ref = get_param_ref(c, &c->fp->program.Base.LocalParams[idx][component]);
|
||||
break;
|
||||
|
||||
case PROGRAM_ENV_PARAM:
|
||||
case TGSI_FILE_CONSTANT:
|
||||
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 invarient:
|
||||
*/
|
||||
ref = get_imm_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;
|
||||
}
|
||||
case TGSI_FILE_IMMEDIATE:
|
||||
ref = get_imm_ref(c, &plist->ParameterValues[idx][component]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
@@ -310,17 +276,16 @@ 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 writemask = inst->dst.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->saturate = inst->dst.Saturate;
|
||||
out->tex_unit = inst->TexSrcUnit;
|
||||
out->tex_idx = inst->TexSrcTarget;
|
||||
out->tex_shadow = inst->TexShadow;
|
||||
out->tex_target = inst->TexSrcTarget;
|
||||
out->eot = inst->Aux & 1;
|
||||
out->target = inst->Aux >> 1;
|
||||
|
||||
@@ -328,7 +293,7 @@ translate_insn(struct brw_wm_compile *c,
|
||||
*/
|
||||
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);
|
||||
out->src[i][j] = get_new_ref(c, inst->src[i], j, out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,15 +345,6 @@ static void pass0_init_payload( struct brw_wm_compile *c )
|
||||
&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] );
|
||||
@@ -403,6 +359,9 @@ static void pass0_init_payload( struct brw_wm_compile *c )
|
||||
* the same number.
|
||||
*
|
||||
* Translate away swizzling and eliminate non-saturating moves.
|
||||
*
|
||||
* Translate instructions from Mesa's prog_instruction structs to our
|
||||
* internal brw_wm_instruction representation.
|
||||
*/
|
||||
void brw_wm_pass0( struct brw_wm_compile *c )
|
||||
{
|
||||
@@ -421,7 +380,7 @@ void brw_wm_pass0( struct brw_wm_compile *c )
|
||||
*/
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_MOV:
|
||||
if (!inst->SaturateMode) {
|
||||
if (!inst->dst.Saturate) {
|
||||
pass0_precalc_mov(c, inst);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -90,17 +90,24 @@ static void track_arg(struct brw_wm_compile *c,
|
||||
static GLuint get_texcoord_mask( GLuint tex_idx )
|
||||
{
|
||||
switch (tex_idx) {
|
||||
case TEXTURE_1D_INDEX:
|
||||
case TGSI_TEXTURE_1D:
|
||||
return BRW_WRITEMASK_X;
|
||||
case TEXTURE_2D_INDEX:
|
||||
case TGSI_TEXTURE_2D:
|
||||
case TGSI_TEXTURE_RECT:
|
||||
return BRW_WRITEMASK_XY;
|
||||
case TEXTURE_3D_INDEX:
|
||||
case TGSI_TEXTURE_3D:
|
||||
return BRW_WRITEMASK_XYZ;
|
||||
case TEXTURE_CUBE_INDEX:
|
||||
case TGSI_TEXTURE_CUBE:
|
||||
return BRW_WRITEMASK_XYZ;
|
||||
case TEXTURE_RECT_INDEX:
|
||||
return BRW_WRITEMASK_XY;
|
||||
default: return 0;
|
||||
|
||||
case TGSI_TEXTURE_SHADOW1D:
|
||||
return BRW_WRITEMASK_XZ;
|
||||
case TGSI_TEXTURE_SHADOW2D:
|
||||
case TGSI_TEXTURE_SHADOWRECT:
|
||||
return BRW_WRITEMASK_XYZ;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,14 +224,9 @@ void brw_wm_pass1( struct brw_wm_compile *c )
|
||||
case TGSI_OPCODE_TEX:
|
||||
case TGSI_OPCODE_TXP:
|
||||
read0 = get_texcoord_mask(inst->tex_idx);
|
||||
|
||||
if (inst->tex_shadow)
|
||||
read0 |= BRW_WRITEMASK_Z;
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_TXB:
|
||||
/* Shadow ignored for txb.
|
||||
*/
|
||||
read0 = get_texcoord_mask(inst->tex_idx) | BRW_WRITEMASK_W;
|
||||
break;
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ struct brw_wm_unit_key {
|
||||
unsigned int max_threads;
|
||||
|
||||
unsigned int nr_surfaces, sampler_count;
|
||||
GLboolean uses_depth, computes_depth, uses_kill, is_glsl;
|
||||
GLboolean uses_depth, computes_depth, uses_kill, has_flow_control;
|
||||
GLboolean polygon_stipple, stats_wm, line_stipple, offset_enable;
|
||||
GLfloat offset_units, offset_factor;
|
||||
};
|
||||
@@ -114,10 +114,10 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
|
||||
|
||||
/* _NEW_COLOR */
|
||||
key->uses_kill = fp->UsesKill || ctx->Color.AlphaEnabled;
|
||||
key->is_glsl = bfp->isGLSL;
|
||||
key->has_flow_control = bfp->has_flow_control;
|
||||
|
||||
/* temporary sanity check assertion */
|
||||
ASSERT(bfp->isGLSL == brw_wm_is_glsl(fp));
|
||||
ASSERT(bfp->has_flow_control == brw_wm_has_flow_control(fp));
|
||||
|
||||
/* _NEW_QUERY */
|
||||
key->stats_wm = (brw->query.stats_wm != 0);
|
||||
@@ -184,7 +184,7 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
|
||||
wm.wm5.program_computes_depth = key->computes_depth;
|
||||
wm.wm5.program_uses_killpixel = key->uses_kill;
|
||||
|
||||
if (key->is_glsl)
|
||||
if (key->has_flow_control)
|
||||
wm.wm5.enable_8_pix = 1;
|
||||
else
|
||||
wm.wm5.enable_16_pix = 1;
|
||||
|
||||
Reference in New Issue
Block a user