summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2010-06-14 10:18:09 -0400
committerZack Rusin <[email protected]>2010-07-06 13:29:04 -0400
commit01eebfe1b6de2e36dd3af0952fc8329b7073a100 (patch)
tree23f1727a4e3a8788fbf82ff6b1fd374bc4ec8b19 /src/gallium/drivers/llvmpipe
parentce929d8210baf0ea66f32565285f0b33cd495e46 (diff)
draw: implement vertex texture sampling using llvm
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c73
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_sampler.c8
6 files changed, 96 insertions, 4 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 49b13f464a7..edcab0f8d95 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -86,7 +86,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return PIPE_MAX_SAMPLERS;
case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
- return 0;
+ return PIPE_MAX_VERTEX_SAMPLERS;
case PIPE_CAP_MAX_COMBINED_SAMPLERS:
return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
case PIPE_CAP_NPOT_TEXTURES:
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 2597fa8f71b..fcb6e06123d 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -641,7 +641,6 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
/*
* XXX: Where should this be unmapped?
*/
-
struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
struct sw_winsys *winsys = screen->winsys;
jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
@@ -658,6 +657,75 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
/**
+ * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
+ */
+void
+lp_setup_set_vertex_sampler_views(struct lp_setup_context *setup,
+ unsigned num,
+ struct pipe_sampler_view **views)
+{
+ unsigned i;
+ uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS];
+ uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS];
+ const void *data[DRAW_MAX_TEXTURE_LEVELS];
+ struct lp_scene *scene;
+ struct llvmpipe_context *lp;
+
+ LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
+
+ assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
+
+ scene = lp_setup_get_current_scene(setup);
+ lp = llvmpipe_context(scene->pipe);
+
+ for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
+
+ if (view) {
+ struct pipe_resource *tex = view->texture;
+ struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex);
+
+ /* We're referencing the texture's internal data, so save a
+ * reference to it.
+ */
+ pipe_resource_reference(&setup->vs.current_tex[i], tex);
+
+ if (!lp_tex->dt) {
+ /* regular texture - setup array of mipmap level pointers */
+ int j;
+ for (j = 0; j <= tex->last_level; j++) {
+ data[j] =
+ llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ,
+ LP_TEX_LAYOUT_LINEAR);
+ row_stride[j] = lp_tex->row_stride[j];
+ img_stride[j] = lp_tex->img_stride[j];
+ }
+ }
+ else {
+ /* display target texture/surface */
+ /*
+ * XXX: Where should this be unmapped?
+ */
+ struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
+ struct sw_winsys *winsys = screen->winsys;
+ data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
+ PIPE_TRANSFER_READ);
+ row_stride[0] = lp_tex->row_stride[0];
+ img_stride[0] = lp_tex->img_stride[0];
+ assert(data[0]);
+ }
+ draw_set_mapped_texture(lp->draw,
+ i,
+ tex->width0, tex->height0, tex->depth0,
+ tex->last_level,
+ row_stride, img_stride, data);
+ }
+ }
+}
+
+
+
+/**
* Is the given texture referenced by any scene?
* Note: we have to check all scenes including any scenes currently
* being rendered and the current scene being built.
@@ -850,6 +918,9 @@ lp_setup_destroy( struct lp_setup_context *setup )
util_unreference_framebuffer_state(&setup->fb);
+ for (i = 0; i < Elements(setup->vs.current_tex); i++) {
+ pipe_resource_reference(&setup->vs.current_tex[i], NULL);
+ }
for (i = 0; i < Elements(setup->fs.current_tex); i++) {
pipe_resource_reference(&setup->fs.current_tex[i], NULL);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index 6a0dc551290..fd2c927c2ea 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -133,6 +133,11 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
unsigned num,
struct pipe_sampler_view **views);
+void
+lp_setup_set_vertex_sampler_views(struct lp_setup_context *setup,
+ unsigned num,
+ struct pipe_sampler_view **views);
+
unsigned
lp_setup_is_resource_referenced( const struct lp_setup_context *setup,
const struct pipe_resource *texture );
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 8f4e00f0732..947d5efe2b0 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -116,6 +116,10 @@ struct lp_setup_context
struct pipe_resource *current_tex[PIPE_MAX_SAMPLERS];
} fs;
+ struct {
+ struct pipe_resource *current_tex[PIPE_MAX_VERTEX_SAMPLERS];
+ } vs;
+
/** fragment shader constants */
struct {
struct pipe_resource *current;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index d20a5218d41..263b1174940 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -188,10 +188,14 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
lp_setup_set_fs_constants(llvmpipe->setup,
llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]);
- if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW)
- lp_setup_set_fragment_sampler_views(llvmpipe->setup,
+ if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW) {
+ lp_setup_set_fragment_sampler_views(llvmpipe->setup,
llvmpipe->num_fragment_sampler_views,
llvmpipe->fragment_sampler_views);
+ lp_setup_set_vertex_sampler_views(llvmpipe->setup,
+ llvmpipe->num_vertex_sampler_views,
+ llvmpipe->vertex_sampler_views);
+ }
llvmpipe->dirty = 0;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index e94065fb6ab..0fea7f20a73 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -100,6 +100,10 @@ llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
llvmpipe->num_vertex_samplers = num_samplers;
+ draw_set_samplers(llvmpipe->draw,
+ llvmpipe->vertex_samplers,
+ llvmpipe->num_vertex_samplers);
+
llvmpipe->dirty |= LP_NEW_SAMPLER;
}
@@ -166,6 +170,10 @@ llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe,
llvmpipe->num_vertex_sampler_views = num;
+ draw_set_sampler_views(llvmpipe->draw,
+ llvmpipe->vertex_sampler_views,
+ llvmpipe->num_vertex_sampler_views);
+
llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
}