summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Krol <michal@vmware.com>2010-01-12 10:19:22 +0100
committerMichal Krol <michal@vmware.com>2010-01-12 10:19:22 +0100
commitde1fb34223b82caf3805ebca9e1bb2fbc13c99fa (patch)
treea71a967b6282564902b1050795bb6a97ae07f632
parent50d0620db207d7650ccee0ba87e4d8f909aa30c5 (diff)
gallium: Prepare interfaces to do TXF in softpipe and TGSI interpreter.
-rw-r--r--src/gallium/auxiliary/draw/draw_gs.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_exec.c4
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c219
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h25
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_exec.c17
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_sse.c8
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_fs.c8
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h7
8 files changed, 227 insertions, 65 deletions
diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
index 5db2e75542..8dde00709d 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -333,6 +333,8 @@ void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
tgsi_exec_machine_bind_shader(shader->machine,
shader->state.tokens,
draw->gs.num_samplers,
- draw->gs.samplers);
+ draw->gs.samplers,
+ 0,
+ NULL);
}
}
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index 41cc802613..46305dca51 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -70,7 +70,9 @@ vs_exec_prepare( struct draw_vertex_shader *shader,
tgsi_exec_machine_bind_shader(evs->machine,
shader->state.tokens,
draw->vs.num_samplers,
- draw->vs.samplers);
+ draw->vs.samplers,
+ 0,
+ NULL);
}
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index c3d79c9136..4ce4bec632 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -540,12 +540,13 @@ tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst)
* allocating temporary storage, setting up constants, etc.
* After this, we can call tgsi_exec_machine_run() many times.
*/
-void
-tgsi_exec_machine_bind_shader(
- struct tgsi_exec_machine *mach,
- const struct tgsi_token *tokens,
- uint numSamplers,
- struct tgsi_sampler **samplers)
+void
+tgsi_exec_machine_bind_shader(struct tgsi_exec_machine *mach,
+ const struct tgsi_token *tokens,
+ uint numSamplers,
+ struct tgsi_sampler **samplers,
+ uint numResources,
+ struct tgsi_resource **resources)
{
uint k;
struct tgsi_parse_context parse;
@@ -564,6 +565,7 @@ tgsi_exec_machine_bind_shader(
mach->Tokens = tokens;
mach->Samplers = samplers;
+ mach->Resources = resources;
k = tgsi_parse_init (&parse, mach->Tokens);
if (k != TGSI_PARSE_OK) {
@@ -1503,7 +1505,107 @@ emit_primitive(struct tgsi_exec_machine *mach)
* Fetch a four texture samples using STR texture coordinates.
*/
static void
-fetch_texel( struct tgsi_sampler *sampler,
+fetch_texel(struct tgsi_resource *resource,
+ const union tgsi_exec_channel *i,
+ const union tgsi_exec_channel *j,
+ const union tgsi_exec_channel *k,
+ const union tgsi_exec_channel *lod,
+ union tgsi_exec_channel *r,
+ union tgsi_exec_channel *g,
+ union tgsi_exec_channel *b,
+ union tgsi_exec_channel *a)
+{
+ uint q;
+ float rgba[NUM_CHANNELS][QUAD_SIZE];
+
+ resource->fetch3D(resource, i->i, j->i, k->i, lod->i, rgba);
+
+ for (q = 0; q < QUAD_SIZE; q++) {
+ r->f[q] = rgba[0][q];
+ g->f[q] = rgba[1][q];
+ b->f[q] = rgba[2][q];
+ a->f[q] = rgba[3][q];
+ }
+}
+
+static void
+exec_txf(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ const uint unit = inst->Src[0].Register.Index;
+ union tgsi_exec_channel r[4];
+ uint chan;
+
+ switch (mach->ResourceDecls[unit].Texture) {
+ case TGSI_TEXTURE_1D:
+ case TGSI_TEXTURE_SHADOW1D:
+ fetch_source(mach, &r[0], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_INT);
+ fetch_source(mach, &r[3], &inst->Src[1], CHAN_W, TGSI_EXEC_DATA_INT);
+
+ fetch_texel(mach->Resources[unit],
+ &r[0],
+ &ZeroVec,
+ &ZeroVec,
+ &r[3],
+ &r[0],
+ &r[1],
+ &r[2],
+ &r[3]);
+ break;
+
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_RECT:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_SHADOWRECT:
+ fetch_source(mach, &r[0], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_INT);
+ fetch_source(mach, &r[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_INT);
+ fetch_source(mach, &r[3], &inst->Src[1], CHAN_W, TGSI_EXEC_DATA_INT);
+
+ fetch_texel(mach->Resources[unit],
+ &r[0],
+ &r[1],
+ &ZeroVec,
+ &r[3],
+ &r[0],
+ &r[1],
+ &r[2],
+ &r[3]);
+ break;
+
+ case TGSI_TEXTURE_3D:
+ case TGSI_TEXTURE_CUBE:
+ fetch_source(mach, &r[0], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_INT);
+ fetch_source(mach, &r[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_INT);
+ fetch_source(mach, &r[2], &inst->Src[1], CHAN_Z, TGSI_EXEC_DATA_INT);
+ fetch_source(mach, &r[3], &inst->Src[1], CHAN_W, TGSI_EXEC_DATA_INT);
+
+ fetch_texel(mach->Resources[unit],
+ &r[0],
+ &r[1],
+ &r[2],
+ &r[3],
+ &r[0],
+ &r[1],
+ &r[2],
+ &r[3]);
+ break;
+
+ default:
+ assert(0);
+ }
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_UINT);
+ }
+ }
+}
+
+/*
+ * Sample four texture samples using STR texture coordinates.
+ */
+static void
+sample_texel(struct tgsi_sampler *sampler,
const union tgsi_exec_channel *s,
const union tgsi_exec_channel *t,
const union tgsi_exec_channel *p,
@@ -1512,14 +1614,14 @@ fetch_texel( struct tgsi_sampler *sampler,
union tgsi_exec_channel *r,
union tgsi_exec_channel *g,
union tgsi_exec_channel *b,
- union tgsi_exec_channel *a )
+ union tgsi_exec_channel *a)
{
uint j;
float rgba[NUM_CHANNELS][QUAD_SIZE];
sampler->get_samples(sampler, s->f, t->f, p->f, c0->f, control, rgba);
- for (j = 0; j < 4; j++) {
+ for (j = 0; j < QUAD_SIZE; j++) {
r->f[j] = rgba[0][j];
g->f[j] = rgba[1][j];
b->f[j] = rgba[2][j];
@@ -1559,7 +1661,7 @@ exec_tex(struct tgsi_exec_machine *mach,
control = tgsi_sampler_lod_bias;
}
- switch (mach->Resources[image_unit].Texture) {
+ switch (mach->ResourceDecls[image_unit].Texture) {
case TGSI_TEXTURE_1D:
case TGSI_TEXTURE_SHADOW1D:
fetch_source(mach, &r[0], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
@@ -1568,10 +1670,16 @@ exec_tex(struct tgsi_exec_machine *mach,
micro_div(&r[0], &r[0], &r[3]);
}
- fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &ZeroVec, &ZeroVec, lod, /* S, T, P, LOD */
- control,
- &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
+ sample_texel(mach->Samplers[sampler_unit],
+ &r[0],
+ &ZeroVec,
+ &ZeroVec,
+ lod,
+ control,
+ &r[0],
+ &r[1],
+ &r[2],
+ &r[3]);
break;
case TGSI_TEXTURE_2D:
@@ -1588,10 +1696,16 @@ exec_tex(struct tgsi_exec_machine *mach,
micro_div(&r[2], &r[2], &r[3]);
}
- fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &r[1], &r[2], lod, /* S, T, P, LOD */
- control,
- &r[0], &r[1], &r[2], &r[3]); /* outputs */
+ sample_texel(mach->Samplers[sampler_unit],
+ &r[0],
+ &r[1],
+ &r[2],
+ lod,
+ control,
+ &r[0],
+ &r[1],
+ &r[2],
+ &r[3]);
break;
case TGSI_TEXTURE_3D:
@@ -1606,10 +1720,16 @@ exec_tex(struct tgsi_exec_machine *mach,
micro_div(&r[2], &r[2], &r[3]);
}
- fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &r[1], &r[2], lod,
- control,
- &r[0], &r[1], &r[2], &r[3]);
+ sample_texel(mach->Samplers[sampler_unit],
+ &r[0],
+ &r[1],
+ &r[2],
+ lod,
+ control,
+ &r[0],
+ &r[1],
+ &r[2],
+ &r[3]);
break;
default:
@@ -1618,7 +1738,7 @@ exec_tex(struct tgsi_exec_machine *mach,
for (chan = 0; chan < NUM_CHANNELS; chan++) {
if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
- store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_UINT);
}
}
}
@@ -1636,15 +1756,21 @@ exec_txd(struct tgsi_exec_machine *mach,
* XXX: This is fake TXD -- the derivatives are not taken into account, yet.
*/
- switch (mach->Resources[image_unit].Texture) {
+ switch (mach->ResourceDecls[image_unit].Texture) {
case TGSI_TEXTURE_1D:
case TGSI_TEXTURE_SHADOW1D:
fetch_source(mach, &r[0], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
- fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, BIAS */
- tgsi_sampler_lod_bias,
- &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
+ sample_texel(mach->Samplers[sampler_unit],
+ &r[0],
+ &ZeroVec,
+ &ZeroVec,
+ &ZeroVec,
+ tgsi_sampler_lod_bias,
+ &r[0],
+ &r[1],
+ &r[2],
+ &r[3]);
break;
case TGSI_TEXTURE_2D:
@@ -1655,10 +1781,16 @@ exec_txd(struct tgsi_exec_machine *mach,
fetch_source(mach, &r[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
fetch_source(mach, &r[2], &inst->Src[1], CHAN_Z, TGSI_EXEC_DATA_FLOAT);
- fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &r[1], &r[2], &ZeroVec, /* inputs */
- tgsi_sampler_lod_bias,
- &r[0], &r[1], &r[2], &r[3]); /* outputs */
+ sample_texel(mach->Samplers[sampler_unit],
+ &r[0],
+ &r[1],
+ &r[2],
+ &ZeroVec,
+ tgsi_sampler_lod_bias,
+ &r[0],
+ &r[1],
+ &r[2],
+ &r[3]);
break;
case TGSI_TEXTURE_3D:
@@ -1667,10 +1799,16 @@ exec_txd(struct tgsi_exec_machine *mach,
fetch_source(mach, &r[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
fetch_source(mach, &r[2], &inst->Src[1], CHAN_Z, TGSI_EXEC_DATA_FLOAT);
- fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &r[1], &r[2], &ZeroVec,
- tgsi_sampler_lod_bias,
- &r[0], &r[1], &r[2], &r[3]);
+ sample_texel(mach->Samplers[sampler_unit],
+ &r[0],
+ &r[1],
+ &r[2],
+ &ZeroVec,
+ tgsi_sampler_lod_bias,
+ &r[0],
+ &r[1],
+ &r[2],
+ &r[3]);
break;
default:
@@ -1679,7 +1817,7 @@ exec_txd(struct tgsi_exec_machine *mach,
for (chan = 0; chan < NUM_CHANNELS; chan++) {
if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
- store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_UINT);
}
}
}
@@ -1757,7 +1895,7 @@ exec_declaration(struct tgsi_exec_machine *mach,
const struct tgsi_full_declaration *decl)
{
if (decl->Declaration.File == TGSI_FILE_RESOURCE) {
- mach->Resources[decl->Range.First] = decl->Resource;
+ mach->ResourceDecls[decl->Range.First] = decl->Resource;
return;
}
@@ -3249,7 +3387,10 @@ exec_instruction(
break;
case TGSI_OPCODE_TXF:
- assert (0);
+ /* texture fetch */
+ /* src[0] = resource */
+ /* src[1] = texcoord */
+ exec_txf(mach, inst);
break;
case TGSI_OPCODE_TXQ:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index 61189fe5cb..d5d558a5ac 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -94,6 +94,15 @@ struct tgsi_sampler
float rgba[NUM_CHANNELS][QUAD_SIZE]);
};
+struct tgsi_resource {
+ void (* fetch3D)(struct tgsi_resource *resource,
+ const int i[QUAD_SIZE],
+ const int j[QUAD_SIZE],
+ const int k[QUAD_SIZE],
+ const int lod[QUAD_SIZE],
+ float rgba[NUM_CHANNELS][QUAD_SIZE]);
+};
+
/**
* For branching/calling subroutines.
*/
@@ -331,7 +340,8 @@ struct tgsi_exec_machine
struct tgsi_exec_labels Labels;
- struct tgsi_declaration_resource Resources[PIPE_MAX_SHADER_RESOURCES];
+ struct tgsi_declaration_resource ResourceDecls[PIPE_MAX_SHADER_RESOURCES];
+ struct tgsi_resource **Resources;
};
struct tgsi_exec_machine *
@@ -341,12 +351,13 @@ void
tgsi_exec_machine_destroy(struct tgsi_exec_machine *mach);
-void
-tgsi_exec_machine_bind_shader(
- struct tgsi_exec_machine *mach,
- const struct tgsi_token *tokens,
- uint numSamplers,
- struct tgsi_sampler **samplers);
+void
+tgsi_exec_machine_bind_shader(struct tgsi_exec_machine *mach,
+ const struct tgsi_token *tokens,
+ uint numSamplers,
+ struct tgsi_sampler **samplers,
+ uint numResources,
+ struct tgsi_resource **resources);
uint
tgsi_exec_machine_run(
diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c
index 27fa126b7c..a12a249909 100644
--- a/src/gallium/drivers/softpipe/sp_fs_exec.c
+++ b/src/gallium/drivers/softpipe/sp_fs_exec.c
@@ -60,19 +60,22 @@ sp_exec_fragment_shader(const struct sp_fragment_shader *base)
static void
-exec_prepare( const struct sp_fragment_shader *base,
- struct tgsi_exec_machine *machine,
- struct tgsi_sampler **samplers )
+exec_prepare(const struct sp_fragment_shader *base,
+ struct tgsi_exec_machine *machine,
+ struct tgsi_sampler **samplers,
+ struct tgsi_resource **resources)
{
/*
* Bind tokens/shader to the interpreter's machine state.
* Avoid redundant binding.
*/
if (machine->Tokens != base->shader.tokens) {
- tgsi_exec_machine_bind_shader( machine,
- base->shader.tokens,
- PIPE_MAX_SAMPLERS,
- samplers );
+ tgsi_exec_machine_bind_shader(machine,
+ base->shader.tokens,
+ PIPE_MAX_SAMPLERS,
+ samplers,
+ PIPE_MAX_SHADER_RESOURCES,
+ resources);
}
}
diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c
index f912950658..882eb11b1a 100644
--- a/src/gallium/drivers/softpipe/sp_fs_sse.c
+++ b/src/gallium/drivers/softpipe/sp_fs_sse.c
@@ -68,11 +68,13 @@ sp_sse_fragment_shader(const struct sp_fragment_shader *base)
static void
-fs_sse_prepare( const struct sp_fragment_shader *base,
- struct tgsi_exec_machine *machine,
- struct tgsi_sampler **samplers )
+fs_sse_prepare(const struct sp_fragment_shader *base,
+ struct tgsi_exec_machine *machine,
+ struct tgsi_sampler **samplers,
+ struct tgsi_resource **resources)
{
machine->Samplers = samplers;
+ machine->Resources = resources;
}
diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c
index 1e7533d0f9..7a32b5f34c 100644
--- a/src/gallium/drivers/softpipe/sp_quad_fs.c
+++ b/src/gallium/drivers/softpipe/sp_quad_fs.c
@@ -142,10 +142,10 @@ shade_begin(struct quad_stage *qs)
struct quad_shade_stage *qss = quad_shade_stage(qs);
struct softpipe_context *softpipe = qs->softpipe;
- softpipe->fs->prepare( softpipe->fs,
- qss->machine,
- (struct tgsi_sampler **)
- softpipe->tgsi.frag_samplers_list );
+ softpipe->fs->prepare(softpipe->fs,
+ qss->machine,
+ (struct tgsi_sampler **)softpipe->tgsi.frag_samplers_list,
+ NULL);
qs->next->begin(qs->next);
}
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 9b18dac67b..b994640ef8 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -68,9 +68,10 @@ struct sp_fragment_shader {
struct tgsi_shader_info info;
- void (*prepare)( const struct sp_fragment_shader *shader,
- struct tgsi_exec_machine *machine,
- struct tgsi_sampler **samplers);
+ void (*prepare)(const struct sp_fragment_shader *shader,
+ struct tgsi_exec_machine *machine,
+ struct tgsi_sampler **samplers,
+ struct tgsi_resource **resources);
/* Run the shader - this interface will get cleaned up in the
* future: