summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Galibert <galibert@pobox.com>2012-05-17 16:48:54 +0200
committerJosé Fonseca <jose.r.fonseca@gmail.com>2012-05-18 00:27:28 +0100
commit5d10d757276a599a60a68b88b21087b5824a8df7 (patch)
treeb27a03dec6ac9b33f0522caf2b5e306229dbecce
parent1ec421823b1263a7b482adf48a15b186ea91efd2 (diff)
llvmpipe: Implement TXQ.
Piglits test for fragment shaders pass, vertex shaders fail. The actual failure seems to be in the interpolators, and not the textureSize query. Signed-off-by: Olivier Galibert <galibert@pobox.com> Reviewed-by: Roland Scheidegger <sroland@vmware.com> Reviewed-by: José Fonseca <jose.r.fonseca@gmail.com>
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm_sample.c23
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.c7
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.h14
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c73
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.h7
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c86
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample.c23
7 files changed, 227 insertions, 6 deletions
diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c
index 8af3461735..0a8b3bc535 100644
--- a/src/gallium/auxiliary/draw/draw_llvm_sample.c
+++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c
@@ -195,6 +195,28 @@ draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
}
+/**
+ * Fetch the texture size.
+ */
+static void
+draw_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
+ struct gallivm_state *gallivm,
+ unsigned unit,
+ LLVMValueRef explicit_lod, /* optional */
+ LLVMValueRef *sizes_out)
+{
+ struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa *)base;
+
+ assert(unit < PIPE_MAX_VERTEX_SAMPLERS);
+
+ lp_build_size_query_soa(gallivm,
+ &sampler->dynamic_state.static_state[unit],
+ &sampler->dynamic_state.base,
+ unit,
+ explicit_lod,
+ sizes_out);
+}
+
struct lp_build_sampler_soa *
draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
LLVMValueRef context_ptr)
@@ -207,6 +229,7 @@ draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
sampler->base.destroy = draw_llvm_sampler_soa_destroy;
sampler->base.emit_fetch_texel = draw_llvm_sampler_soa_emit_fetch_texel;
+ sampler->base.emit_size_query = draw_llvm_sampler_soa_emit_size_query;
sampler->dynamic_state.base.width = draw_llvm_texture_width;
sampler->dynamic_state.base.height = draw_llvm_texture_height;
sampler->dynamic_state.base.depth = draw_llvm_texture_depth;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index c6d4f1bcc2..2ffd9b8bfc 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -51,11 +51,6 @@
*/
#define BRILINEAR_FACTOR 2
-static LLVMValueRef
-lp_build_minify(struct lp_build_context *bld,
- LLVMValueRef base_size,
- LLVMValueRef level);
-
/**
* Does the given texture wrap mode allow sampling the texture border color?
* XXX maybe move this into gallium util code.
@@ -670,7 +665,7 @@ lp_build_get_const_mipmap_level(struct lp_build_sample_context *bld,
* Codegen equivalent for u_minify().
* Return max(1, base_size >> level);
*/
-static LLVMValueRef
+LLVMValueRef
lp_build_minify(struct lp_build_context *bld,
LLVMValueRef base_size,
LLVMValueRef level)
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
index a71e656fe0..8ccba2ca09 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -405,8 +405,22 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
LLVMValueRef texel_out[4]);
void
+lp_build_size_query_soa(struct gallivm_state *gallivm,
+ const struct lp_sampler_static_state *static_state,
+ struct lp_sampler_dynamic_state *dynamic_state,
+ unsigned unit,
+ LLVMValueRef explicit_lod,
+ LLVMValueRef *sizes_out);
+
+void
lp_build_sample_nop(struct gallivm_state *gallivm, struct lp_type type,
LLVMValueRef texel_out[4]);
+LLVMValueRef
+lp_build_minify(struct lp_build_context *bld,
+ LLVMValueRef base_size,
+ LLVMValueRef level);
+
+
#endif /* LP_BLD_SAMPLE_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 4ea7b4bd8a..73dc3e7708 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -35,6 +35,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
+#include "pipe/p_shader_tokens.h"
#include "util/u_debug.h"
#include "util/u_dump.h"
#include "util/u_memory.h"
@@ -1277,3 +1278,75 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
apply_sampler_swizzle(&bld, texel_out);
}
+
+void
+lp_build_size_query_soa(struct gallivm_state *gallivm,
+ const struct lp_sampler_static_state *static_state,
+ struct lp_sampler_dynamic_state *dynamic_state,
+ unsigned unit,
+ LLVMValueRef explicit_lod,
+ LLVMValueRef *sizes_out)
+{
+ LLVMValueRef lod;
+ LLVMValueRef size;
+ int dims, i;
+ struct lp_build_context bld_int_vec;
+
+ switch (static_state->target) {
+ case PIPE_TEXTURE_1D:
+ case PIPE_BUFFER:
+ dims = 1;
+ break;
+ case PIPE_TEXTURE_2D:
+ case PIPE_TEXTURE_CUBE:
+ case PIPE_TEXTURE_RECT:
+ dims = 2;
+ break;
+ case PIPE_TEXTURE_3D:
+ dims = 3;
+ break;
+
+ default:
+ assert(0);
+ return;
+ }
+
+ lp_build_context_init(&bld_int_vec, gallivm, lp_type_int_vec(32));
+
+ if (explicit_lod) {
+ LLVMValueRef first_level;
+ lod = LLVMBuildExtractElement(gallivm->builder, explicit_lod, lp_build_const_int32(gallivm, 0), "");
+ first_level = dynamic_state->first_level(dynamic_state, gallivm, unit);
+ lod = lp_build_broadcast_scalar(&bld_int_vec,
+ LLVMBuildAdd(gallivm->builder, lod, first_level, "lod"));
+
+ } else {
+ lod = bld_int_vec.zero;
+ }
+
+ size = bld_int_vec.undef;
+
+ size = LLVMBuildInsertElement(gallivm->builder, size,
+ dynamic_state->width(dynamic_state, gallivm, unit),
+ lp_build_const_int32(gallivm, 0), "");
+
+ if (dims >= 2) {
+ size = LLVMBuildInsertElement(gallivm->builder, size,
+ dynamic_state->height(dynamic_state, gallivm, unit),
+ lp_build_const_int32(gallivm, 1), "");
+ }
+
+ if (dims >= 3) {
+ size = LLVMBuildInsertElement(gallivm->builder, size,
+ dynamic_state->depth(dynamic_state, gallivm, unit),
+ lp_build_const_int32(gallivm, 2), "");
+ }
+
+ size = lp_build_minify(&bld_int_vec, size, lod);
+
+ for (i=0; i < dims; i++) {
+ sizes_out[i] = lp_build_extract_broadcast(gallivm, bld_int_vec.type, bld_int_vec.type,
+ size,
+ lp_build_const_int32(gallivm, i));
+ }
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
index 773c679a4d..141e799c4e 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
@@ -170,6 +170,13 @@ struct lp_build_sampler_soa
LLVMValueRef lod_bias, /* optional */
LLVMValueRef explicit_lod, /* optional */
LLVMValueRef *texel);
+
+ void
+ (*emit_size_query)( const struct lp_build_sampler_soa *sampler,
+ struct gallivm_state *gallivm,
+ unsigned unit,
+ LLVMValueRef explicit_lod, /* optional */
+ LLVMValueRef *sizes_out);
};
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index cca7ef5f89..a9d69a3259 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -1209,6 +1209,80 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
texel);
}
+static void
+emit_txq( struct lp_build_tgsi_soa_context *bld,
+ const struct tgsi_full_instruction *inst,
+ LLVMValueRef *sizes_out)
+{
+ LLVMValueRef explicit_lod;
+ unsigned num_coords, has_lod;
+ unsigned i;
+
+ switch (inst->Texture.Texture) {
+ case TGSI_TEXTURE_1D:
+ case TGSI_TEXTURE_SHADOW1D:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_SHADOWCUBE:
+ num_coords = 1;
+ has_lod = 1;
+ break;
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_CUBE:
+ case TGSI_TEXTURE_1D_ARRAY:
+ case TGSI_TEXTURE_SHADOW1D_ARRAY:
+ num_coords = 2;
+ has_lod = 1;
+ break;
+ case TGSI_TEXTURE_3D:
+// case TGSI_TEXTURE_CUBE_ARRAY:
+// case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
+ case TGSI_TEXTURE_2D_ARRAY:
+ case TGSI_TEXTURE_SHADOW2D_ARRAY:
+ num_coords = 3;
+ has_lod = 1;
+ break;
+
+ case TGSI_TEXTURE_BUFFER:
+ num_coords = 1;
+ has_lod = 0;
+ break;
+
+ case TGSI_TEXTURE_RECT:
+ case TGSI_TEXTURE_SHADOWRECT:
+// case TGSI_TEXTURE_2D_MS:
+ num_coords = 2;
+ has_lod = 0;
+ break;
+
+// case TGSI_TEXTURE_2D_MS_ARRAY:
+// num_coords = 3;
+// has_lod = 0;
+// break;
+
+ default:
+ assert(0);
+ return;
+ }
+
+ if (!bld->sampler) {
+ _debug_printf("warning: found texture query instruction but no sampler generator supplied\n");
+ for (i = 0; i < num_coords; i++)
+ sizes_out[i] = bld->bld_base.base.undef;
+ return;
+ }
+
+ if (has_lod)
+ explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 2 );
+ else
+ explicit_lod = NULL;
+
+ bld->sampler->emit_size_query(bld->sampler,
+ bld->bld_base.base.gallivm,
+ inst->Src[1].Register.Index,
+ explicit_lod,
+ sizes_out);
+}
+
static boolean
near_end_of_shader(struct lp_build_tgsi_soa_context *bld,
int pc)
@@ -1585,6 +1659,17 @@ txp_emit(
}
static void
+txq_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
+
+ emit_txq(bld, emit_data->inst, emit_data->output);
+}
+
+static void
cal_emit(
const struct lp_build_tgsi_action * action,
struct lp_build_tgsi_context * bld_base,
@@ -1954,6 +2039,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm,
bld.bld_base.op_actions[TGSI_OPCODE_TXD].emit = txd_emit;
bld.bld_base.op_actions[TGSI_OPCODE_TXL].emit = txl_emit;
bld.bld_base.op_actions[TGSI_OPCODE_TXP].emit = txp_emit;
+ bld.bld_base.op_actions[TGSI_OPCODE_TXQ].emit = txq_emit;
lp_exec_mask_init(&bld.exec_mask, &bld.bld_base.base);
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
index ccc139603e..daa96f20c7 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
@@ -204,6 +204,28 @@ lp_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
texel);
}
+/**
+ * Fetch the texture size.
+ */
+static void
+lp_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
+ struct gallivm_state *gallivm,
+ unsigned unit,
+ LLVMValueRef explicit_lod, /* optional */
+ LLVMValueRef *sizes_out)
+{
+ struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base;
+
+ assert(unit < PIPE_MAX_SAMPLERS);
+
+ lp_build_size_query_soa(gallivm,
+ &sampler->dynamic_state.static_state[unit],
+ &sampler->dynamic_state.base,
+ unit,
+ explicit_lod,
+ sizes_out);
+}
+
struct lp_build_sampler_soa *
lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
@@ -217,6 +239,7 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
sampler->base.destroy = lp_llvm_sampler_soa_destroy;
sampler->base.emit_fetch_texel = lp_llvm_sampler_soa_emit_fetch_texel;
+ sampler->base.emit_size_query = lp_llvm_sampler_soa_emit_size_query;
sampler->dynamic_state.base.width = lp_llvm_texture_width;
sampler->dynamic_state.base.height = lp_llvm_texture_height;
sampler->dynamic_state.base.depth = lp_llvm_texture_depth;