llvmpipe/draw: Fix texture sampling in geometry shaders
We weren't correctly propagating the samplers and sampler views when they were related to geometry shaders. Signed-off-by: Zack Rusin <zackr@vmware.com> Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: José Fonseca <jfonseca@vmware.com>
This commit is contained in:
parent
186a6bffdd
commit
d066133a76
|
@ -792,8 +792,8 @@ draw_set_samplers(struct draw_context *draw,
|
|||
draw->num_samplers[shader_stage] = num;
|
||||
|
||||
#ifdef HAVE_LLVM
|
||||
if (draw->llvm && shader_stage == PIPE_SHADER_VERTEX)
|
||||
draw_llvm_set_sampler_state(draw);
|
||||
if (draw->llvm)
|
||||
draw_llvm_set_sampler_state(draw, shader_stage);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ create_gs_jit_context_type(struct gallivm_state *gallivm,
|
|||
LLVMTargetDataRef target = gallivm->target;
|
||||
LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context);
|
||||
LLVMTypeRef int_type = LLVMInt32TypeInContext(gallivm->context);
|
||||
LLVMTypeRef elem_types[8];
|
||||
LLVMTypeRef elem_types[DRAW_GS_JIT_CTX_NUM_FIELDS];
|
||||
LLVMTypeRef context_type;
|
||||
|
||||
elem_types[0] = LLVMArrayType(LLVMPointerType(float_type, 0), /* constants */
|
||||
|
@ -249,17 +249,17 @@ create_gs_jit_context_type(struct gallivm_state *gallivm,
|
|||
elem_types[1] = LLVMPointerType(LLVMArrayType(LLVMArrayType(float_type, 4),
|
||||
DRAW_TOTAL_CLIP_PLANES), 0);
|
||||
elem_types[2] = LLVMPointerType(float_type, 0); /* viewport */
|
||||
|
||||
elem_types[3] = LLVMPointerType(LLVMPointerType(int_type, 0), 0);
|
||||
elem_types[4] = LLVMPointerType(LLVMVectorType(int_type,
|
||||
vector_length), 0);
|
||||
elem_types[5] = LLVMPointerType(LLVMVectorType(int_type,
|
||||
vector_length), 0);
|
||||
|
||||
elem_types[6] = LLVMArrayType(texture_type,
|
||||
elem_types[3] = LLVMArrayType(texture_type,
|
||||
PIPE_MAX_SHADER_SAMPLER_VIEWS); /* textures */
|
||||
elem_types[7] = LLVMArrayType(sampler_type,
|
||||
elem_types[4] = LLVMArrayType(sampler_type,
|
||||
PIPE_MAX_SAMPLERS); /* samplers */
|
||||
|
||||
elem_types[5] = LLVMPointerType(LLVMPointerType(int_type, 0), 0);
|
||||
elem_types[6] = LLVMPointerType(LLVMVectorType(int_type,
|
||||
vector_length), 0);
|
||||
elem_types[7] = LLVMPointerType(LLVMVectorType(int_type,
|
||||
vector_length), 0);
|
||||
|
||||
context_type = LLVMStructTypeInContext(gallivm->context, elem_types,
|
||||
Elements(elem_types), 0);
|
||||
|
@ -270,23 +270,26 @@ create_gs_jit_context_type(struct gallivm_state *gallivm,
|
|||
#endif
|
||||
|
||||
LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, constants,
|
||||
target, context_type, 0);
|
||||
target, context_type, DRAW_GS_JIT_CTX_CONSTANTS);
|
||||
LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, planes,
|
||||
target, context_type, 1);
|
||||
target, context_type, DRAW_GS_JIT_CTX_PLANES);
|
||||
LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, viewport,
|
||||
target, context_type, 2);
|
||||
LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, prim_lengths,
|
||||
target, context_type, 3);
|
||||
LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, emitted_vertices,
|
||||
target, context_type, 4);
|
||||
LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, emitted_prims,
|
||||
target, context_type, 5);
|
||||
target, context_type, DRAW_GS_JIT_CTX_VIEWPORT);
|
||||
LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, textures,
|
||||
target, context_type,
|
||||
DRAW_GS_JIT_CTX_TEXTURES);
|
||||
LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, samplers,
|
||||
target, context_type,
|
||||
DRAW_GS_JIT_CTX_SAMPLERS);
|
||||
LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, prim_lengths,
|
||||
target, context_type,
|
||||
DRAW_GS_JIT_CTX_PRIM_LENGTHS);
|
||||
LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, emitted_vertices,
|
||||
target, context_type,
|
||||
DRAW_GS_JIT_CTX_EMITTED_VERTICES);
|
||||
LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, emitted_prims,
|
||||
target, context_type,
|
||||
DRAW_GS_JIT_CTX_EMITTED_PRIMS);
|
||||
LP_CHECK_STRUCT_SIZE(struct draw_gs_jit_context,
|
||||
target, context_type);
|
||||
|
||||
|
@ -1721,33 +1724,36 @@ draw_llvm_set_mapped_texture(struct draw_context *draw,
|
|||
|
||||
|
||||
void
|
||||
draw_llvm_set_sampler_state(struct draw_context *draw)
|
||||
draw_llvm_set_sampler_state(struct draw_context *draw,
|
||||
unsigned shader_type)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < draw->num_samplers[PIPE_SHADER_VERTEX]; i++) {
|
||||
struct draw_jit_sampler *jit_sam = &draw->llvm->jit_context.samplers[i];
|
||||
if (shader_type == PIPE_SHADER_VERTEX) {
|
||||
for (i = 0; i < draw->num_samplers[PIPE_SHADER_VERTEX]; i++) {
|
||||
struct draw_jit_sampler *jit_sam = &draw->llvm->jit_context.samplers[i];
|
||||
|
||||
if (draw->samplers[i]) {
|
||||
const struct pipe_sampler_state *s
|
||||
= draw->samplers[PIPE_SHADER_VERTEX][i];
|
||||
jit_sam->min_lod = s->min_lod;
|
||||
jit_sam->max_lod = s->max_lod;
|
||||
jit_sam->lod_bias = s->lod_bias;
|
||||
COPY_4V(jit_sam->border_color, s->border_color.f);
|
||||
if (draw->samplers[i]) {
|
||||
const struct pipe_sampler_state *s
|
||||
= draw->samplers[PIPE_SHADER_VERTEX][i];
|
||||
jit_sam->min_lod = s->min_lod;
|
||||
jit_sam->max_lod = s->max_lod;
|
||||
jit_sam->lod_bias = s->lod_bias;
|
||||
COPY_4V(jit_sam->border_color, s->border_color.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (shader_type == PIPE_SHADER_GEOMETRY) {
|
||||
for (i = 0; i < draw->num_samplers[PIPE_SHADER_GEOMETRY]; i++) {
|
||||
struct draw_jit_sampler *jit_sam = &draw->llvm->gs_jit_context.samplers[i];
|
||||
|
||||
for (i = 0; i < draw->num_samplers[PIPE_SHADER_GEOMETRY]; i++) {
|
||||
struct draw_jit_sampler *jit_sam = &draw->llvm->gs_jit_context.samplers[i];
|
||||
|
||||
if (draw->samplers[i]) {
|
||||
const struct pipe_sampler_state *s
|
||||
= draw->samplers[PIPE_SHADER_GEOMETRY][i];
|
||||
jit_sam->min_lod = s->min_lod;
|
||||
jit_sam->max_lod = s->max_lod;
|
||||
jit_sam->lod_bias = s->lod_bias;
|
||||
COPY_4V(jit_sam->border_color, s->border_color.f);
|
||||
if (draw->samplers[i]) {
|
||||
const struct pipe_sampler_state *s
|
||||
= draw->samplers[PIPE_SHADER_GEOMETRY][i];
|
||||
jit_sam->min_lod = s->min_lod;
|
||||
jit_sam->max_lod = s->max_lod;
|
||||
jit_sam->lod_bias = s->lod_bias;
|
||||
COPY_4V(jit_sam->border_color, s->border_color.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1951,6 +1957,8 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
|
|||
&llvm->draw->gs.geometry_shader->info,
|
||||
&gs_iface);
|
||||
|
||||
sampler->destroy(sampler);
|
||||
|
||||
lp_build_mask_end(&mask);
|
||||
|
||||
LLVMBuildRet(builder, lp_build_zero(gallivm, lp_type_uint(32)));
|
||||
|
|
|
@ -186,35 +186,40 @@ struct draw_gs_jit_context
|
|||
float (*planes) [DRAW_TOTAL_CLIP_PLANES][4];
|
||||
float *viewport;
|
||||
|
||||
/* There two need to be exactly at DRAW_JIT_CTX_TEXTURES and
|
||||
* DRAW_JIT_CTX_SAMPLERS positions in the struct */
|
||||
struct draw_jit_texture textures[PIPE_MAX_SHADER_SAMPLER_VIEWS];
|
||||
struct draw_jit_sampler samplers[PIPE_MAX_SAMPLERS];
|
||||
|
||||
int **prim_lengths;
|
||||
int *emitted_vertices;
|
||||
int *emitted_prims;
|
||||
|
||||
struct draw_jit_texture textures[PIPE_MAX_SHADER_SAMPLER_VIEWS];
|
||||
struct draw_jit_sampler samplers[PIPE_MAX_SAMPLERS];
|
||||
};
|
||||
|
||||
enum {
|
||||
DRAW_GS_JIT_CTX_CONSTANTS = 0,
|
||||
DRAW_GS_JIT_CTX_PLANES = 1,
|
||||
DRAW_GS_JIT_CTX_VIEWPORT = 2,
|
||||
/* Textures and samples are reserved for DRAW_JIT_CTX_TEXTURES
|
||||
* and DRAW_JIT_CTX_SAMPLERS, because they both need
|
||||
* to be at exactly the same locations as they are in the
|
||||
* VS ctx structure for sampling to work. */
|
||||
DRAW_GS_JIT_CTX_TEXTURES = DRAW_JIT_CTX_TEXTURES,
|
||||
DRAW_GS_JIT_CTX_SAMPLERS = DRAW_JIT_CTX_SAMPLERS,
|
||||
DRAW_GS_JIT_CTX_PRIM_LENGTHS = 5,
|
||||
DRAW_GS_JIT_CTX_EMITTED_VERTICES = 6,
|
||||
DRAW_GS_JIT_CTX_EMITTED_PRIMS = 7,
|
||||
DRAW_GS_JIT_CTX_NUM_FIELDS = 8
|
||||
};
|
||||
|
||||
#define draw_gs_jit_context_constants(_gallivm, _ptr) \
|
||||
lp_build_struct_get_ptr(_gallivm, _ptr, 0, "constants")
|
||||
lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_GS_JIT_CTX_CONSTANTS, "constants")
|
||||
|
||||
#define draw_gs_jit_context_planes(_gallivm, _ptr) \
|
||||
lp_build_struct_get(_gallivm, _ptr, 1, "planes")
|
||||
lp_build_struct_get(_gallivm, _ptr, DRAW_GS_JIT_CTX_PLANES, "planes")
|
||||
|
||||
#define draw_gs_jit_context_viewport(_gallivm, _ptr) \
|
||||
lp_build_struct_get(_gallivm, _ptr, 2, "viewport")
|
||||
|
||||
#define draw_gs_jit_prim_lengths(_gallivm, _ptr) \
|
||||
lp_build_struct_get(_gallivm, _ptr, 3, "prim_lengths")
|
||||
|
||||
#define draw_gs_jit_emitted_vertices(_gallivm, _ptr) \
|
||||
lp_build_struct_get(_gallivm, _ptr, 4, "emitted_vertices")
|
||||
|
||||
#define draw_gs_jit_emitted_prims(_gallivm, _ptr) \
|
||||
lp_build_struct_get(_gallivm, _ptr, 5, "emitted_prims")
|
||||
|
||||
#define DRAW_GS_JIT_CTX_TEXTURES 6
|
||||
#define DRAW_GS_JIT_CTX_SAMPLERS 7
|
||||
lp_build_struct_get(_gallivm, _ptr, DRAW_GS_JIT_CTX_VIEWPORT, "viewport")
|
||||
|
||||
#define draw_gs_jit_context_textures(_gallivm, _ptr) \
|
||||
lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_GS_JIT_CTX_TEXTURES, "textures")
|
||||
|
@ -222,6 +227,15 @@ struct draw_gs_jit_context
|
|||
#define draw_gs_jit_context_samplers(_gallivm, _ptr) \
|
||||
lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_GS_JIT_CTX_SAMPLERS, "samplers")
|
||||
|
||||
#define draw_gs_jit_prim_lengths(_gallivm, _ptr) \
|
||||
lp_build_struct_get(_gallivm, _ptr, DRAW_GS_JIT_CTX_PRIM_LENGTHS, "prim_lengths")
|
||||
|
||||
#define draw_gs_jit_emitted_vertices(_gallivm, _ptr) \
|
||||
lp_build_struct_get(_gallivm, _ptr, DRAW_GS_JIT_CTX_EMITTED_VERTICES, "emitted_vertices")
|
||||
|
||||
#define draw_gs_jit_emitted_prims(_gallivm, _ptr) \
|
||||
lp_build_struct_get(_gallivm, _ptr, DRAW_GS_JIT_CTX_EMITTED_PRIMS, "emitted_prims")
|
||||
|
||||
|
||||
|
||||
typedef int
|
||||
|
@ -478,7 +492,7 @@ draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_stat
|
|||
LLVMValueRef context_ptr);
|
||||
|
||||
void
|
||||
draw_llvm_set_sampler_state(struct draw_context *draw);
|
||||
draw_llvm_set_sampler_state(struct draw_context *draw, unsigned shader_stage);
|
||||
|
||||
void
|
||||
draw_llvm_set_mapped_texture(struct draw_context *draw,
|
||||
|
|
|
@ -81,6 +81,10 @@ static void llvmpipe_destroy( struct pipe_context *pipe )
|
|||
pipe_sampler_view_reference(&llvmpipe->sampler_views[PIPE_SHADER_VERTEX][i], NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < Elements(llvmpipe->sampler_views[0]); i++) {
|
||||
pipe_sampler_view_reference(&llvmpipe->sampler_views[PIPE_SHADER_GEOMETRY][i], NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < Elements(llvmpipe->constants); i++) {
|
||||
for (j = 0; j < Elements(llvmpipe->constants[i]); j++) {
|
||||
pipe_resource_reference(&llvmpipe->constants[i][j].buffer, NULL);
|
||||
|
|
|
@ -82,6 +82,7 @@ struct llvmpipe_context {
|
|||
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
||||
struct pipe_index_buffer index_buffer;
|
||||
struct pipe_resource *mapped_vs_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS];
|
||||
struct pipe_resource *mapped_gs_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS];
|
||||
|
||||
unsigned num_samplers[PIPE_SHADER_TYPES];
|
||||
unsigned num_sampler_views[PIPE_SHADER_TYPES];
|
||||
|
|
|
@ -98,6 +98,9 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||
llvmpipe_prepare_vertex_sampling(lp,
|
||||
lp->num_sampler_views[PIPE_SHADER_VERTEX],
|
||||
lp->sampler_views[PIPE_SHADER_VERTEX]);
|
||||
llvmpipe_prepare_geometry_sampling(lp,
|
||||
lp->num_sampler_views[PIPE_SHADER_GEOMETRY],
|
||||
lp->sampler_views[PIPE_SHADER_GEOMETRY]);
|
||||
|
||||
/* draw! */
|
||||
draw_vbo(draw, info);
|
||||
|
@ -114,6 +117,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||
draw_set_mapped_so_targets(draw, 0, NULL);
|
||||
|
||||
llvmpipe_cleanup_vertex_sampling(lp);
|
||||
llvmpipe_cleanup_geometry_sampling(lp);
|
||||
|
||||
/*
|
||||
* TODO: Flush only when a user vertex/index buffer is present
|
||||
|
|
|
@ -141,4 +141,12 @@ void
|
|||
llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx);
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_prepare_geometry_sampling(struct llvmpipe_context *ctx,
|
||||
unsigned num,
|
||||
struct pipe_sampler_view **views);
|
||||
void
|
||||
llvmpipe_cleanup_geometry_sampling(struct llvmpipe_context *ctx);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -250,14 +250,15 @@ llvmpipe_delete_sampler_state(struct pipe_context *pipe,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called during state validation when LP_NEW_SAMPLER_VIEW is set.
|
||||
*/
|
||||
void
|
||||
llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
|
||||
unsigned num,
|
||||
struct pipe_sampler_view **views)
|
||||
static void
|
||||
prepare_shader_sampling(
|
||||
struct llvmpipe_context *lp,
|
||||
unsigned num,
|
||||
struct pipe_sampler_view **views,
|
||||
unsigned shader_type,
|
||||
struct pipe_resource *mapped_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS])
|
||||
{
|
||||
|
||||
unsigned i;
|
||||
uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
|
||||
uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
|
||||
|
@ -282,7 +283,7 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
|
|||
/* We're referencing the texture's internal data, so save a
|
||||
* reference to it.
|
||||
*/
|
||||
pipe_resource_reference(&lp->mapped_vs_tex[i], tex);
|
||||
pipe_resource_reference(&mapped_tex[i], tex);
|
||||
|
||||
if (!lp_tex->dt) {
|
||||
/* regular texture - setup array of mipmap level offsets */
|
||||
|
@ -357,7 +358,7 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
|
|||
assert(addr);
|
||||
}
|
||||
draw_set_mapped_texture(lp->draw,
|
||||
PIPE_SHADER_VERTEX,
|
||||
shader_type,
|
||||
i,
|
||||
width0, tex->height0, num_layers,
|
||||
first_level, last_level,
|
||||
|
@ -366,6 +367,19 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called during state validation when LP_NEW_SAMPLER_VIEW is set.
|
||||
*/
|
||||
void
|
||||
llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
|
||||
unsigned num,
|
||||
struct pipe_sampler_view **views)
|
||||
{
|
||||
prepare_shader_sampling(lp, num, views, PIPE_SHADER_VERTEX,
|
||||
lp->mapped_vs_tex);
|
||||
}
|
||||
|
||||
void
|
||||
llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx)
|
||||
|
@ -376,6 +390,28 @@ llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called during state validation when LP_NEW_SAMPLER_VIEW is set.
|
||||
*/
|
||||
void
|
||||
llvmpipe_prepare_geometry_sampling(struct llvmpipe_context *lp,
|
||||
unsigned num,
|
||||
struct pipe_sampler_view **views)
|
||||
{
|
||||
prepare_shader_sampling(lp, num, views, PIPE_SHADER_GEOMETRY,
|
||||
lp->mapped_gs_tex);
|
||||
}
|
||||
|
||||
void
|
||||
llvmpipe_cleanup_geometry_sampling(struct llvmpipe_context *ctx)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < Elements(ctx->mapped_gs_tex); i++) {
|
||||
pipe_resource_reference(&ctx->mapped_gs_tex[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue