diff options
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
27 files changed, 585 insertions, 190 deletions
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 89c06ea3ad7..b37c6754c08 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -42,6 +42,11 @@ C_SOURCES = \ CPP_SOURCES = \ +PROGS := lp_test_format \ + lp_test_blend \ + lp_test_conv \ + lp_test_printf + include ../../Makefile.template @@ -49,13 +54,7 @@ lp_tile_soa.c: lp_tile_soa.py ../../auxiliary/util/u_format_parse.py ../../auxil python lp_tile_soa.py ../../auxiliary/util/u_format.csv > $@ -testprogs := lp_test_format \ - lp_test_blend \ - lp_test_conv - -LIBS += $(GL_LIB_DEPS) -L. -lllvmpipe -L../../auxiliary/ -lgallium +LIBS += $(GL_LIB_DEPS) -L../../auxiliary/ -lgallium -#$(testprogs): lp_test_% : lp_test_%.o lp_test_main.o libllvmpipe.a -# $(LD) $(filter %.o,$^) -o $@ -Wl,--start-group $(LIBS) -Wl,--end-group +$(PROGS): lp_test_main.o -#default: $(testprogs) diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index e0676c80a25..383e4b0614d 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -69,11 +69,11 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) pipe_surface_reference(&llvmpipe->framebuffer.zsbuf, NULL); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&llvmpipe->texture[i], NULL); + pipe_sampler_view_reference(&llvmpipe->fragment_sampler_views[i], NULL); } for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - pipe_texture_reference(&llvmpipe->vertex_textures[i], NULL); + pipe_sampler_view_reference(&llvmpipe->vertex_sampler_views[i], NULL); } for (i = 0; i < Elements(llvmpipe->constants); i++) { @@ -158,8 +158,10 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv ) llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state; llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple; llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state; - llvmpipe->pipe.set_fragment_sampler_textures = llvmpipe_set_sampler_textures; - llvmpipe->pipe.set_vertex_sampler_textures = llvmpipe_set_vertex_sampler_textures; + llvmpipe->pipe.set_fragment_sampler_views = llvmpipe_set_fragment_sampler_views; + llvmpipe->pipe.set_vertex_sampler_views = llvmpipe_set_vertex_sampler_views; + llvmpipe->pipe.create_sampler_view = llvmpipe_create_sampler_view; + llvmpipe->pipe.sampler_view_destroy = llvmpipe_sampler_view_destroy; llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state; llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers; diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index f391871b0ee..71f991049e5 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -69,15 +69,15 @@ struct llvmpipe_context { struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; - struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; + struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; unsigned num_samplers; - unsigned num_textures; + unsigned num_fragment_sampler_views; unsigned num_vertex_samplers; - unsigned num_vertex_textures; + unsigned num_vertex_sampler_views; unsigned num_vertex_buffers; unsigned dirty; /**< Mask of LP_NEW_x flags */ diff --git a/src/gallium/drivers/llvmpipe/lp_fence.c b/src/gallium/drivers/llvmpipe/lp_fence.c index 525c117f316..00dc3eab6b1 100644 --- a/src/gallium/drivers/llvmpipe/lp_fence.c +++ b/src/gallium/drivers/llvmpipe/lp_fence.c @@ -29,6 +29,7 @@ #include "pipe/p_screen.h" #include "util/u_memory.h" #include "util/u_inlines.h" +#include "lp_debug.h" #include "lp_fence.h" @@ -99,6 +100,21 @@ llvmpipe_fence_finish(struct pipe_screen *screen, } +void +lp_fence_signal(struct lp_fence *fence) +{ + pipe_mutex_lock(fence->mutex); + + fence->count++; + assert(fence->count <= fence->rank); + + LP_DBG(DEBUG_RAST, "%s count=%u rank=%u\n", __FUNCTION__, + fence->count, fence->rank); + + pipe_condvar_signal(fence->signalled); + + pipe_mutex_unlock(fence->mutex); +} void diff --git a/src/gallium/drivers/llvmpipe/lp_fence.h b/src/gallium/drivers/llvmpipe/lp_fence.h index c90e6de423b..d9270f5784a 100644 --- a/src/gallium/drivers/llvmpipe/lp_fence.h +++ b/src/gallium/drivers/llvmpipe/lp_fence.h @@ -54,6 +54,10 @@ lp_fence_create(unsigned rank); void +lp_fence_signal(struct lp_fence *fence); + + +void llvmpipe_init_screen_fence_funcs(struct pipe_screen *screen); diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index 636d72a9bb8..782669a1e77 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -111,7 +111,6 @@ llvmpipe_flush_texture(struct pipe_context *pipe, boolean cpu_access, boolean do_not_flush) { - struct pipe_fence_handle *last_fence = NULL; unsigned referenced; referenced = pipe->is_texture_referenced(pipe, texture, face, level); @@ -142,7 +141,7 @@ llvmpipe_flush_texture(struct pipe_context *pipe, pipe->flush(pipe, flush_flags, &fence); - if (last_fence) { + if (fence) { pipe->screen->fence_finish(pipe->screen, fence, 0); pipe->screen->fence_reference(pipe->screen, &fence, NULL); } diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 5887613120d..927e472ff26 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -91,36 +91,53 @@ lp_jit_init_globals(struct llvmpipe_screen *screen) /* struct lp_jit_context */ { - LLVMTypeRef elem_types[8]; + LLVMTypeRef elem_types[LP_JIT_CTX_COUNT]; LLVMTypeRef context_type; - elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */ - elem_types[1] = LLVMFloatType(); /* alpha_ref_value */ elem_types[2] = LLVMFloatType(); /* scissor_xmin */ - elem_types[3] = LLVMFloatType(); /* scissor_ymin */ - elem_types[4] = LLVMFloatType(); /* scissor_xmax */ - elem_types[5] = LLVMFloatType(); /* scissor_ymax */ - elem_types[6] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */ - elem_types[7] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */ + elem_types[LP_JIT_CTX_CONSTANTS] = LLVMPointerType(LLVMFloatType(), 0); + elem_types[LP_JIT_CTX_ALPHA_REF] = LLVMFloatType(); + elem_types[LP_JIT_CTX_STENCIL_REF_FRONT] = LLVMInt32Type(); + elem_types[LP_JIT_CTX_STENCIL_REF_BACK] = LLVMInt32Type(); + elem_types[LP_JIT_CTX_SCISSOR_XMIN] = LLVMFloatType(); + elem_types[LP_JIT_CTX_SCISSOR_YMIN] = LLVMFloatType(); + elem_types[LP_JIT_CTX_SCISSOR_XMAX] = LLVMFloatType(); + elem_types[LP_JIT_CTX_SCISSOR_YMAX] = LLVMFloatType(); + elem_types[LP_JIT_CTX_BLEND_COLOR] = LLVMPointerType(LLVMInt8Type(), 0); + elem_types[LP_JIT_CTX_TEXTURES] = LLVMArrayType(texture_type, + PIPE_MAX_SAMPLERS); context_type = LLVMStructType(elem_types, Elements(elem_types), 0); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, constants, - screen->target, context_type, 0); + screen->target, context_type, + LP_JIT_CTX_CONSTANTS); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value, - screen->target, context_type, 1); + screen->target, context_type, + LP_JIT_CTX_ALPHA_REF); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_front, + screen->target, context_type, + LP_JIT_CTX_STENCIL_REF_FRONT); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_back, + screen->target, context_type, + LP_JIT_CTX_STENCIL_REF_BACK); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmin, - screen->target, context_type, 2); + screen->target, context_type, + LP_JIT_CTX_SCISSOR_XMIN); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymin, - screen->target, context_type, 3); + screen->target, context_type, + LP_JIT_CTX_SCISSOR_YMIN); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmax, - screen->target, context_type, 4); + screen->target, context_type, + LP_JIT_CTX_SCISSOR_XMAX); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymax, - screen->target, context_type, 5); + screen->target, context_type, + LP_JIT_CTX_SCISSOR_YMAX); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color, - screen->target, context_type, 6); + screen->target, context_type, + LP_JIT_CTX_BLEND_COLOR); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures, screen->target, context_type, - LP_JIT_CONTEXT_TEXTURES_INDEX); + LP_JIT_CTX_TEXTURES); LP_CHECK_STRUCT_SIZE(struct lp_jit_context, screen->target, context_type); diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 13167ae3bf4..4930ff02e6b 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -84,6 +84,8 @@ struct lp_jit_context float alpha_ref_value; + uint32_t stencil_ref_front, stencil_ref_back; + /** floats, not ints */ float scissor_xmin, scissor_ymin, scissor_xmax, scissor_ymax; @@ -94,37 +96,66 @@ struct lp_jit_context }; +/** + * These enum values must match the position of the fields in the + * lp_jit_context struct above. + */ +enum { + LP_JIT_CTX_CONSTANTS = 0, + LP_JIT_CTX_ALPHA_REF, + LP_JIT_CTX_STENCIL_REF_FRONT, + LP_JIT_CTX_STENCIL_REF_BACK, + LP_JIT_CTX_SCISSOR_XMIN, + LP_JIT_CTX_SCISSOR_YMIN, + LP_JIT_CTX_SCISSOR_XMAX, + LP_JIT_CTX_SCISSOR_YMAX, + LP_JIT_CTX_BLEND_COLOR, + LP_JIT_CTX_TEXTURES, + LP_JIT_CTX_COUNT +}; + + #define lp_jit_context_constants(_builder, _ptr) \ - lp_build_struct_get(_builder, _ptr, 0, "constants") + lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_CONSTANTS, "constants") #define lp_jit_context_alpha_ref_value(_builder, _ptr) \ - lp_build_struct_get(_builder, _ptr, 1, "alpha_ref_value") + lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_ALPHA_REF, "alpha_ref_value") + +#define lp_jit_context_stencil_ref_front_value(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_STENCIL_REF_FRONT, "stencil_ref_front") + +#define lp_jit_context_stencil_ref_back_value(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_STENCIL_REF_BACK, "stencil_ref_back") #define lp_jit_context_scissor_xmin_value(_builder, _ptr) \ - lp_build_struct_get(_builder, _ptr, 2, "scissor_xmin") + lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_XMIN, "scissor_xmin") #define lp_jit_context_scissor_ymin_value(_builder, _ptr) \ - lp_build_struct_get(_builder, _ptr, 3, "scissor_ymin") + lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_YMIN, "scissor_ymin") #define lp_jit_context_scissor_xmax_value(_builder, _ptr) \ - lp_build_struct_get(_builder, _ptr, 4, "scissor_xmax") + lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_XMAX, "scissor_xmax") #define lp_jit_context_scissor_ymax_value(_builder, _ptr) \ - lp_build_struct_get(_builder, _ptr, 5, "scissor_ymax") + lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_YMAX, "scissor_ymax") #define lp_jit_context_blend_color(_builder, _ptr) \ - lp_build_struct_get(_builder, _ptr, 6, "blend_color") - -#define LP_JIT_CONTEXT_TEXTURES_INDEX 7 + lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_BLEND_COLOR, "blend_color") #define lp_jit_context_textures(_builder, _ptr) \ - lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES_INDEX, "textures") + lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES, "textures") + + +/** Indexes into jit_function[] array */ +#define RAST_WHOLE 0 +#define RAST_EDGE_TEST 1 typedef void (*lp_jit_frag_func)(const struct lp_jit_context *context, uint32_t x, uint32_t y, + float facing, const void *a0, const void *dadx, const void *dady, diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 81ea11a16b6..8352f175598 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -189,7 +189,7 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task, LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil); - assert(rast->zsbuf.map); + /*assert(rast->zsbuf.map);*/ if (!rast->zsbuf.map) return; @@ -312,15 +312,16 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task, depth = lp_rast_depth_pointer(rast, tile_x + x, tile_y + y); /* run shader */ - state->jit_function[0]( &state->jit_context, - tile_x + x, tile_y + y, - inputs->a0, - inputs->dadx, - inputs->dady, - color, - depth, - INT_MIN, INT_MIN, INT_MIN, - NULL, NULL, NULL ); + state->jit_function[RAST_WHOLE]( &state->jit_context, + tile_x + x, tile_y + y, + inputs->facing, + inputs->a0, + inputs->dadx, + inputs->dady, + color, + depth, + INT_MIN, INT_MIN, INT_MIN, + NULL, NULL, NULL ); } } } @@ -375,15 +376,18 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task, assert(lp_check_alignment(inputs->step[2], 16)); /* run shader */ - state->jit_function[1]( &state->jit_context, - x, y, - inputs->a0, - inputs->dadx, - inputs->dady, - color, - depth, - c1, c2, c3, - inputs->step[0], inputs->step[1], inputs->step[2]); + state->jit_function[RAST_EDGE_TEST]( &state->jit_context, + x, y, + inputs->facing, + inputs->a0, + inputs->dadx, + inputs->dady, + color, + depth, + c1, c2, c3, + inputs->step[0], + inputs->step[1], + inputs->step[2]); } @@ -487,18 +491,7 @@ lp_rast_fence(struct lp_rasterizer_task *task, const union lp_rast_cmd_arg arg) { struct lp_fence *fence = arg.fence; - - pipe_mutex_lock( fence->mutex ); - - fence->count++; - assert(fence->count <= fence->rank); - - LP_DBG(DEBUG_RAST, "%s count=%u rank=%u\n", __FUNCTION__, - fence->count, fence->rank); - - pipe_condvar_signal( fence->signalled ); - - pipe_mutex_unlock( fence->mutex ); + lp_fence_signal(fence); } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 303f6e3f7e4..ae838f3fbef 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -82,6 +82,8 @@ struct lp_rast_state { * These pointers point into the bin data buffer. */ struct lp_rast_shader_inputs { + float facing; /** Positive for front-facing, negative for back-facing */ + float (*a0)[4]; float (*dadx)[4]; float (*dady)[4]; diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 39bf2c25879..6ee9bcaae3a 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -195,6 +195,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task, /* run shader */ state->jit_function[0]( &state->jit_context, x, y, + inputs->facing, inputs->a0, inputs->dadx, inputs->dady, diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 5093f58bb19..f1bbc2092c4 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -204,8 +204,10 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, return FALSE; } - if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { - if(!winsys->is_displaytarget_format_supported(winsys, format)) + if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_SCANOUT | + PIPE_TEXTURE_USAGE_SHARED)) { + if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) return FALSE; } diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h index d977f98cfaa..af25e043cc9 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.h +++ b/src/gallium/drivers/llvmpipe/lp_screen.h @@ -34,7 +34,7 @@ #ifndef LP_SCREEN_H #define LP_SCREEN_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include <llvm-c/ExecutionEngine.h> #include "pipe/p_screen.h" diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 16128c34c80..76a8b87a309 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -402,6 +402,20 @@ lp_setup_set_alpha_ref_value( struct lp_setup_context *setup, } void +lp_setup_set_stencil_ref_values( struct lp_setup_context *setup, + const ubyte refs[2] ) +{ + LP_DBG(DEBUG_SETUP, "%s %d %d\n", __FUNCTION__, refs[0], refs[1]); + + if (setup->fs.current.jit_context.stencil_ref_front != refs[0] || + setup->fs.current.jit_context.stencil_ref_back != refs[1]) { + setup->fs.current.jit_context.stencil_ref_front = refs[0]; + setup->fs.current.jit_context.stencil_ref_back = refs[1]; + setup->dirty |= LP_SETUP_NEW_FS; + } +} + +void lp_setup_set_blend_color( struct lp_setup_context *setup, const struct pipe_blend_color *blend_color ) { @@ -450,11 +464,12 @@ lp_setup_set_vertex_info( struct lp_setup_context *setup, /** - * Called during state validation when LP_NEW_TEXTURE is set. + * Called during state validation when LP_NEW_SAMPLER_VIEW is set. */ void -lp_setup_set_sampler_textures( struct lp_setup_context *setup, - unsigned num, struct pipe_texture **texture) +lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, + unsigned num, + struct pipe_sampler_view **views) { unsigned i; @@ -463,9 +478,10 @@ lp_setup_set_sampler_textures( struct lp_setup_context *setup, assert(num <= PIPE_MAX_SAMPLERS); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - struct pipe_texture *tex = i < num ? texture[i] : NULL; + struct pipe_sampler_view *view = i < num ? views[i] : NULL; - if(tex) { + if(view) { + struct pipe_texture *tex = view->texture; struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex); struct lp_jit_texture *jit_tex; jit_tex = &setup->fs.current.jit_context.textures[i]; @@ -473,6 +489,12 @@ lp_setup_set_sampler_textures( struct lp_setup_context *setup, jit_tex->height = tex->height0; jit_tex->depth = tex->depth0; jit_tex->last_level = tex->last_level; + + /* We're referencing the texture's internal data, so save a + * reference to it. + */ + pipe_texture_reference(&setup->fs.current_tex[i], tex); + if (!lp_tex->dt) { /* regular texture - setup array of mipmap level pointers */ int j; @@ -495,12 +517,6 @@ lp_setup_set_sampler_textures( struct lp_setup_context *setup, jit_tex->row_stride[0] = lp_tex->stride[0]; assert(jit_tex->data[0]); } - - /* the scene references this texture */ - { - struct lp_scene *scene = lp_setup_get_current_scene(setup); - lp_scene_texture_reference(scene, tex); - } } } @@ -635,6 +651,7 @@ lp_setup_update_state( struct lp_setup_context *setup ) * the new, current state. So allocate a new lp_rast_state object * and append it to the bin's setup data buffer. */ + uint i; struct lp_rast_state *stored = (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored); if(stored) { @@ -648,6 +665,14 @@ lp_setup_update_state( struct lp_setup_context *setup ) lp_rast_set_state, lp_rast_arg_state(setup->fs.stored) ); } + + /* The scene now references the textures in the rasterization + * state record. Note that now. + */ + for (i = 0; i < Elements(setup->fs.current_tex); i++) { + if (setup->fs.current_tex[i]) + lp_scene_texture_reference(scene, setup->fs.current_tex[i]); + } } } @@ -663,8 +688,14 @@ lp_setup_update_state( struct lp_setup_context *setup ) void lp_setup_destroy( struct lp_setup_context *setup ) { + uint i; + reset_context( setup ); + for (i = 0; i < Elements(setup->fs.current_tex); i++) { + pipe_texture_reference(&setup->fs.current_tex[i], NULL); + } + pipe_buffer_reference(&setup->constants.current, NULL); /* free the scenes in the 'empty' queue */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index be1bf96f12d..dbfc1bf8d4c 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -113,6 +113,10 @@ lp_setup_set_alpha_ref_value( struct lp_setup_context *setup, float alpha_ref_value ); void +lp_setup_set_stencil_ref_values( struct lp_setup_context *setup, + const ubyte refs[2] ); + +void lp_setup_set_blend_color( struct lp_setup_context *setup, const struct pipe_blend_color *blend_color ); @@ -121,8 +125,9 @@ lp_setup_set_scissor( struct lp_setup_context *setup, const struct pipe_scissor_state *scissor ); void -lp_setup_set_sampler_textures( struct lp_setup_context *setup, - unsigned num, struct pipe_texture **texture); +lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, + unsigned num, + struct pipe_sampler_view **views); unsigned lp_setup_is_texture_referenced( const struct lp_setup_context *setup, diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 464fb369840..ca0dafab627 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -111,6 +111,7 @@ struct lp_setup_context const struct lp_rast_state *stored; /**< what's in the scene */ struct lp_rast_state current; /**< currently set state */ + struct pipe_texture *current_tex[PIPE_MAX_SAMPLERS]; } fs; /** fragment shader constants */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index ac6264dc73e..ce689d3d568 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -361,6 +361,8 @@ do_triangle_ccw(struct lp_setup_context *setup, */ setup_tri_coefficients( setup, tri, oneoverarea, v1, v2, v3, frontfacing ); + tri->inputs.facing = frontfacing ? 1.0F : -1.0F; + /* half-edge constants, will be interated over the whole render target. */ tri->c1 = tri->dy12 * x1 - tri->dx12 * y1; diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index a5a1a720742..74ebf90d580 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -31,7 +31,7 @@ #ifndef LP_STATE_H #define LP_STATE_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include "pipe/p_state.h" #include "tgsi/tgsi_scan.h" @@ -50,7 +50,7 @@ #define LP_NEW_DEPTH_STENCIL_ALPHA 0x100 #define LP_NEW_CONSTANTS 0x200 #define LP_NEW_SAMPLER 0x400 -#define LP_NEW_TEXTURE 0x800 +#define LP_NEW_SAMPLER_VIEW 0x800 #define LP_NEW_VERTEX 0x1000 #define LP_NEW_VS 0x2000 #define LP_NEW_QUERY 0x4000 @@ -67,6 +67,7 @@ struct lp_fragment_shader; struct lp_fragment_shader_variant_key { struct pipe_depth_state depth; + struct pipe_stencil_state stencil[2]; struct pipe_alpha_state alpha; struct pipe_blend_state blend; enum pipe_format zsbuf_format; @@ -192,14 +193,23 @@ void llvmpipe_set_polygon_stipple( struct pipe_context *, void llvmpipe_set_scissor_state( struct pipe_context *, const struct pipe_scissor_state * ); -void llvmpipe_set_sampler_textures( struct pipe_context *, - unsigned num, - struct pipe_texture ** ); +void llvmpipe_set_fragment_sampler_views(struct pipe_context *, + unsigned num, + struct pipe_sampler_view **); void -llvmpipe_set_vertex_sampler_textures(struct pipe_context *, - unsigned num_textures, - struct pipe_texture **); +llvmpipe_set_vertex_sampler_views(struct pipe_context *, + unsigned num, + struct pipe_sampler_view **); + +struct pipe_sampler_view * +llvmpipe_create_sampler_view(struct pipe_context *pipe, + struct pipe_texture *texture, + const struct pipe_sampler_view *templ); + +void +llvmpipe_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view); void llvmpipe_set_viewport_state( struct pipe_context *, const struct pipe_viewport_state * ); diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index bdd906e1a73..777871638f6 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -150,7 +150,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) */ if (llvmpipe->tex_timestamp != lp_screen->timestamp) { llvmpipe->tex_timestamp = lp_screen->timestamp; - llvmpipe->dirty |= LP_NEW_TEXTURE; + llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW; } if (llvmpipe->dirty & (LP_NEW_RASTERIZER | @@ -164,7 +164,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) LP_NEW_DEPTH_STENCIL_ALPHA | LP_NEW_RASTERIZER | LP_NEW_SAMPLER | - LP_NEW_TEXTURE)) + LP_NEW_SAMPLER_VIEW)) llvmpipe_update_fs( llvmpipe ); if (llvmpipe->dirty & LP_NEW_BLEND_COLOR) @@ -174,18 +174,21 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) if (llvmpipe->dirty & LP_NEW_SCISSOR) lp_setup_set_scissor(llvmpipe->setup, &llvmpipe->scissor); - if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) + if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) { lp_setup_set_alpha_ref_value(llvmpipe->setup, llvmpipe->depth_stencil->alpha.ref_value); + lp_setup_set_stencil_ref_values(llvmpipe->setup, + llvmpipe->stencil_ref.ref_value); + } if (llvmpipe->dirty & LP_NEW_CONSTANTS) lp_setup_set_fs_constants(llvmpipe->setup, llvmpipe->constants[PIPE_SHADER_FRAGMENT]); - if (llvmpipe->dirty & LP_NEW_TEXTURE) - lp_setup_set_sampler_textures(llvmpipe->setup, - llvmpipe->num_textures, - llvmpipe->texture); + if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW) + lp_setup_set_fragment_sampler_views(llvmpipe->setup, + llvmpipe->num_fragment_sampler_views, + llvmpipe->fragment_sampler_views); llvmpipe->dirty = 0; } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 9a8de0edfda..7bbf348e0b8 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -138,20 +138,22 @@ generate_pos0(LLVMBuilderRef builder, /** - * Generate the depth test. + * Generate the depth /stencil test code. */ static void -generate_depth(LLVMBuilderRef builder, - const struct lp_fragment_shader_variant_key *key, - struct lp_type src_type, - struct lp_build_mask_context *mask, - LLVMValueRef src, - LLVMValueRef dst_ptr) +generate_depth_stencil(LLVMBuilderRef builder, + const struct lp_fragment_shader_variant_key *key, + struct lp_type src_type, + struct lp_build_mask_context *mask, + LLVMValueRef stencil_refs[2], + LLVMValueRef src, + LLVMValueRef dst_ptr, + LLVMValueRef facing) { const struct util_format_description *format_desc; struct lp_type dst_type; - if(!key->depth.enabled) + if (!key->depth.enabled && !key->stencil[0].enabled && !key->stencil[1].enabled) return; format_desc = util_format_description(key->zsbuf_format); @@ -178,19 +180,22 @@ generate_depth(LLVMBuilderRef builder, assert(dst_type.width == src_type.width); assert(dst_type.length == src_type.length); + /* Convert fragment Z from float to integer */ lp_build_conv(builder, src_type, dst_type, &src, 1, &src, 1); dst_ptr = LLVMBuildBitCast(builder, dst_ptr, LLVMPointerType(lp_build_vec_type(dst_type), 0), ""); - - lp_build_depth_test(builder, - &key->depth, - dst_type, - format_desc, - mask, - src, - dst_ptr); + lp_build_depth_stencil_test(builder, + &key->depth, + key->stencil, + dst_type, + format_desc, + mask, + stencil_refs, + src, + dst_ptr, + facing); } @@ -252,7 +257,7 @@ generate_tri_edge_mask(LLVMBuilderRef builder, LLVMConstInt(LLVMInt32Type(), INT_MIN, 0), ""); - in_out_mask = lp_build_int_const_scalar(i32_type, ~0); + in_out_mask = lp_build_const_int_vec(i32_type, ~0); lp_build_flow_scope_declare(flow, &in_out_mask); @@ -367,7 +372,7 @@ build_int32_vec_const(int value) i32_type.norm = FALSE; /* values are not normalized */ i32_type.width = 32; /* 32-bit int values */ i32_type.length = 4; /* 4 elements per vector */ - return lp_build_int_const_scalar(i32_type, value); + return lp_build_const_int_vec(i32_type, value); } @@ -390,6 +395,7 @@ generate_fs(struct llvmpipe_context *lp, LLVMValueRef *pmask, LLVMValueRef (*color)[4], LLVMValueRef depth_ptr, + LLVMValueRef facing, unsigned do_tri_test, LLVMValueRef c0, LLVMValueRef c1, @@ -405,15 +411,19 @@ generate_fs(struct llvmpipe_context *lp, LLVMValueRef consts_ptr; LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS]; LLVMValueRef z = interp->pos[2]; + LLVMValueRef stencil_refs[2]; struct lp_build_flow_context *flow; struct lp_build_mask_context mask; - boolean early_depth_test; + boolean early_depth_stencil_test; unsigned attrib; unsigned chan; unsigned cbuf; assert(i < 4); + stencil_refs[0] = lp_jit_context_stencil_ref_front_value(builder, context_ptr); + stencil_refs[1] = lp_jit_context_stencil_ref_back_value(builder, context_ptr); + elem_type = lp_build_elem_type(type); vec_type = lp_build_vec_type(type); int_vec_type = lp_build_int_vec_type(type); @@ -453,16 +463,16 @@ generate_fs(struct llvmpipe_context *lp, lp_build_mask_update(&mask, smask); } - early_depth_test = - key->depth.enabled && + early_depth_stencil_test = + (key->depth.enabled || key->stencil[0].enabled) && !key->alpha.enabled && !shader->info.uses_kill && !shader->info.writes_z; - if(early_depth_test) - generate_depth(builder, key, - type, &mask, - z, depth_ptr); + if (early_depth_stencil_test) + generate_depth_stencil(builder, key, + type, &mask, + stencil_refs, z, depth_ptr, facing); lp_build_tgsi_soa(builder, tokens, type, &mask, consts_ptr, interp->pos, interp->inputs, @@ -506,10 +516,10 @@ generate_fs(struct llvmpipe_context *lp, } } - if(!early_depth_test) - generate_depth(builder, key, - type, &mask, - z, depth_ptr); + if (!early_depth_stencil_test) + generate_depth_stencil(builder, key, + type, &mask, + stencil_refs, z, depth_ptr, facing); lp_build_mask_end(&mask); @@ -585,6 +595,20 @@ generate_blend(const struct pipe_blend_state *blend, } +/** casting function to avoid compiler warnings */ +static lp_jit_frag_func +cast_voidptr_to_lp_jit_frag_func(void *p) +{ + union { + void *v; + lp_jit_frag_func f; + } tmp; + assert(sizeof(tmp.v) == sizeof(tmp.f)); + tmp.v = p; + return tmp.f; +} + + /** * Generate the runtime callable function for the whole fragment pipeline. * Note that the function which we generate operates on a block of 16 @@ -606,7 +630,7 @@ generate_fragment(struct llvmpipe_context *lp, LLVMTypeRef fs_int_vec_type; LLVMTypeRef blend_vec_type; LLVMTypeRef blend_int_vec_type; - LLVMTypeRef arg_types[14]; + LLVMTypeRef arg_types[15]; LLVMTypeRef func_type; LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type(); LLVMValueRef context_ptr; @@ -629,6 +653,7 @@ generate_fragment(struct llvmpipe_context *lp, LLVMValueRef blend_mask; LLVMValueRef blend_in_color[NUM_CHANNELS]; LLVMValueRef function; + LLVMValueRef facing; unsigned num_fs; unsigned i; unsigned chan; @@ -668,20 +693,21 @@ generate_fragment(struct llvmpipe_context *lp, arg_types[0] = screen->context_ptr_type; /* context */ arg_types[1] = LLVMInt32Type(); /* x */ arg_types[2] = LLVMInt32Type(); /* y */ - arg_types[3] = LLVMPointerType(fs_elem_type, 0); /* a0 */ - arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* dadx */ - arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dady */ - arg_types[6] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0); /* color */ - arg_types[7] = LLVMPointerType(fs_int_vec_type, 0); /* depth */ - arg_types[8] = LLVMInt32Type(); /* c0 */ - arg_types[9] = LLVMInt32Type(); /* c1 */ - arg_types[10] = LLVMInt32Type(); /* c2 */ + arg_types[3] = LLVMFloatType(); /* facing */ + arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* a0 */ + arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dadx */ + arg_types[6] = LLVMPointerType(fs_elem_type, 0); /* dady */ + arg_types[7] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0); /* color */ + arg_types[8] = LLVMPointerType(fs_int_vec_type, 0); /* depth */ + arg_types[9] = LLVMInt32Type(); /* c0 */ + arg_types[10] = LLVMInt32Type(); /* c1 */ + arg_types[11] = LLVMInt32Type(); /* c2 */ /* Note: the step arrays are built as int32[16] but we interpret * them here as int32_vec4[4]. */ - arg_types[11] = LLVMPointerType(int32_vec4_type, 0);/* step0 */ - arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step1 */ - arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step2 */ + arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step0 */ + arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step1 */ + arg_types[14] = LLVMPointerType(int32_vec4_type, 0);/* step2 */ func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0); @@ -701,17 +727,18 @@ generate_fragment(struct llvmpipe_context *lp, context_ptr = LLVMGetParam(function, 0); x = LLVMGetParam(function, 1); y = LLVMGetParam(function, 2); - a0_ptr = LLVMGetParam(function, 3); - dadx_ptr = LLVMGetParam(function, 4); - dady_ptr = LLVMGetParam(function, 5); - color_ptr_ptr = LLVMGetParam(function, 6); - depth_ptr = LLVMGetParam(function, 7); - c0 = LLVMGetParam(function, 8); - c1 = LLVMGetParam(function, 9); - c2 = LLVMGetParam(function, 10); - step0_ptr = LLVMGetParam(function, 11); - step1_ptr = LLVMGetParam(function, 12); - step2_ptr = LLVMGetParam(function, 13); + facing = LLVMGetParam(function, 3); + a0_ptr = LLVMGetParam(function, 4); + dadx_ptr = LLVMGetParam(function, 5); + dady_ptr = LLVMGetParam(function, 6); + color_ptr_ptr = LLVMGetParam(function, 7); + depth_ptr = LLVMGetParam(function, 8); + c0 = LLVMGetParam(function, 9); + c1 = LLVMGetParam(function, 10); + c2 = LLVMGetParam(function, 11); + step0_ptr = LLVMGetParam(function, 12); + step1_ptr = LLVMGetParam(function, 13); + step2_ptr = LLVMGetParam(function, 14); lp_build_name(context_ptr, "context"); lp_build_name(x, "x"); @@ -770,6 +797,7 @@ generate_fragment(struct llvmpipe_context *lp, &fs_mask[i], /* output */ out_color, depth_ptr_i, + facing, do_tri_test, c0, c1, c2, step0_ptr, step1_ptr, step2_ptr); @@ -845,10 +873,14 @@ generate_fragment(struct llvmpipe_context *lp, /* * Translate the LLVM IR into machine code. */ - variant->jit_function[do_tri_test] = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, function); + { + void *f = LLVMGetPointerToGlobal(screen->engine, function); + + variant->jit_function[do_tri_test] = cast_voidptr_to_lp_jit_frag_func(f); - if (LP_DEBUG & DEBUG_ASM) - lp_disassemble(variant->jit_function[do_tri_test]); + if (LP_DEBUG & DEBUG_ASM) + lp_disassemble(f); + } } @@ -1054,10 +1086,15 @@ make_variant_key(struct llvmpipe_context *lp, memset(key, 0, sizeof *key); - if(lp->framebuffer.zsbuf && - lp->depth_stencil->depth.enabled) { - key->zsbuf_format = lp->framebuffer.zsbuf->format; - memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth); + if (lp->framebuffer.zsbuf) { + if (lp->depth_stencil->depth.enabled) { + key->zsbuf_format = lp->framebuffer.zsbuf->format; + memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth); + } + if (lp->depth_stencil->stencil[0].enabled) { + key->zsbuf_format = lp->framebuffer.zsbuf->format; + memcpy(&key->stencil, &lp->depth_stencil->stencil, sizeof key->stencil); + } } key->alpha.enabled = lp->depth_stencil->alpha.enabled; @@ -1094,7 +1131,7 @@ make_variant_key(struct llvmpipe_context *lp, for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) - lp_sampler_static_state(&key->sampler[i], lp->texture[i], lp->sampler[i]); + lp_sampler_static_state(&key->sampler[i], lp->fragment_sampler_views[i]->texture, lp->sampler[i]); } @@ -1140,6 +1177,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) opaque = !key.blend.logicop_enable && !key.blend.rt[0].blend_enable && key.blend.rt[0].colormask == 0xf && + !key.stencil[0].enabled && !key.alpha.enabled && !key.depth.enabled && !key.scissor && @@ -1147,7 +1185,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) ? TRUE : FALSE; lp_setup_set_fs_functions(lp->setup, - shader->current->jit_function[0], - shader->current->jit_function[1], + shader->current->jit_function[RAST_WHOLE], + shader->current->jit_function[RAST_EDGE_TEST], opaque); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index b30a0757768..2645441b58c 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -105,8 +105,9 @@ llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe, void -llvmpipe_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) +llvmpipe_set_fragment_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); uint i; @@ -114,51 +115,79 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe, assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ - if (num == llvmpipe->num_textures && - !memcmp(llvmpipe->texture, texture, num * sizeof(struct pipe_texture *))) + if (num == llvmpipe->num_fragment_sampler_views && + !memcmp(llvmpipe->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) return; draw_flush(llvmpipe->draw); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - struct pipe_texture *tex = i < num ? texture[i] : NULL; + struct pipe_sampler_view *view = i < num ? views[i] : NULL; - pipe_texture_reference(&llvmpipe->texture[i], tex); + pipe_sampler_view_reference(&llvmpipe->fragment_sampler_views[i], view); } - llvmpipe->num_textures = num; + llvmpipe->num_fragment_sampler_views = num; - llvmpipe->dirty |= LP_NEW_TEXTURE; + llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW; } void -llvmpipe_set_vertex_sampler_textures(struct pipe_context *pipe, - unsigned num_textures, - struct pipe_texture **textures) +llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); uint i; - assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS); + assert(num <= PIPE_MAX_VERTEX_SAMPLERS); /* Check for no-op */ - if (num_textures == llvmpipe->num_vertex_textures && - !memcmp(llvmpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) { + if (num == llvmpipe->num_vertex_sampler_views && + !memcmp(llvmpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { return; } draw_flush(llvmpipe->draw); for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - struct pipe_texture *tex = i < num_textures ? textures[i] : NULL; + struct pipe_sampler_view *view = i < num ? views[i] : NULL; - pipe_texture_reference(&llvmpipe->vertex_textures[i], tex); + pipe_sampler_view_reference(&llvmpipe->vertex_sampler_views[i], view); } - llvmpipe->num_vertex_textures = num_textures; + llvmpipe->num_vertex_sampler_views = num; - llvmpipe->dirty |= LP_NEW_TEXTURE; + llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW; +} + + +struct pipe_sampler_view * +llvmpipe_create_sampler_view(struct pipe_context *pipe, + struct pipe_texture *texture, + const struct pipe_sampler_view *templ) +{ + struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + + if (view) { + *view = *templ; + view->reference.count = 1; + view->texture = NULL; + pipe_texture_reference(&view->texture, texture); + view->context = pipe; + } + + return view; +} + + +void +llvmpipe_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + pipe_texture_reference(&view->texture, NULL); + FREE(view); } diff --git a/src/gallium/drivers/llvmpipe/lp_test.h b/src/gallium/drivers/llvmpipe/lp_test.h index 1df98978988..338a04a4878 100644 --- a/src/gallium/drivers/llvmpipe/lp_test.h +++ b/src/gallium/drivers/llvmpipe/lp_test.h @@ -41,7 +41,7 @@ #include <stdio.h> #include <float.h> -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include <llvm-c/Analysis.h> #include <llvm-c/ExecutionEngine.h> #include <llvm-c/Target.h> diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c index 2c4d7fb6e14..fb595893bd0 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_format.c +++ b/src/gallium/drivers/llvmpipe/lp_test_format.c @@ -29,7 +29,7 @@ #include <stdlib.h> #include <stdio.h> -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include <llvm-c/Analysis.h> #include <llvm-c/ExecutionEngine.h> #include <llvm-c/Target.h> diff --git a/src/gallium/drivers/llvmpipe/lp_test_printf.c b/src/gallium/drivers/llvmpipe/lp_test_printf.c new file mode 100644 index 00000000000..e5e5925012a --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_test_printf.c @@ -0,0 +1,162 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include <stdlib.h> +#include <stdio.h> + +#include "gallivm/lp_bld.h" +#include "gallivm/lp_bld_printf.h" + +#include <llvm-c/Analysis.h> +#include <llvm-c/ExecutionEngine.h> +#include <llvm-c/Target.h> +#include <llvm-c/Transforms/Scalar.h> + +#include "lp_test.h" + + +struct printf_test_case { +}; + +void +write_tsv_header(FILE *fp) +{ + fprintf(fp, + "result\t" + "format\n"); + + fflush(fp); +} + + + +typedef void (*test_printf_t)(int i); + +static LLVMValueRef +add_printf_test(LLVMModuleRef module) +{ + LLVMTypeRef args[1] = { LLVMIntType(32) }; + LLVMValueRef func = LLVMAddFunction(module, "test_printf", LLVMFunctionType(LLVMVoidType(), args, 1, 0)); + LLVMBuilderRef builder = LLVMCreateBuilder(); + LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry"); + + LLVMSetFunctionCallConv(func, LLVMCCallConv); + + LLVMPositionBuilderAtEnd(builder, block); + lp_build_printf(builder, "hello, world\n"); + lp_build_printf(builder, "print 5 6: %d %d\n", LLVMConstInt(LLVMInt32Type(), 5, 0), + LLVMConstInt(LLVMInt32Type(), 6, 0)); + LLVMBuildRetVoid(builder); + LLVMDisposeBuilder(builder); + return func; +} + + +PIPE_ALIGN_STACK +static boolean +test_printf(unsigned verbose, FILE *fp, const struct printf_test_case *testcase) +{ + LLVMModuleRef module = NULL; + LLVMValueRef test = NULL; + LLVMExecutionEngineRef engine = NULL; + LLVMModuleProviderRef provider = NULL; + LLVMPassManagerRef pass = NULL; + char *error = NULL; + test_printf_t test_printf; + float unpacked[4]; + unsigned packed; + boolean success = TRUE; + + module = LLVMModuleCreateWithName("test"); + + test = add_printf_test(module); + + if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) { + LLVMDumpModule(module); + abort(); + } + LLVMDisposeMessage(error); + + provider = LLVMCreateModuleProviderForExistingModule(module); + if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { + fprintf(stderr, "%s\n", error); + LLVMDisposeMessage(error); + abort(); + } + +#if 0 + pass = LLVMCreatePassManager(); + LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); + /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, + * but there are more on SVN. */ + LLVMAddConstantPropagationPass(pass); + LLVMAddInstructionCombiningPass(pass); + LLVMAddPromoteMemoryToRegisterPass(pass); + LLVMAddGVNPass(pass); + LLVMAddCFGSimplificationPass(pass); + LLVMRunPassManager(pass, module); +#else + (void)pass; +#endif + + test_printf = (test_printf_t)LLVMGetPointerToGlobal(engine, test); + + memset(unpacked, 0, sizeof unpacked); + packed = 0; + + + // LLVMDumpModule(module); + + test_printf(0); + + LLVMFreeMachineCodeForFunction(engine, test); + + LLVMDisposeExecutionEngine(engine); + if(pass) + LLVMDisposePassManager(pass); + + return success; +} + + +boolean +test_all(unsigned verbose, FILE *fp) +{ + bool success = TRUE; + + test_printf(verbose, fp, NULL); + + return success; +} + + +boolean +test_some(unsigned verbose, FILE *fp, unsigned long n) +{ + return test_all(verbose, fp); +} diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.h b/src/gallium/drivers/llvmpipe/lp_tex_sample.h index 799df182b6a..1228a831f3b 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.h +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.h @@ -29,7 +29,7 @@ #define LP_TEX_SAMPLE_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" struct lp_sampler_static_state; diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c index 662508af61a..4715cfe4f62 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c @@ -105,7 +105,7 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base, /* context[0] */ indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0); /* context[0].textures */ - indices[1] = LLVMConstInt(LLVMInt32Type(), LP_JIT_CONTEXT_TEXTURES_INDEX, 0); + indices[1] = LLVMConstInt(LLVMInt32Type(), LP_JIT_CTX_TEXTURES, 0); /* context[0].textures[unit] */ indices[2] = LLVMConstInt(LLVMInt32Type(), unit, 0); /* context[0].textures[unit].member */ diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 9a85a42897d..8137f29af52 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -103,6 +103,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, unsigned height = align(lpt->base.height0, TILE_SIZE); lpt->dt = winsys->displaytarget_create(winsys, + lpt->base.tex_usage, lpt->base.format, width, height, 16, @@ -250,6 +251,51 @@ llvmpipe_texture_unmap(struct pipe_texture *texture, } +static struct pipe_texture * +llvmpipe_texture_from_handle(struct pipe_screen *screen, + const struct pipe_texture *template, + struct winsys_handle *whandle) +{ + struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys; + struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture); + if (!lpt) + return NULL; + + lpt->base = *template; + pipe_reference_init(&lpt->base.reference, 1); + lpt->base.screen = screen; + + lpt->dt = winsys->displaytarget_from_handle(winsys, + template, + whandle, + &lpt->stride[0]); + if (!lpt->dt) + goto fail; + + return &lpt->base; + + fail: + FREE(lpt); + return NULL; +} + + +static boolean +llvmpipe_texture_get_handle(struct pipe_screen *screen, + struct pipe_texture *pt, + struct winsys_handle *whandle) +{ + struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys; + struct llvmpipe_texture *lpt = llvmpipe_texture(pt); + + assert(lpt->dt); + if (!lpt->dt) + return FALSE; + + return winsys->displaytarget_get_handle(winsys, lpt->dt, whandle); +} + + static struct pipe_surface * llvmpipe_get_tex_surface(struct pipe_screen *screen, struct pipe_texture *pt, @@ -418,6 +464,8 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = llvmpipe_texture_create; screen->texture_destroy = llvmpipe_texture_destroy; + screen->texture_from_handle = llvmpipe_texture_from_handle; + screen->texture_get_handle = llvmpipe_texture_get_handle; screen->get_tex_surface = llvmpipe_get_tex_surface; screen->tex_surface_destroy = llvmpipe_tex_surface_destroy; |