i965g: get basic texturing working again

Revert to fixed-layout surface binding table -- it's probably the best
way to do this.  Pass sampler and texture numbers separately even
though we're always keeping them the same at present.
This commit is contained in:
Keith Whitwell 2009-11-21 01:52:22 +00:00
parent 95d7aca4b9
commit 8bf75f28de
9 changed files with 118 additions and 67 deletions

View file

@ -209,9 +209,9 @@ struct brw_fragment_shader {
struct brw_sampler {
float border_color[4];
struct brw_ss0 ss0;
struct brw_ss1 ss1;
float border_color[4];
struct brw_ss3 ss3;
};
@ -355,20 +355,23 @@ struct brw_vs_ouput_sizes {
/** Number of texture sampler units */
#define BRW_MAX_TEX_UNIT 16
/** Max number of render targets in a shader */
#define BRW_MAX_DRAW_BUFFERS 4
/**
* Size of our surface binding table for the WM.
* This contains pointers to the drawing surfaces and current texture
* objects and shader constant buffers (+2).
*/
#define BRW_WM_MAX_SURF (PIPE_MAX_COLOR_BUFS + BRW_MAX_TEX_UNIT + 1)
#define BRW_WM_MAX_SURF (BRW_MAX_DRAW_BUFFERS + BRW_MAX_TEX_UNIT + 1)
/**
* Helpers to convert drawing buffers, textures and constant buffers
* to surface binding table indexes, for WM.
*/
#define SURF_INDEX_DRAW(d) (d)
#define SURF_INDEX_FRAG_CONST_BUFFER (PIPE_MAX_COLOR_BUFS)
#define SURF_INDEX_TEXTURE(t) (PIPE_MAX_COLOR_BUFS + 1 + (t))
#define BTI_COLOR_BUF(d) (d)
#define BTI_FRAGMENT_CONSTANTS (BRW_MAX_DRAW_BUFFERS)
#define BTI_TEXTURE(t) (BRW_MAX_DRAW_BUFFERS + 1 + (t))
/**
* Size of surface binding table for the VS.

View file

@ -31,7 +31,7 @@ static void brw_set_framebuffer_state( struct pipe_context *pipe,
/* Color buffers:
*/
for (i = 0; i < MAX2(fb->nr_cbufs, brw->curr.fb.nr_cbufs); i++) {
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
if (brw->curr.fb.cbufs[i] != fb->cbufs[i]) {
brw->state.dirty.mesa |= PIPE_NEW_COLOR_BUFFERS;
pipe_surface_reference(&brw->curr.fb.cbufs[i], fb->cbufs[i]);
@ -39,7 +39,7 @@ static void brw_set_framebuffer_state( struct pipe_context *pipe,
}
if (brw->curr.fb.nr_cbufs != fb->nr_cbufs) {
brw->curr.fb.nr_cbufs = fb->nr_cbufs;
brw->curr.fb.nr_cbufs = MIN2(BRW_MAX_DRAW_BUFFERS, fb->nr_cbufs);
brw->state.dirty.mesa |= PIPE_NEW_NR_CBUFS;
}
}

View file

@ -107,7 +107,7 @@ static void *
brw_create_sampler_state( struct pipe_context *pipe,
const struct pipe_sampler_state *template )
{
struct brw_sampler_state *sampler = CALLOC_STRUCT(brw_sampler_state);
struct brw_sampler *sampler = CALLOC_STRUCT(brw_sampler);
sampler->ss0.min_filter = translate_img_filter( template->min_img_filter );
sampler->ss0.mag_filter = translate_img_filter( template->mag_img_filter );
@ -214,7 +214,6 @@ void brw_pipe_sampler_init( struct brw_context *brw )
brw->base.set_sampler_textures = brw_set_sampler_textures;
}
void brw_pipe_sampler_cleanup( struct brw_context *brw )
{
}

View file

@ -153,9 +153,10 @@ static enum pipe_error upload_sf_prog(struct brw_context *brw)
case TGSI_INTERPOLATE_CONSTANT:
break;
case TGSI_INTERPOLATE_LINEAR:
case TGSI_INTERPOLATE_PERSPECTIVE:
key.linear_attrs |= 1 << (i+1);
break;
case TGSI_INTERPOLATE_PERSPECTIVE:
// case TGSI_INTERPOLATE_PERSPECTIVE:
key.persp_attrs |= 1 << (i+1);
break;
}

View file

@ -56,6 +56,15 @@ GLuint brw_wm_nr_args( GLuint opcode )
case WM_FB_WRITE:
case WM_PINTERP:
return 3;
case TGSI_OPCODE_TEX:
case TGSI_OPCODE_TXP:
case TGSI_OPCODE_TXB:
case TGSI_OPCODE_TXD:
/* sampler arg is held as a field in the instruction, not in an
* actual register:
*/
return tgsi_get_opcode_info(opcode)->num_src - 1;
default:
assert(opcode < MAX_OPCODE);
return tgsi_get_opcode_info(opcode)->num_src;

View file

@ -135,6 +135,7 @@ struct brw_wm_instruction {
GLuint opcode:8;
GLuint saturate:1;
GLuint writemask:4;
GLuint sampler:4;
GLuint tex_unit:4; /* texture/sampler unit for texture instructions */
GLuint target:4; /* TGSI_TEXTURE_x for texture instructions,
* target binding table index for FB_WRITE
@ -201,7 +202,8 @@ struct brw_fp_instruction {
unsigned opcode:8;
unsigned target:8; /* XXX: special usage for FB_WRITE */
unsigned tex_unit:4;
unsigned pad:12;
unsigned sampler:4;
unsigned pad:8;
};

View file

@ -792,7 +792,8 @@ static void emit_tex( struct brw_wm_compile *c,
const struct brw_wm_instruction *inst,
struct brw_reg *dst,
GLuint dst_flags,
struct brw_reg *arg )
struct brw_reg *coord,
GLuint sampler)
{
struct brw_compile *p = &c->func;
GLuint msgLength, responseLength;
@ -838,7 +839,7 @@ static void emit_tex( struct brw_wm_compile *c,
for (i = 0; i < nr; i++) {
static const GLuint swz[4] = {0,1,2,2};
if (emit & (1<<i))
brw_MOV(p, brw_message_reg(msgLength+1), arg[swz[i]]);
brw_MOV(p, brw_message_reg(msgLength+1), coord[swz[i]]);
else
brw_MOV(p, brw_message_reg(msgLength+1), brw_imm_f(0));
msgLength += 2;
@ -862,8 +863,8 @@ static void emit_tex( struct brw_wm_compile *c,
retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
1,
retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW),
SURF_INDEX_TEXTURE(inst->tex_unit),
inst->tex_unit, /* sampler */
BTI_TEXTURE(inst->tex_unit),
sampler, /* sampler index */
inst->writemask,
msg_type,
responseLength,
@ -878,7 +879,8 @@ static void emit_txb( struct brw_wm_compile *c,
const struct brw_wm_instruction *inst,
struct brw_reg *dst,
GLuint dst_flags,
struct brw_reg *arg )
struct brw_reg *coord,
GLuint sampler )
{
struct brw_compile *p = &c->func;
GLuint msgLength;
@ -888,7 +890,7 @@ static void emit_txb( struct brw_wm_compile *c,
switch (inst->target) {
case TGSI_TEXTURE_1D:
case TGSI_TEXTURE_SHADOW1D:
brw_MOV(p, brw_message_reg(2), arg[0]);
brw_MOV(p, brw_message_reg(2), coord[0]);
brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
break;
@ -896,22 +898,22 @@ static void emit_txb( struct brw_wm_compile *c,
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(2), coord[0]);
brw_MOV(p, brw_message_reg(4), coord[1]);
brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
break;
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]);
brw_MOV(p, brw_message_reg(2), coord[0]);
brw_MOV(p, brw_message_reg(4), coord[1]);
brw_MOV(p, brw_message_reg(6), coord[2]);
break;
default:
/* unexpected target */
abort();
}
brw_MOV(p, brw_message_reg(8), arg[3]);
brw_MOV(p, brw_message_reg(8), coord[3]);
msgLength = 9;
if (BRW_IS_IGDNG(p->brw))
@ -923,8 +925,8 @@ static void emit_txb( struct brw_wm_compile *c,
retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
1,
retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW),
SURF_INDEX_TEXTURE(inst->tex_unit),
inst->tex_unit, /* sampler */
BTI_TEXTURE(inst->tex_unit),
sampler, /* sampler index */
inst->writemask,
msg_type,
8, /* responseLength */
@ -1483,11 +1485,11 @@ void brw_wm_emit( struct brw_wm_compile *c )
/* Texturing operations:
*/
case TGSI_OPCODE_TEX:
emit_tex(c, inst, dst, dst_flags, args[0]);
emit_tex(c, inst, dst, dst_flags, args[0], inst->sampler);
break;
case TGSI_OPCODE_TXB:
emit_txb(c, inst, dst, dst_flags, args[0]);
emit_txb(c, inst, dst, dst_flags, args[0], inst->sampler);
break;
case TGSI_OPCODE_KIL:

View file

@ -282,6 +282,7 @@ static struct brw_fp_instruction * emit_tex_op(struct brw_wm_compile *c,
struct brw_fp_dst dest,
GLuint tex_unit,
GLuint target,
GLuint sampler,
struct brw_fp_src src0,
struct brw_fp_src src1,
struct brw_fp_src src2 )
@ -298,6 +299,7 @@ static struct brw_fp_instruction * emit_tex_op(struct brw_wm_compile *c,
inst->dst = dest;
inst->tex_unit = tex_unit;
inst->target = target;
inst->sampler = sampler;
inst->src[0] = src0;
inst->src[1] = src1;
inst->src[2] = src2;
@ -313,7 +315,7 @@ static INLINE void emit_op3(struct brw_wm_compile *c,
struct brw_fp_src src1,
struct brw_fp_src src2 )
{
emit_tex_op(c, op, dest, 0, 0, src0, src1, src2);
emit_tex_op(c, op, dest, 0, 0, 0, src0, src1, src2);
}
@ -323,7 +325,7 @@ static INLINE void emit_op2(struct brw_wm_compile *c,
struct brw_fp_src src0,
struct brw_fp_src src1)
{
emit_tex_op(c, op, dest, 0, 0, src0, src1, src_undef());
emit_tex_op(c, op, dest, 0, 0, 0, src0, src1, src_undef());
}
static INLINE void emit_op1(struct brw_wm_compile *c,
@ -331,14 +333,14 @@ static INLINE void emit_op1(struct brw_wm_compile *c,
struct brw_fp_dst dest,
struct brw_fp_src src0)
{
emit_tex_op(c, op, dest, 0, 0, src0, src_undef(), src_undef());
emit_tex_op(c, op, dest, 0, 0, 0, src0, src_undef(), src_undef());
}
static INLINE void emit_op0(struct brw_wm_compile *c,
GLuint op,
struct brw_fp_dst dest)
{
emit_tex_op(c, op, dest, 0, 0, src_undef(), src_undef(), src_undef());
emit_tex_op(c, op, dest, 0, 0, 0, src_undef(), src_undef(), src_undef());
}
@ -674,7 +676,8 @@ static void precalc_tex( struct brw_wm_compile *c,
struct brw_fp_dst dst,
unsigned target,
unsigned unit,
struct brw_fp_src src0 )
struct brw_fp_src src0,
struct brw_fp_src sampler )
{
struct brw_fp_src coord = src_undef();
struct brw_fp_dst tmp = dst_undef();
@ -751,6 +754,7 @@ static void precalc_tex( struct brw_wm_compile *c,
dst_saturate(tmp, dst.saturate),
unit,
target,
sampler.index,
coord,
src_undef(),
src_undef());
@ -802,6 +806,7 @@ static void precalc_tex( struct brw_wm_compile *c,
dst,
unit,
target,
sampler.index,
coord,
src_undef(),
src_undef());
@ -851,7 +856,8 @@ static void precalc_txp( struct brw_wm_compile *c,
struct brw_fp_dst dst,
unsigned target,
unsigned unit,
struct brw_fp_src src0 )
struct brw_fp_src src0,
struct brw_fp_src sampler )
{
if (projtex(c, target, src0)) {
struct brw_fp_dst tmp = get_temp(c);
@ -877,7 +883,8 @@ static void precalc_txp( struct brw_wm_compile *c,
dst,
target,
unit,
src_reg_from_dst(tmp));
src_reg_from_dst(tmp),
sampler );
release_temp(c, tmp);
}
@ -885,7 +892,7 @@ static void precalc_txp( struct brw_wm_compile *c,
{
/* dst = TEX src0
*/
precalc_tex(c, dst, target, unit, src0);
precalc_tex(c, dst, target, unit, src0, sampler);
}
}
@ -936,6 +943,7 @@ static void emit_fb_write( struct brw_wm_compile *c )
dst_undef(),
(i == c->key.nr_cbufs - 1), /* EOT */
i,
0, /* no sampler */
outcolor,
payload_r0_depth,
outdepth);
@ -1056,15 +1064,17 @@ static void emit_insn( struct brw_wm_compile *c,
case TGSI_OPCODE_TEX:
precalc_tex(c, dst,
inst->InstructionExtTexture.Texture,
src[0].file, /* sampler unit */
src[1] );
src[1].index, /* use sampler unit for tex idx */
src[0], /* coord */
src[1]); /* sampler */
break;
case TGSI_OPCODE_TXP:
precalc_txp(c, dst,
inst->InstructionExtTexture.Texture,
src[0].file, /* sampler unit */
src[1] );
src[1].index, /* use sampler unit for tex idx */
src[0], /* coord */
src[1]); /* sampler */
break;
case TGSI_OPCODE_TXB:
@ -1072,8 +1082,9 @@ static void emit_insn( struct brw_wm_compile *c,
*/
precalc_tex(c, dst,
inst->InstructionExtTexture.Texture,
src[0].file, /* sampler unit */
src[1] );
src[1].index, /* use sampler unit for tex idx*/
src[0],
src[1]);
break;
case TGSI_OPCODE_XPD:

View file

@ -149,19 +149,23 @@ brw_wm_get_binding_table(struct brw_context *brw,
enum pipe_error ret;
struct brw_winsys_reloc reloc[BRW_WM_MAX_SURF];
uint32_t data[BRW_WM_MAX_SURF];
GLuint nr_relocs = 0;
GLuint data_size = brw->wm.nr_surfaces * sizeof data[0];
int i;
assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF);
assert(brw->wm.nr_surfaces > 0);
/* Emit binding table relocations to surface state */
/* Emit binding table relocations to surface state
*/
for (i = 0; i < brw->wm.nr_surfaces; i++) {
make_reloc(&reloc[i],
BRW_USAGE_STATE,
0,
i * sizeof(GLuint),
brw->wm.surf_bo[i]);
if (brw->wm.surf_bo[i]) {
make_reloc(&reloc[nr_relocs++],
BRW_USAGE_STATE,
0,
i * sizeof(GLuint),
brw->wm.surf_bo[i]);
}
}
/* Note there is no key for this search beyond the values in the
@ -169,7 +173,7 @@ brw_wm_get_binding_table(struct brw_context *brw,
*/
if (brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
NULL, 0,
reloc, brw->wm.nr_surfaces,
reloc, nr_relocs,
NULL,
bo_out))
return PIPE_OK;
@ -182,7 +186,7 @@ brw_wm_get_binding_table(struct brw_context *brw,
ret = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
NULL, 0,
reloc, brw->wm.nr_surfaces,
reloc, nr_relocs,
data, data_size,
NULL, NULL,
bo_out);
@ -208,40 +212,60 @@ static enum pipe_error prepare_wm_surfaces(struct brw_context *brw )
for (i = 0; i < brw->curr.fb.nr_cbufs; i++) {
ret = brw_update_render_surface(brw,
brw_surface(brw->curr.fb.cbufs[i]),
&brw->wm.surf_bo[nr_surfaces++]);
&brw->wm.surf_bo[BTI_COLOR_BUF(i)]);
if (ret)
return ret;
nr_surfaces = BTI_COLOR_BUF(i) + 1;
}
/* PIPE_NEW_FRAGMENT_CONSTANTS
*/
#if 0
if (brw->curr.fragment_constants) {
ret = brw_update_fragment_constant_surface(
brw,
brw->curr.fragment_constants,
&brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS]);
if (ret)
return ret;
nr_surfaces = BTI_FRAGMENT_CONSTANTS + 1;
}
else {
bo_reference(&brw->wm.surf_bo[SURF_FRAG_CONSTANTS], NULL);
}
#endif
/* PIPE_NEW_TEXTURE
*/
for (i = 0; i < brw->curr.num_textures; i++) {
ret = brw_update_texture_surface(brw,
brw_texture(brw->curr.texture[i]),
&brw->wm.surf_bo[nr_surfaces++]);
&brw->wm.surf_bo[BTI_TEXTURE(i)]);
if (ret)
return ret;
nr_surfaces = BTI_TEXTURE(i) + 1;
}
/* PIPE_NEW_FRAGMENT_CONSTANTS
/* Clear any inactive entries:
*/
#if 0
if (brw->curr.fragment_constants) {
ret = brw_update_fragment_constant_surface(brw,
brw->curr.fragment_constants,
&brw->wm.surf_bo[nr_surfaces++]);
if (ret)
return ret;
}
#endif
for (i = brw->curr.fb.nr_cbufs; i < BRW_MAX_DRAW_BUFFERS; i++)
bo_reference(&brw->wm.surf_bo[BTI_COLOR_BUF(i)], NULL);
if (!brw->curr.fragment_constants)
bo_reference(&brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS], NULL);
/* XXX: no pipe_max_textures define?? */
for (i = brw->curr.num_textures; i < PIPE_MAX_SAMPLERS; i++)
bo_reference(&brw->wm.surf_bo[BTI_TEXTURE(i)], NULL);
if (brw->wm.nr_surfaces != nr_surfaces) {
/* Unreference any left-over old buffers
*/
for (i = nr_surfaces; i < brw->wm.nr_surfaces; i++)
bo_reference(&brw->wm.surf_bo[i], NULL);
brw->wm.nr_surfaces = nr_surfaces;
brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
}