llvmpipe: disconnect vertex texture sampling from the setup
it was wrong to put this in the fs paths, but it was easier to just stuff it along the fragment texture sampling paths. the patch disconnects vertex texture sampling and just maps the textures before the draw itself and unmaps them after.
This commit is contained in:
@@ -83,6 +83,7 @@ struct llvmpipe_context {
|
||||
int so_count[PIPE_MAX_SO_BUFFERS];
|
||||
int num_buffers;
|
||||
} so_target;
|
||||
struct pipe_resource *mapped_vs_tex[PIPE_MAX_VERTEX_SAMPLERS];
|
||||
|
||||
unsigned num_samplers;
|
||||
unsigned num_fragment_sampler_views;
|
||||
|
||||
@@ -84,6 +84,9 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
|
||||
draw_set_mapped_element_buffer_range(draw, 0, 0, start,
|
||||
start + count - 1, NULL);
|
||||
}
|
||||
llvmpipe_prepare_vertex_sampling(lp,
|
||||
lp->num_vertex_sampler_views,
|
||||
lp->vertex_sampler_views);
|
||||
|
||||
/* draw! */
|
||||
draw_arrays(draw, mode, start, count);
|
||||
@@ -97,6 +100,7 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
|
||||
if (indexBuffer) {
|
||||
draw_set_mapped_element_buffer(draw, 0, 0, NULL);
|
||||
}
|
||||
llvmpipe_cleanup_vertex_sampling(lp);
|
||||
|
||||
/*
|
||||
* TODO: Flush only when a user vertex/index buffer is present
|
||||
|
||||
@@ -656,75 +656,6 @@ 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
|
||||
@@ -918,9 +849,6 @@ 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);
|
||||
}
|
||||
|
||||
@@ -133,11 +133,6 @@ 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 );
|
||||
|
||||
@@ -116,10 +116,6 @@ 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;
|
||||
|
||||
@@ -130,6 +130,12 @@ llvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe);
|
||||
void
|
||||
llvmpipe_init_so_funcs(struct llvmpipe_context *llvmpipe);
|
||||
|
||||
void
|
||||
llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *ctx,
|
||||
unsigned num,
|
||||
struct pipe_sampler_view **views);
|
||||
void
|
||||
llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -188,14 +188,10 @@ 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -35,10 +35,9 @@
|
||||
#include "draw/draw_context.h"
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_screen.h"
|
||||
#include "lp_state.h"
|
||||
#include "draw/draw_context.h"
|
||||
|
||||
#include "state_tracker/sw_winsys.h"
|
||||
|
||||
|
||||
static void *
|
||||
@@ -222,6 +221,77 @@ 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)
|
||||
{
|
||||
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];
|
||||
|
||||
assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
|
||||
if (!num)
|
||||
return;
|
||||
|
||||
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(&lp->mapped_vs_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < Elements(ctx->mapped_vs_tex); i++) {
|
||||
pipe_resource_reference(&ctx->mapped_vs_tex[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user