summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2009-08-25 08:05:31 +0100
committerJosé Fonseca <[email protected]>2009-08-29 09:21:42 +0100
commitc40eddd294abfe8af3619d08ccd7e9c8f1660fcb (patch)
tree6723081feab6f7376197c58afbe585d68f8e110e /src/gallium/drivers/llvmpipe
parentd4806c64a23b8dfc58313b54e607f6c3cd8ae5ff (diff)
llvmpipe: Isolate sampling from TGSI translation.
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_tgsi.h17
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c102
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c112
5 files changed, 145 insertions, 94 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h b/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h
index d42ab99cf82..912db24aecb 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h
@@ -39,15 +39,19 @@
struct tgsi_token;
-struct tgsi_sampler;
union lp_type;
struct lp_build_context;
struct lp_build_mask_context;
-void PIPE_CDECL
-lp_build_tgsi_fetch_texel_soa( struct tgsi_sampler **samplers,
- uint32_t unit,
- float *store );
+
+typedef void
+(*lp_emit_fetch_texel_soa_callback)( LLVMBuilderRef builder,
+ void *context,
+ unsigned unit,
+ unsigned num_coords,
+ const LLVMValueRef *coords,
+ LLVMValueRef lodbias,
+ LLVMValueRef *texel);
void
lp_build_tgsi_soa(LLVMBuilderRef builder,
@@ -58,7 +62,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
const LLVMValueRef *pos,
const LLVMValueRef (*inputs)[4],
LLVMValueRef (*outputs)[4],
- LLVMValueRef samplers_ptr);
+ lp_emit_fetch_texel_soa_callback emit_fetch_texel,
+ void *emit_fetch_texel_context);
#endif /* LP_BLD_TGSI_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
index 1335ba862eb..0c837188cac 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
@@ -87,15 +87,14 @@ struct lp_build_tgsi_soa_context
const LLVMValueRef *pos;
const LLVMValueRef (*inputs)[NUM_CHANNELS];
LLVMValueRef (*outputs)[NUM_CHANNELS];
- LLVMValueRef samplers_ptr;
+
+ lp_emit_fetch_texel_soa_callback emit_fetch_texel;
+ void *emit_fetch_texel_context;
LLVMValueRef immediates[LP_MAX_IMMEDIATES][NUM_CHANNELS];
LLVMValueRef temps[LP_MAX_TEMPS][NUM_CHANNELS];
struct lp_build_mask_context *mask;
-
- /** Coords/texels store */
- LLVMValueRef store_ptr;
};
@@ -236,52 +235,6 @@ emit_store(
}
-void PIPE_CDECL
-lp_build_tgsi_fetch_texel_soa( struct tgsi_sampler **samplers,
- uint32_t unit,
- float *store )
-{
- struct tgsi_sampler *sampler = samplers[unit];
-
-#if 0
- uint j;
-
- debug_printf("%s sampler: %p (%p) store: %p\n",
- __FUNCTION__,
- sampler, *sampler,
- store );
-
- debug_printf("lodbias %f\n", store[12]);
-
- for (j = 0; j < 4; j++)
- debug_printf("sample %d texcoord %f %f\n",
- j,
- store[0+j],
- store[4+j]);
-#endif
-
- {
- float rgba[NUM_CHANNELS][QUAD_SIZE];
- sampler->get_samples(sampler,
- &store[0],
- &store[4],
- &store[8],
- 0.0f, /*store[12], lodbias */
- rgba);
- memcpy(store, rgba, sizeof rgba);
- }
-
-#if 0
- for (j = 0; j < 4; j++)
- debug_printf("sample %d result %f %f %f %f\n",
- j,
- store[0+j],
- store[4+j],
- store[8+j],
- store[12+j]);
-#endif
-}
-
/**
* High-level instruction translators.
*/
@@ -292,28 +245,28 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
boolean apply_lodbias,
boolean projected)
{
- LLVMTypeRef vec_type = lp_build_vec_type(bld->base.type);
const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
LLVMValueRef lodbias;
LLVMValueRef oow;
- LLVMValueRef args[3];
- unsigned count;
+ LLVMValueRef coords[3];
+ LLVMValueRef texel[4];
+ unsigned num_coords;
unsigned i;
switch (inst->InstructionExtTexture.Texture) {
case TGSI_TEXTURE_1D:
case TGSI_TEXTURE_SHADOW1D:
- count = 1;
+ num_coords = 1;
break;
case TGSI_TEXTURE_2D:
case TGSI_TEXTURE_RECT:
case TGSI_TEXTURE_SHADOW2D:
case TGSI_TEXTURE_SHADOWRECT:
- count = 2;
+ num_coords = 2;
break;
case TGSI_TEXTURE_3D:
case TGSI_TEXTURE_CUBE:
- count = 3;
+ num_coords = 3;
break;
default:
assert(0);
@@ -325,41 +278,22 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
else
lodbias = bld->base.zero;
- if(!bld->store_ptr)
- bld->store_ptr = LLVMBuildArrayAlloca(bld->base.builder,
- vec_type,
- LLVMConstInt(LLVMInt32Type(), 4, 0),
- "store");
-
if (projected) {
oow = emit_fetch( bld, inst, 0, 3 );
oow = lp_build_rcp(&bld->base, oow);
}
- for (i = 0; i < count; i++) {
- LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
- LLVMValueRef coord_ptr = LLVMBuildGEP(bld->base.builder, bld->store_ptr, &index, 1, "");
- LLVMValueRef coord;
-
- coord = emit_fetch( bld, inst, 0, i );
-
+ for (i = 0; i < num_coords; i++) {
+ coords[i] = emit_fetch( bld, inst, 0, i );
if (projected)
- coord = lp_build_mul(&bld->base, coord, oow);
-
- LLVMBuildStore(bld->base.builder, coord, coord_ptr);
+ coords[i] = lp_build_mul(&bld->base, coords[i], oow);
}
- args[0] = bld->samplers_ptr;
- args[1] = LLVMConstInt(LLVMInt32Type(), unit, 0);
- args[2] = bld->store_ptr;
-
- lp_build_intrinsic(bld->base.builder, "fetch_texel", LLVMVoidType(), args, 3);
+ bld->emit_fetch_texel(bld->base.builder, bld->emit_fetch_texel_context,
+ unit, num_coords, coords, lodbias, texel);
FOR_EACH_DST0_ENABLED_CHANNEL( inst, i ) {
- LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
- LLVMValueRef res_ptr = LLVMBuildGEP(bld->base.builder, bld->store_ptr, &index, 1, "");
- LLVMValueRef res = LLVMBuildLoad(bld->base.builder, res_ptr, "");
- emit_store( bld, inst, 0, i, res );
+ emit_store( bld, inst, 0, i, texel[i] );
}
}
@@ -1353,7 +1287,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
const LLVMValueRef *pos,
const LLVMValueRef (*inputs)[NUM_CHANNELS],
LLVMValueRef (*outputs)[NUM_CHANNELS],
- LLVMValueRef samplers_ptr)
+ lp_emit_fetch_texel_soa_callback emit_fetch_texel,
+ void *emit_fetch_texel_context)
{
struct lp_build_tgsi_soa_context bld;
struct tgsi_parse_context parse;
@@ -1368,7 +1303,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
bld.inputs = inputs;
bld.outputs = outputs;
bld.consts_ptr = consts_ptr;
- bld.samplers_ptr = samplers_ptr;
+ bld.emit_fetch_texel = emit_fetch_texel;
+ bld.emit_fetch_texel_context = emit_fetch_texel_context;
tgsi_parse_init( &parse, tokens );
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 39c4df83633..d288460a1b8 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -38,7 +38,6 @@
#include "util/u_memory.h"
#include "lp_screen.h"
#include "lp_bld_intr.h"
-#include "lp_bld_tgsi.h" /* for lp_build_tgsi_fetch_texel_soa */
#include "lp_jit.h"
@@ -88,7 +87,7 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
fetch_texel = lp_declare_intrinsic(screen->module, "fetch_texel",
ret_type, arg_types, Elements(arg_types));
- LLVMAddGlobalMapping(screen->engine, fetch_texel, lp_build_tgsi_fetch_texel_soa);
+ LLVMAddGlobalMapping(screen->engine, fetch_texel, lp_fetch_texel_soa);
}
#ifdef DEBUG
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 33010ad5fb8..a7fb60f9f5c 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -92,6 +92,11 @@ typedef void
void *color,
void *depth);
+void PIPE_CDECL
+lp_fetch_texel_soa( struct tgsi_sampler **samplers,
+ uint32_t unit,
+ float *store );
+
void
lp_jit_screen_cleanup(struct llvmpipe_screen *screen);
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 4981432eb38..94170bd7161 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -71,6 +71,7 @@
#include "lp_bld_type.h"
#include "lp_bld_const.h"
#include "lp_bld_conv.h"
+#include "lp_bld_intr.h"
#include "lp_bld_logic.h"
#include "lp_bld_depth.h"
#include "lp_bld_interp.h"
@@ -172,6 +173,107 @@ generate_depth(struct llvmpipe_context *lp,
}
+struct build_fetch_texel_context
+{
+ LLVMValueRef context_ptr;
+
+ LLVMValueRef samplers_ptr;
+
+ /** Coords/texels store */
+ LLVMValueRef store_ptr;
+};
+
+
+void PIPE_CDECL
+lp_fetch_texel_soa( struct tgsi_sampler **samplers,
+ uint32_t unit,
+ float *store )
+{
+ struct tgsi_sampler *sampler = samplers[unit];
+
+#if 0
+ uint j;
+
+ debug_printf("%s sampler: %p (%p) store: %p\n",
+ __FUNCTION__,
+ sampler, *sampler,
+ store );
+
+ debug_printf("lodbias %f\n", store[12]);
+
+ for (j = 0; j < 4; j++)
+ debug_printf("sample %d texcoord %f %f\n",
+ j,
+ store[0+j],
+ store[4+j]);
+#endif
+
+ {
+ float rgba[NUM_CHANNELS][QUAD_SIZE];
+ sampler->get_samples(sampler,
+ &store[0],
+ &store[4],
+ &store[8],
+ 0.0f, /*store[12], lodbias */
+ rgba);
+ memcpy(store, rgba, sizeof rgba);
+ }
+
+#if 0
+ for (j = 0; j < 4; j++)
+ debug_printf("sample %d result %f %f %f %f\n",
+ j,
+ store[0+j],
+ store[4+j],
+ store[8+j],
+ store[12+j]);
+#endif
+}
+
+
+static void
+emit_fetch_texel( LLVMBuilderRef builder,
+ void *context,
+ unsigned unit,
+ unsigned num_coords,
+ const LLVMValueRef *coords,
+ LLVMValueRef lodbias,
+ LLVMValueRef *texel)
+{
+ struct build_fetch_texel_context *bld = context;
+ LLVMTypeRef vec_type = LLVMTypeOf(coords[0]);
+ LLVMValueRef args[3];
+ unsigned i;
+
+ if(!bld->samplers_ptr)
+ bld->samplers_ptr = lp_jit_context_samplers(builder, bld->context_ptr);
+
+ if(!bld->store_ptr)
+ bld->store_ptr = LLVMBuildArrayAlloca(builder,
+ vec_type,
+ LLVMConstInt(LLVMInt32Type(), 4, 0),
+ "texel_store");
+
+ for (i = 0; i < num_coords; i++) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ LLVMValueRef coord_ptr = LLVMBuildGEP(builder, bld->store_ptr, &index, 1, "");
+ LLVMBuildStore(builder, coords[i], coord_ptr);
+ }
+
+ args[0] = bld->samplers_ptr;
+ args[1] = LLVMConstInt(LLVMInt32Type(), unit, 0);
+ args[2] = bld->store_ptr;
+
+ lp_build_intrinsic(builder, "fetch_texel", LLVMVoidType(), args, 3);
+
+ for (i = 0; i < NUM_CHANNELS; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ LLVMValueRef texel_ptr = LLVMBuildGEP(builder, bld->store_ptr, &index, 1, "");
+ texel[i] = LLVMBuildLoad(builder, texel_ptr, "");
+ }
+}
+
+
/**
* Generate the fragment shader, depth/stencil test, and alpha tests.
*/
@@ -184,6 +286,7 @@ generate_fs(struct llvmpipe_context *lp,
LLVMValueRef context_ptr,
unsigned i,
const struct lp_build_interp_soa_context *interp,
+ struct build_fetch_texel_context *sampler,
LLVMValueRef *pmask,
LLVMValueRef *color,
LLVMValueRef depth_ptr)
@@ -193,7 +296,6 @@ generate_fs(struct llvmpipe_context *lp,
LLVMTypeRef vec_type;
LLVMTypeRef int_vec_type;
LLVMValueRef consts_ptr;
- LLVMValueRef samplers_ptr;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
LLVMValueRef z = interp->pos[2];
struct lp_build_mask_context mask;
@@ -206,7 +308,6 @@ generate_fs(struct llvmpipe_context *lp,
int_vec_type = lp_build_int_vec_type(type);
consts_ptr = lp_jit_context_constants(builder, context_ptr);
- samplers_ptr = lp_jit_context_samplers(builder, context_ptr);
lp_build_mask_begin(&mask, builder, type, *pmask);
@@ -226,7 +327,7 @@ generate_fs(struct llvmpipe_context *lp,
lp_build_tgsi_soa(builder, tokens, type, &mask,
consts_ptr, interp->pos, interp->inputs,
- outputs, samplers_ptr);
+ outputs, emit_fetch_texel, sampler);
for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) {
for(chan = 0; chan < NUM_CHANNELS; ++chan) {
@@ -361,6 +462,7 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMBuilderRef builder;
LLVMValueRef x0;
LLVMValueRef y0;
+ struct build_fetch_texel_context sampler;
struct lp_build_interp_soa_context interp;
LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH];
LLVMValueRef fs_out_color[NUM_CHANNELS][LP_MAX_VECTOR_LENGTH];
@@ -484,6 +586,9 @@ generate_fragment(struct llvmpipe_context *lp,
a0_ptr, dadx_ptr, dady_ptr,
x0, y0, 2, 0);
+ memset(&sampler, 0, sizeof sampler);
+ sampler.context_ptr = context_ptr;
+
for(i = 0; i < num_fs; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
LLVMValueRef out_color[NUM_CHANNELS];
@@ -501,6 +606,7 @@ generate_fragment(struct llvmpipe_context *lp,
context_ptr,
i,
&interp,
+ &sampler,
&fs_mask[i],
out_color,
depth_ptr_i);