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>
This commit is contained in:
parent
1ec421823b
commit
5d10d75727
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -404,9 +404,23 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
|
|||
LLVMValueRef explicit_lod,
|
||||
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 */
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
@ -1584,6 +1658,17 @@ txp_emit(
|
|||
emit_data->output);
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue