diff options
Diffstat (limited to 'src')
90 files changed, 1939 insertions, 713 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index 0ac18426d97..e2796d5bd38 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -119,6 +119,7 @@ C_SOURCES = \ util/u_mm.c \ util/u_rect.c \ util/u_ringbuffer.c \ + util/u_sampler.c \ util/u_simple_shaders.c \ util/u_snprintf.c \ util/u_surface.c \ @@ -126,12 +127,13 @@ C_SOURCES = \ util/u_tile.c \ util/u_timed_winsys.c \ util/u_upload_mgr.c \ - util/u_simple_screen.c \ - vl/vl_bitstream_parser.c \ - vl/vl_mpeg12_mc_renderer.c \ - vl/vl_compositor.c \ - vl/vl_csc.c \ - vl/vl_shader_build.c \ + util/u_simple_screen.c + # Disabling until pipe-video branch gets merged in + #vl/vl_bitstream_parser.c \ + #vl/vl_mpeg12_mc_renderer.c \ + #vl/vl_compositor.c \ + #vl/vl_csc.c \ + #vl/vl_shader_build.c \ target-helpers/wrap_screen.c GALLIVM_SOURCES = \ diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index 2be16776fb8..65e1dc8a58d 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -162,6 +162,7 @@ source = [ 'util/u_mm.c', 'util/u_rect.c', 'util/u_ringbuffer.c', + 'util/u_sampler.c', 'util/u_simple_shaders.c', 'util/u_snprintf.c', 'util/u_surface.c', @@ -170,11 +171,12 @@ source = [ 'util/u_timed_winsys.c', 'util/u_upload_mgr.c', 'util/u_simple_screen.c', - 'vl/vl_bitstream_parser.c', - 'vl/vl_mpeg12_mc_renderer.c', - 'vl/vl_compositor.c', - 'vl/vl_csc.c', - 'vl/vl_shader_build.c', + # Disabling until pipe-video branch gets merged in + #'vl/vl_bitstream_parser.c', + #'vl/vl_mpeg12_mc_renderer.c', + #'vl/vl_compositor.c', + #'vl/vl_csc.c', + #'vl/vl_shader_build.c', 'target-helpers/wrap_screen.c', ] diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 6500891a10c..4ed9e09c529 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -37,7 +37,9 @@ #include "pipe/p_state.h" #include "util/u_inlines.h" +#include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_sampler.h" #include "tgsi/tgsi_parse.h" #include "cso_cache/cso_context.h" @@ -69,17 +71,17 @@ struct cso_context { unsigned nr_vertex_samplers_saved; void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS]; - struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; - uint nr_textures; + uint nr_fragment_sampler_views; + struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; - struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; - uint nr_vertex_textures; + uint nr_vertex_sampler_views; + struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; - uint nr_textures_saved; - struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS]; + uint nr_fragment_sampler_views_saved; + struct pipe_sampler_view *fragment_sampler_views_saved[PIPE_MAX_SAMPLERS]; - uint nr_vertex_textures_saved; - struct pipe_texture *vertex_textures_saved[PIPE_MAX_SAMPLERS]; + uint nr_vertex_sampler_views_saved; + struct pipe_sampler_view *vertex_sampler_views_saved[PIPE_MAX_VERTEX_SAMPLERS]; /** Current and saved state. * The saved state is used as a 1-deep stack. @@ -293,13 +295,13 @@ void cso_release_all( struct cso_context *ctx ) } for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->textures[i], NULL); - pipe_texture_reference(&ctx->textures_saved[i], NULL); + pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL); + pipe_sampler_view_reference(&ctx->fragment_sampler_views_saved[i], NULL); } for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); - pipe_texture_reference(&ctx->vertex_textures_saved[i], NULL); + pipe_sampler_view_reference(&ctx->vertex_sampler_views[i], NULL); + pipe_sampler_view_reference(&ctx->vertex_sampler_views_saved[i], NULL); } free_framebuffer_state(&ctx->fb); @@ -622,108 +624,68 @@ enum pipe_error cso_set_sampler_textures( struct cso_context *ctx, { uint i; - ctx->nr_textures = count; + ctx->nr_fragment_sampler_views = count; - for (i = 0; i < count; i++) - pipe_texture_reference(&ctx->textures[i], textures[i]); - for ( ; i < PIPE_MAX_SAMPLERS; i++) - pipe_texture_reference(&ctx->textures[i], NULL); - - ctx->pipe->set_fragment_sampler_textures(ctx->pipe, count, textures); + for (i = 0; i < count; i++) { + struct pipe_sampler_view templ, *view; - return PIPE_OK; -} + u_sampler_view_default_template(&templ, + textures[i], + textures[i]->format); -void cso_save_sampler_textures( struct cso_context *ctx ) -{ - uint i; + view = ctx->pipe->create_sampler_view(ctx->pipe, + textures[i], + &templ); - ctx->nr_textures_saved = ctx->nr_textures; - for (i = 0; i < ctx->nr_textures; i++) { - assert(!ctx->textures_saved[i]); - pipe_texture_reference(&ctx->textures_saved[i], ctx->textures[i]); + pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], view); } -} - -void cso_restore_sampler_textures( struct cso_context *ctx ) -{ - uint i; - - ctx->nr_textures = ctx->nr_textures_saved; - - for (i = 0; i < ctx->nr_textures; i++) { - pipe_texture_reference(&ctx->textures[i], NULL); - ctx->textures[i] = ctx->textures_saved[i]; - ctx->textures_saved[i] = NULL; + for ( ; i < PIPE_MAX_SAMPLERS; i++) { + pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL); } - for ( ; i < PIPE_MAX_SAMPLERS; i++) - pipe_texture_reference(&ctx->textures[i], NULL); - - ctx->pipe->set_fragment_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures); - - ctx->nr_textures_saved = 0; -} - - -enum pipe_error -cso_set_vertex_sampler_textures(struct cso_context *ctx, - uint count, - struct pipe_texture **textures) -{ - uint i; - - ctx->nr_vertex_textures = count; - - for (i = 0; i < count; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], textures[i]); - } - for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); - } - - ctx->pipe->set_vertex_sampler_textures(ctx->pipe, count, textures); + ctx->pipe->set_fragment_sampler_views(ctx->pipe, + count, + ctx->fragment_sampler_views); return PIPE_OK; } -void -cso_save_vertex_sampler_textures(struct cso_context *ctx) +void cso_save_sampler_textures( struct cso_context *ctx ) { uint i; - ctx->nr_vertex_textures_saved = ctx->nr_vertex_textures; - for (i = 0; i < ctx->nr_vertex_textures; i++) { - assert(!ctx->vertex_textures_saved[i]); - pipe_texture_reference(&ctx->vertex_textures_saved[i], ctx->vertex_textures[i]); + ctx->nr_fragment_sampler_views_saved = ctx->nr_fragment_sampler_views; + for (i = 0; i < ctx->nr_fragment_sampler_views; i++) { + assert(!ctx->fragment_sampler_views_saved[i]); + + pipe_sampler_view_reference(&ctx->fragment_sampler_views_saved[i], + ctx->fragment_sampler_views[i]); } } -void -cso_restore_vertex_sampler_textures(struct cso_context *ctx) +void cso_restore_sampler_textures( struct cso_context *ctx ) { uint i; - ctx->nr_vertex_textures = ctx->nr_vertex_textures_saved; + ctx->nr_fragment_sampler_views = ctx->nr_fragment_sampler_views_saved; - for (i = 0; i < ctx->nr_vertex_textures; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); - ctx->vertex_textures[i] = ctx->vertex_textures_saved[i]; - ctx->vertex_textures_saved[i] = NULL; + for (i = 0; i < ctx->nr_fragment_sampler_views; i++) { + pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL); + ctx->fragment_sampler_views[i] = ctx->fragment_sampler_views_saved[i]; + ctx->fragment_sampler_views_saved[i] = NULL; } - for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); + for ( ; i < PIPE_MAX_SAMPLERS; i++) { + pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL); } - ctx->pipe->set_vertex_sampler_textures(ctx->pipe, - ctx->nr_vertex_textures, - ctx->vertex_textures); + ctx->pipe->set_fragment_sampler_views(ctx->pipe, + ctx->nr_fragment_sampler_views, + ctx->fragment_sampler_views); - ctx->nr_vertex_textures_saved = 0; + ctx->nr_fragment_sampler_views_saved = 0; } - enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx, const struct pipe_depth_stencil_alpha_state *templ) { @@ -1261,3 +1223,122 @@ void cso_restore_vertex_elements(struct cso_context *ctx) } ctx->velements_saved = NULL; } + +/* fragment sampler view state */ + +void +cso_set_fragment_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views) +{ + uint i; + + for (i = 0; i < count; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], views[i]); + } + for (; i < cso->nr_fragment_sampler_views; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL); + } + + cso->pipe->set_fragment_sampler_views(cso->pipe, + MAX2(count, cso->nr_fragment_sampler_views), + cso->fragment_sampler_views); + + cso->nr_fragment_sampler_views = count; +} + +void +cso_save_fragment_sampler_views(struct cso_context *cso) +{ + uint i; + + cso->nr_fragment_sampler_views_saved = cso->nr_fragment_sampler_views; + + for (i = 0; i < cso->nr_fragment_sampler_views; i++) { + assert(!cso->fragment_sampler_views_saved[i]); + + pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i], + cso->fragment_sampler_views[i]); + } +} + +void +cso_restore_fragment_sampler_views(struct cso_context *cso) +{ + uint i; + + for (i = 0; i < cso->nr_fragment_sampler_views_saved; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], cso->fragment_sampler_views_saved[i]); + pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i], NULL); + } + for (; i < cso->nr_fragment_sampler_views; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL); + } + + cso->pipe->set_fragment_sampler_views(cso->pipe, + MAX2(cso->nr_fragment_sampler_views, cso->nr_fragment_sampler_views_saved), + cso->fragment_sampler_views); + + cso->nr_fragment_sampler_views = cso->nr_fragment_sampler_views_saved; + cso->nr_fragment_sampler_views_saved = 0; +} + + +/* vertex sampler view state */ + +void +cso_set_vertex_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views) +{ + uint i; + + for (i = 0; i < count; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], views[i]); + } + for (; i < cso->nr_vertex_sampler_views; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL); + } + + cso->pipe->set_vertex_sampler_views(cso->pipe, + MAX2(count, cso->nr_vertex_sampler_views), + cso->vertex_sampler_views); + + cso->nr_vertex_sampler_views = count; +} + +void +cso_save_vertex_sampler_views(struct cso_context *cso) +{ + uint i; + + cso->nr_vertex_sampler_views_saved = cso->nr_vertex_sampler_views; + + for (i = 0; i < cso->nr_vertex_sampler_views; i++) { + assert(!cso->vertex_sampler_views_saved[i]); + + pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i], + cso->vertex_sampler_views[i]); + } +} + +void +cso_restore_vertex_sampler_views(struct cso_context *cso) +{ + uint i; + + for (i = 0; i < cso->nr_vertex_sampler_views_saved; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], cso->vertex_sampler_views_saved[i]); + pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i], NULL); + } + for (; i < cso->nr_vertex_sampler_views; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL); + } + + cso->pipe->set_vertex_sampler_views(cso->pipe, + MAX2(cso->nr_vertex_sampler_views, cso->nr_vertex_sampler_views_saved), + cso->vertex_sampler_views); + + cso->nr_vertex_sampler_views = cso->nr_vertex_sampler_views_saved; + cso->nr_vertex_sampler_views_saved = 0; +} diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 9c16abd28dd..a24077e009c 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -111,17 +111,6 @@ void cso_save_sampler_textures( struct cso_context *cso ); void cso_restore_sampler_textures( struct cso_context *cso ); - -enum pipe_error -cso_set_vertex_sampler_textures(struct cso_context *cso, - uint count, - struct pipe_texture **textures); -void -cso_save_vertex_sampler_textures(struct cso_context *cso); -void -cso_restore_vertex_sampler_textures(struct cso_context *cso); - - enum pipe_error cso_set_vertex_elements(struct cso_context *ctx, unsigned count, const struct pipe_vertex_element *states); @@ -198,6 +187,34 @@ void cso_restore_clip(struct cso_context *cso); +/* fragment sampler view state */ + +void +cso_set_fragment_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views); + +void +cso_save_fragment_sampler_views(struct cso_context *cso); + +void +cso_restore_fragment_sampler_views(struct cso_context *cso); + + +/* vertex sampler view state */ + +void +cso_set_vertex_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views); + +void +cso_save_vertex_sampler_views(struct cso_context *cso); + +void +cso_restore_vertex_sampler_views(struct cso_context *cso); + + #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 1c07ab13654..f4615064e65 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -40,6 +40,7 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_sampler.h" #include "tgsi/tgsi_transform.h" #include "tgsi/tgsi_dump.h" @@ -88,8 +89,9 @@ struct aaline_stage void *sampler_cso; struct pipe_texture *texture; + struct pipe_sampler_view *sampler_view; uint num_samplers; - uint num_textures; + uint num_sampler_views; /* @@ -98,7 +100,7 @@ struct aaline_stage struct aaline_fragment_shader *fs; struct { void *sampler[PIPE_MAX_SAMPLERS]; - struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; } state; /* @@ -111,8 +113,9 @@ struct aaline_stage void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **); - void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, - struct pipe_texture **); + void (*driver_set_sampler_views)(struct pipe_context *, + unsigned, + struct pipe_sampler_view **); struct pipe_context *pipe; }; @@ -394,6 +397,7 @@ aaline_create_texture(struct aaline_stage *aaline) struct pipe_context *pipe = aaline->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_texture texTemp; + struct pipe_sampler_view viewTempl; uint level; memset(&texTemp, 0, sizeof(texTemp)); @@ -408,6 +412,16 @@ aaline_create_texture(struct aaline_stage *aaline) if (!aaline->texture) return FALSE; + u_sampler_view_default_template(&viewTempl, + aaline->texture, + aaline->texture->format); + aaline->sampler_view = pipe->create_sampler_view(pipe, + aaline->texture, + &viewTempl); + if (!aaline->sampler_view) { + return FALSE; + } + /* Fill in mipmap images. * Basically each level is solid opaque, except for the outermost * texels which are zero. Special case the 1x1 and 2x2 levels. @@ -669,16 +683,16 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) /* how many samplers? */ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ - num_samplers = MAX2(aaline->num_textures, aaline->num_samplers); + num_samplers = MAX2(aaline->num_sampler_views, aaline->num_samplers); num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1); aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso; - pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit], - aaline->texture); + pipe_sampler_view_reference(&aaline->state.sampler_views[aaline->fs->sampler_unit], + aaline->sampler_view); draw->suspend_flushing = TRUE; aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler); - aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture); + aaline->driver_set_sampler_views(pipe, num_samplers, aaline->state.sampler_views); draw->suspend_flushing = FALSE; /* now really draw first line */ @@ -702,8 +716,9 @@ aaline_flush(struct draw_stage *stage, unsigned flags) aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, aaline->state.sampler); - aaline->driver_set_sampler_textures(pipe, aaline->num_textures, - aaline->state.texture); + aaline->driver_set_sampler_views(pipe, + aaline->num_sampler_views, + aaline->state.sampler_views); draw->suspend_flushing = FALSE; draw->extra_shader_outputs.slot = 0; @@ -724,7 +739,7 @@ aaline_destroy(struct draw_stage *stage) uint i; for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&aaline->state.texture[i], NULL); + pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL); } if (aaline->sampler_cso) @@ -733,6 +748,10 @@ aaline_destroy(struct draw_stage *stage) if (aaline->texture) pipe_texture_reference(&aaline->texture, NULL); + if (aaline->sampler_view) { + pipe_sampler_view_reference(&aaline->sampler_view, NULL); + } + draw_free_temp_verts( stage ); FREE( stage ); @@ -844,23 +863,24 @@ aaline_bind_sampler_states(struct pipe_context *pipe, static void -aaline_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) +aaline_set_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); uint i; /* save current */ for (i = 0; i < num; i++) { - pipe_texture_reference(&aaline->state.texture[i], texture[i]); + pipe_sampler_view_reference(&aaline->state.sampler_views[i], views[i]); } for ( ; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&aaline->state.texture[i], NULL); + pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL); } - aaline->num_textures = num; + aaline->num_sampler_views = num; /* pass-through */ - aaline->driver_set_sampler_textures(aaline->pipe, num, texture); + aaline->driver_set_sampler_views(aaline->pipe, num, views); } @@ -898,7 +918,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) aaline->driver_delete_fs_state = pipe->delete_fs_state; aaline->driver_bind_sampler_states = pipe->bind_fragment_sampler_states; - aaline->driver_set_sampler_textures = pipe->set_fragment_sampler_textures; + aaline->driver_set_sampler_views = pipe->set_fragment_sampler_views; /* override the driver's functions */ pipe->create_fs_state = aaline_create_fs_state; @@ -906,7 +926,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) pipe->delete_fs_state = aaline_delete_fs_state; pipe->bind_fragment_sampler_states = aaline_bind_sampler_states; - pipe->set_fragment_sampler_textures = aaline_set_sampler_textures; + pipe->set_fragment_sampler_views = aaline_set_sampler_views; /* Install once everything is known to be OK: */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 38c22bf4e94..794fd81d70f 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -42,6 +42,7 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_sampler.h" #include "tgsi/tgsi_transform.h" #include "tgsi/tgsi_dump.h" @@ -75,8 +76,9 @@ struct pstip_stage void *sampler_cso; struct pipe_texture *texture; + struct pipe_sampler_view *sampler_view; uint num_samplers; - uint num_textures; + uint num_sampler_views; /* * Currently bound state @@ -84,7 +86,7 @@ struct pstip_stage struct pstip_fragment_shader *fs; struct { void *samplers[PIPE_MAX_SAMPLERS]; - struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; const struct pipe_poly_stipple *stipple; } state; @@ -98,8 +100,9 @@ struct pstip_stage void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **); - void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, - struct pipe_texture **); + void (*driver_set_sampler_views)(struct pipe_context *, + unsigned, + struct pipe_sampler_view **); void (*driver_set_polygon_stipple)(struct pipe_context *, const struct pipe_poly_stipple *); @@ -424,6 +427,7 @@ pstip_create_texture(struct pstip_stage *pstip) struct pipe_context *pipe = pstip->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_texture texTemp; + struct pipe_sampler_view viewTempl; memset(&texTemp, 0, sizeof(texTemp)); texTemp.target = PIPE_TEXTURE_2D; @@ -437,6 +441,16 @@ pstip_create_texture(struct pstip_stage *pstip) if (pstip->texture == NULL) return FALSE; + u_sampler_view_default_template(&viewTempl, + pstip->texture, + pstip->texture->format); + pstip->sampler_view = pipe->create_sampler_view(pipe, + pstip->texture, + &viewTempl); + if (!pstip->sampler_view) { + return FALSE; + } + return TRUE; } @@ -515,19 +529,19 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) /* how many samplers? */ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ - num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); + num_samplers = MAX2(pstip->num_sampler_views, pstip->num_samplers); num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1); /* plug in our sampler, texture */ pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso; - pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit], - pstip->texture); + pipe_sampler_view_reference(&pstip->state.sampler_views[pstip->fs->sampler_unit], + pstip->sampler_view); assert(num_samplers <= PIPE_MAX_SAMPLERS); draw->suspend_flushing = TRUE; pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); - pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); + pstip->driver_set_sampler_views(pipe, num_samplers, pstip->state.sampler_views); draw->suspend_flushing = FALSE; /* now really draw first triangle */ @@ -551,8 +565,9 @@ pstip_flush(struct draw_stage *stage, unsigned flags) pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, pstip->state.samplers); - pstip->driver_set_sampler_textures(pipe, pstip->num_textures, - pstip->state.textures); + pstip->driver_set_sampler_views(pipe, + pstip->num_sampler_views, + pstip->state.sampler_views); draw->suspend_flushing = FALSE; } @@ -571,13 +586,17 @@ pstip_destroy(struct draw_stage *stage) uint i; for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&pstip->state.textures[i], NULL); + pipe_sampler_view_reference(&pstip->state.sampler_views[i], NULL); } pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso); pipe_texture_reference(&pstip->texture, NULL); + if (pstip->sampler_view) { + pipe_sampler_view_reference(&pstip->sampler_view, NULL); + } + draw_free_temp_verts( stage ); FREE( stage ); } @@ -682,24 +701,25 @@ pstip_bind_sampler_states(struct pipe_context *pipe, static void -pstip_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) +pstip_set_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); uint i; /* save current */ for (i = 0; i < num; i++) { - pipe_texture_reference(&pstip->state.textures[i], texture[i]); + pipe_sampler_view_reference(&pstip->state.sampler_views[i], views[i]); } for (; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&pstip->state.textures[i], NULL); + pipe_sampler_view_reference(&pstip->state.sampler_views[i], NULL); } - pstip->num_textures = num; + pstip->num_sampler_views = num; /* pass-through */ - pstip->driver_set_sampler_textures(pstip->pipe, num, texture); + pstip->driver_set_sampler_views(pstip->pipe, num, views); } @@ -756,7 +776,7 @@ draw_install_pstipple_stage(struct draw_context *draw, pstip->driver_delete_fs_state = pipe->delete_fs_state; pstip->driver_bind_sampler_states = pipe->bind_fragment_sampler_states; - pstip->driver_set_sampler_textures = pipe->set_fragment_sampler_textures; + pstip->driver_set_sampler_views = pipe->set_fragment_sampler_views; pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; /* override the driver's functions */ @@ -765,7 +785,7 @@ draw_install_pstipple_stage(struct draw_context *draw, pipe->delete_fs_state = pstip_delete_fs_state; pipe->bind_fragment_sampler_states = pstip_bind_sampler_states; - pipe->set_fragment_sampler_textures = pstip_set_sampler_textures; + pipe->set_fragment_sampler_views = pstip_set_sampler_views; pipe->set_polygon_stipple = pstip_set_polygon_stipple; return TRUE; diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 4d0737ccd3d..4d9168face3 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -45,6 +45,7 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_sampler.h" #include "util/u_simple_shaders.h" #include "util/u_surface.h" #include "util/u_rect.h" @@ -280,6 +281,7 @@ regions_overlap(int srcX0, int srcY0, void util_blit_pixels_writemask(struct blit_state *ctx, struct pipe_surface *src, + struct pipe_sampler_view *src_sampler_view, int srcX0, int srcY0, int srcX1, int srcY1, struct pipe_surface *dst, @@ -290,7 +292,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, { struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_texture *tex = NULL; + struct pipe_sampler_view *sampler_view = NULL; struct pipe_framebuffer_state fb; const int srcW = abs(srcX1 - srcX0); const int srcH = abs(srcY1 - srcY0); @@ -345,6 +347,8 @@ util_blit_pixels_writemask(struct blit_state *ctx, src->texture->last_level != 0) { struct pipe_texture texTemp; + struct pipe_texture *tex; + struct pipe_sampler_view sv_templ; struct pipe_surface *texSurf; const int srcLeft = MIN2(srcX0, srcX1); const int srcTop = MIN2(srcY0, srcY1); @@ -376,6 +380,14 @@ util_blit_pixels_writemask(struct blit_state *ctx, if (!tex) return; + u_sampler_view_default_template(&sv_templ, tex, tex->format); + + sampler_view = ctx->pipe->create_sampler_view(ctx->pipe, tex, &sv_templ); + if (!sampler_view) { + pipe_texture_reference(&tex, NULL); + return; + } + texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); @@ -399,22 +411,25 @@ util_blit_pixels_writemask(struct blit_state *ctx, s1 = 1.0f; t0 = 0.0f; t1 = 1.0f; + + pipe_texture_reference(&tex, NULL); } else { - pipe_texture_reference(&tex, src->texture); - s0 = srcX0 / (float)tex->width0; - s1 = srcX1 / (float)tex->width0; - t0 = srcY0 / (float)tex->height0; - t1 = srcY1 / (float)tex->height0; + pipe_sampler_view_reference(&sampler_view, src_sampler_view); + s0 = srcX0 / (float)src->texture->width0; + s1 = srcX1 / (float)src->texture->width0; + t0 = srcY0 / (float)src->texture->height0; + t1 = srcY1 / (float)src->texture->height0; } + /* save state (restored below) */ cso_save_blend(ctx->cso); cso_save_depth_stencil_alpha(ctx->cso); cso_save_rasterizer(ctx->cso); cso_save_samplers(ctx->cso); - cso_save_sampler_textures(ctx->cso); + cso_save_fragment_sampler_views(ctx->cso); cso_save_viewport(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); @@ -447,7 +462,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_set_viewport(ctx->cso, &ctx->viewport); /* texture */ - cso_set_sampler_textures(ctx->cso, 1, &tex); + cso_set_fragment_sampler_views(ctx->cso, 1, &sampler_view); if (ctx->fs[writemask] == NULL) ctx->fs[writemask] = @@ -486,7 +501,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_restore_depth_stencil_alpha(ctx->cso); cso_restore_rasterizer(ctx->cso); cso_restore_samplers(ctx->cso); - cso_restore_sampler_textures(ctx->cso); + cso_restore_fragment_sampler_views(ctx->cso); cso_restore_viewport(ctx->cso); cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); @@ -494,13 +509,14 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_restore_clip(ctx->cso); cso_restore_vertex_elements(ctx->cso); - pipe_texture_reference(&tex, NULL); + pipe_sampler_view_reference(&sampler_view, NULL); } void util_blit_pixels(struct blit_state *ctx, struct pipe_surface *src, + struct pipe_sampler_view *src_sampler_view, int srcX0, int srcY0, int srcX1, int srcY1, struct pipe_surface *dst, @@ -508,7 +524,7 @@ util_blit_pixels(struct blit_state *ctx, int dstX1, int dstY1, float z, uint filter ) { - util_blit_pixels_writemask( ctx, src, + util_blit_pixels_writemask( ctx, src, src_sampler_view, srcX0, srcY0, srcX1, srcY1, dst, diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h index a102021529e..2d8cdd25fb9 100644 --- a/src/gallium/auxiliary/util/u_blit.h +++ b/src/gallium/auxiliary/util/u_blit.h @@ -53,6 +53,7 @@ util_destroy_blit(struct blit_state *ctx); extern void util_blit_pixels(struct blit_state *ctx, struct pipe_surface *src, + struct pipe_sampler_view *src_sampler_view, int srcX0, int srcY0, int srcX1, int srcY1, struct pipe_surface *dst, @@ -63,6 +64,7 @@ util_blit_pixels(struct blit_state *ctx, void util_blit_pixels_writemask(struct blit_state *ctx, struct pipe_surface *src, + struct pipe_sampler_view *src_sampler_view, int srcX0, int srcY0, int srcX1, int srcY1, struct pipe_surface *dst, diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 36d582491f3..1692987e8e3 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -45,6 +45,7 @@ #include "util/u_draw_quad.h" #include "util/u_pack_color.h" #include "util/u_rect.h" +#include "util/u_sampler.h" #include "util/u_simple_shaders.h" #include "util/u_texture.h" @@ -96,6 +97,8 @@ struct blitter_context_priv /* Rasterizer state. */ void *rs_state; + struct pipe_sampler_view *sampler_view; + /* Viewport state. */ struct pipe_viewport_state viewport; @@ -127,7 +130,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) ctx->blitter.saved_vs = INVALID_PTR; ctx->blitter.saved_velem_state = INVALID_PTR; ctx->blitter.saved_fb_state.nr_cbufs = ~0; - ctx->blitter.saved_num_textures = ~0; + ctx->blitter.saved_num_sampler_views = ~0; ctx->blitter.saved_num_sampler_states = ~0; /* blend state objects */ @@ -252,6 +255,10 @@ void util_blitter_destroy(struct blitter_context *blitter) if (ctx->sampler_state[i]) pipe->delete_sampler_state(pipe, ctx->sampler_state[i]); + if (ctx->sampler_view) { + pipe_sampler_view_reference(&ctx->sampler_view, NULL); + } + pipe_buffer_reference(&ctx->vbuf, NULL); FREE(ctx); } @@ -305,11 +312,11 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx) ctx->blitter.saved_num_sampler_states = ~0; } - if (ctx->blitter.saved_num_textures != ~0) { - pipe->set_fragment_sampler_textures(pipe, - ctx->blitter.saved_num_textures, - ctx->blitter.saved_textures); - ctx->blitter.saved_num_textures = ~0; + if (ctx->blitter.saved_num_sampler_views != ~0) { + pipe->set_fragment_sampler_views(pipe, + ctx->blitter.saved_num_sampler_views, + ctx->blitter.saved_sampler_views); + ctx->blitter.saved_num_sampler_views = ~0; } } @@ -621,9 +628,10 @@ static void util_blitter_do_copy(struct blitter_context *blitter, struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = ctx->pipe; struct pipe_framebuffer_state fb_state; + struct pipe_sampler_view viewTempl, *view; assert(blitter->saved_fb_state.nr_cbufs != ~0); - assert(blitter->saved_num_textures != ~0); + assert(blitter->saved_num_sampler_views != ~0); assert(blitter->saved_num_sampler_states != ~0); assert(src->texture->target < PIPE_MAX_TEXTURE_TYPES); @@ -651,12 +659,24 @@ static void util_blitter_do_copy(struct blitter_context *blitter, fb_state.zsbuf = 0; } + u_sampler_view_default_template(&viewTempl, + src->texture, + src->texture->format); + view = pipe->create_sampler_view(pipe, + src->texture, + &viewTempl); + + if (ctx->sampler_view) { + pipe_sampler_view_reference(&ctx->sampler_view, NULL); + } + ctx->sampler_view = view; + pipe->bind_rasterizer_state(pipe, ctx->rs_state); pipe->bind_vs_state(pipe, ctx->vs_tex); pipe->bind_fragment_sampler_states(pipe, 1, blitter_get_sampler_state(ctx, src->level)); pipe->bind_vertex_elements_state(pipe, ctx->velem_state); - pipe->set_fragment_sampler_textures(pipe, 1, &src->texture); + pipe->set_fragment_sampler_views(pipe, 1, &view); pipe->set_framebuffer_state(pipe, &fb_state); /* set texture coordinates */ diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index ecafdabafae..2ad7201a29d 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -53,10 +53,10 @@ struct blitter_context struct pipe_clip_state saved_clip; int saved_num_sampler_states; - void *saved_sampler_states[32]; + void *saved_sampler_states[PIPE_MAX_SAMPLERS]; - int saved_num_textures; - struct pipe_texture *saved_textures[32]; /* is 32 enough? */ + int saved_num_sampler_views; + struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS]; }; /** @@ -242,17 +242,17 @@ void util_blitter_save_fragment_sampler_states( num_sampler_states * sizeof(void *)); } -static INLINE -void util_blitter_save_fragment_sampler_textures( - struct blitter_context *blitter, - int num_textures, - struct pipe_texture **textures) +static INLINE void +util_blitter_save_fragment_sampler_views(struct blitter_context *blitter, + int num_views, + struct pipe_sampler_view **views) { - assert(num_textures <= Elements(blitter->saved_textures)); + assert(num_views <= Elements(blitter->saved_sampler_views)); - blitter->saved_num_textures = num_textures; - memcpy(blitter->saved_textures, textures, - num_textures * sizeof(struct pipe_texture *)); + blitter->saved_num_sampler_views = num_views; + memcpy(blitter->saved_sampler_views, + views, + num_views * sizeof(struct pipe_sampler_view *)); } #ifdef __cplusplus diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index e7255e3baa8..e22ab188e11 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -120,6 +120,16 @@ pipe_texture_reference(struct pipe_texture **ptr, struct pipe_texture *tex) *ptr = tex; } +static INLINE void +pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view) +{ + struct pipe_sampler_view *old_view = *ptr; + + if (pipe_reference(&(*ptr)->reference, &view->reference)) + old_view->context->sampler_view_destroy(old_view->context, old_view); + *ptr = view; +} + /* * Convenience wrappers for screen buffer functions. diff --git a/src/gallium/auxiliary/util/u_sampler.c b/src/gallium/auxiliary/util/u_sampler.c new file mode 100644 index 00000000000..4d8f861ce49 --- /dev/null +++ b/src/gallium/auxiliary/util/u_sampler.c @@ -0,0 +1,100 @@ +/************************************************************************** + * + * 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 "u_format.h" +#include "u_sampler.h" + + +static void +default_template(struct pipe_sampler_view *view, + const struct pipe_texture *texture, + enum pipe_format format, + unsigned expand_green_blue) +{ + /* XXX: Check if format is compatible with texture->format. + */ + + view->format = format; + view->first_level = 0; + view->last_level = texture->last_level; + view->swizzle_r = PIPE_SWIZZLE_RED; + view->swizzle_g = PIPE_SWIZZLE_GREEN; + view->swizzle_b = PIPE_SWIZZLE_BLUE; + view->swizzle_a = PIPE_SWIZZLE_ALPHA; + + /* Override default green and blue component expansion to the requested + * one. + * + * Gallium expands nonexistent components to (0,0,0,1), DX9 expands + * to (1,1,1,1). Since alpha is always expanded to 1, and red is + * always present, we only really care about green and blue + * components. + * + * To make it look less hackish, one would have to add + * UTIL_FORMAT_SWIZZLE_EXPAND to indicate components for expansion + * and then override without exceptions or favoring one component + * over another. + */ + if (format != PIPE_FORMAT_A8_UNORM) { + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (desc) { + if (desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0) { + view->swizzle_g = expand_green_blue; + } + if (desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0) { + view->swizzle_b = expand_green_blue; + } + } + } +} + +void +u_sampler_view_default_template(struct pipe_sampler_view *view, + const struct pipe_texture *texture, + enum pipe_format format) +{ + /* Expand to (0, 0, 0, 1) */ + default_template(view, + texture, + format, + PIPE_SWIZZLE_ZERO); +} + +void +u_sampler_view_default_dx9_template(struct pipe_sampler_view *view, + const struct pipe_texture *texture, + enum pipe_format format) +{ + /* Expand to (1, 1, 1, 1) */ + default_template(view, + texture, + format, + PIPE_SWIZZLE_ONE); +} diff --git a/src/gallium/auxiliary/util/u_sampler.h b/src/gallium/auxiliary/util/u_sampler.h new file mode 100644 index 00000000000..bdd061c851c --- /dev/null +++ b/src/gallium/auxiliary/util/u_sampler.h @@ -0,0 +1,57 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + + +#ifndef U_SAMPLER_H +#define U_SAMPLER_H + + +#include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "pipe/p_state.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +void +u_sampler_view_default_template(struct pipe_sampler_view *view, + const struct pipe_texture *texture, + enum pipe_format format); + +void +u_sampler_view_default_dx9_template(struct pipe_sampler_view *view, + const struct pipe_texture *texture, + enum pipe_format format); + + +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif /* U_SAMPLER_H */ diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c index e445895efc5..82e44192aaf 100644 --- a/src/gallium/auxiliary/util/u_tile.c +++ b/src/gallium/auxiliary/util/u_tile.c @@ -1275,6 +1275,69 @@ pipe_get_tile_rgba(struct pipe_context *pipe, void +pipe_get_tile_swizzle(struct pipe_context *pipe, + struct pipe_transfer *pt, + uint x, + uint y, + uint w, + uint h, + uint swizzle_r, + uint swizzle_g, + uint swizzle_b, + uint swizzle_a, + enum pipe_format format, + float *p) +{ + unsigned dst_stride = w * 4; + void *packed; + uint i; + float rgba01[6]; + + if (pipe_clip_tile(x, y, &w, &h, pt)) { + return; + } + + packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); + if (!packed) { + return; + } + + if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) { + assert((x & 1) == 0); + } + + pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0); + + pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride); + + FREE(packed); + + if (swizzle_r == PIPE_SWIZZLE_RED && + swizzle_g == PIPE_SWIZZLE_GREEN && + swizzle_b == PIPE_SWIZZLE_BLUE && + swizzle_a == PIPE_SWIZZLE_ALPHA) { + /* no-op, skip */ + return; + } + + rgba01[PIPE_SWIZZLE_ZERO] = 0.0f; + rgba01[PIPE_SWIZZLE_ONE] = 1.0f; + + for (i = 0; i < w * h; i++) { + rgba01[PIPE_SWIZZLE_RED] = p[0]; + rgba01[PIPE_SWIZZLE_GREEN] = p[1]; + rgba01[PIPE_SWIZZLE_BLUE] = p[2]; + rgba01[PIPE_SWIZZLE_ALPHA] = p[3]; + + *p++ = rgba01[swizzle_r]; + *p++ = rgba01[swizzle_g]; + *p++ = rgba01[swizzle_b]; + *p++ = rgba01[swizzle_a]; + } +} + + +void pipe_put_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *pt, uint x, uint y, uint w, uint h, diff --git a/src/gallium/auxiliary/util/u_tile.h b/src/gallium/auxiliary/util/u_tile.h index 8329087cfa6..1d8ce7d8cbc 100644 --- a/src/gallium/auxiliary/util/u_tile.h +++ b/src/gallium/auxiliary/util/u_tile.h @@ -75,6 +75,20 @@ pipe_get_tile_rgba(struct pipe_context *pipe, float *p); void +pipe_get_tile_swizzle(struct pipe_context *pipe, + struct pipe_transfer *pt, + uint x, + uint y, + uint w, + uint h, + uint swizzle_r, + uint swizzle_g, + uint swizzle_b, + uint swizzle_a, + enum pipe_format format, + float *p); + +void pipe_put_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *pt, uint x, uint y, uint w, uint h, diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index 4608e97adbb..ef3e4639314 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -40,8 +40,24 @@ buffers, surfaces) are bound to the driver. are mostly restricted to the first one right now). * ``set_framebuffer_state`` -* ``set_fragment_sampler_textures`` -* ``set_vertex_sampler_textures`` + +* ``set_fragment_sampler_views`` binds an array of sampler views to + fragment shader stage. Every binding point acquires a reference + to a respective sampler view and releases a reference to the previous + sampler view. + +* ``set_vertex_sampler_views`` binds an array of sampler views to vertex + shader stage. Every binding point acquires a reference to a respective + sampler view and releases a reference to the previous sampler view. + +* ``create_sampler_view`` creates a new sampler view. texture is associated + with the sampler view which results in sampler view holding a reference + to the texture. Format specified in template must be compatible + with texture format. + +* ``sampler_view_destroy`` destroys a sampler view and releases its reference + to associated texture. + * ``set_vertex_buffers`` diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 28f80b82cd5..4d87f9a038a 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -127,6 +127,7 @@ struct cell_context struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct cell_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; uint num_textures; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index dce10ae7f86..059ce8597bc 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -257,8 +257,9 @@ cell_delete_sampler_state(struct pipe_context *pipe, static void -cell_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) +cell_set_fragment_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct cell_context *cell = cell_context(pipe); uint i, changed = 0x0; @@ -266,10 +267,14 @@ cell_set_sampler_textures(struct pipe_context *pipe, assert(num <= CELL_MAX_SAMPLERS); for (i = 0; i < CELL_MAX_SAMPLERS; i++) { - struct cell_texture *new_tex = cell_texture(i < num ? texture[i] : NULL); - struct cell_texture *old_tex = cell->texture[i]; - if (old_tex != new_tex) { + struct pipe_sampler_view *new_view = i < num ? views[i] : NULL; + struct pipe_sampler_view *old_view = cell->fragment_sampler_views[i]; + if (old_view != new_view) { + struct pipe_texture *new_tex = new_view ? new_view->texture : NULL; + + pipe_sampler_view_reference(&cell->fragment_sampler_views[i], + views[i]); pipe_texture_reference((struct pipe_texture **) &cell->texture[i], (struct pipe_texture *) new_tex); @@ -286,6 +291,34 @@ cell_set_sampler_textures(struct pipe_context *pipe, } +static struct pipe_sampler_view * +cell_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; +} + + +static void +cell_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + pipe_texture_reference(&view->texture, NULL); + FREE(view); +} + + /** * Map color and z/stencil framebuffer surfaces. */ @@ -409,7 +442,9 @@ cell_init_state_functions(struct cell_context *cell) cell->pipe.bind_fragment_sampler_states = cell_bind_sampler_states; cell->pipe.delete_sampler_state = cell_delete_sampler_state; - cell->pipe.set_fragment_sampler_textures = cell_set_sampler_textures; + cell->pipe.set_fragment_sampler_views = cell_set_fragment_sampler_views; + cell->pipe.create_sampler_view = cell_create_sampler_view; + cell->pipe.sampler_view_destroy = cell_sampler_view_destroy; cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state; cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state; diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 4a754465bbe..73031321d98 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -47,7 +47,7 @@ #define FO_NEW_ALPHA_TEST 0x100 #define FO_NEW_DEPTH_STENCIL 0x200 #define FO_NEW_SAMPLER 0x400 -#define FO_NEW_TEXTURE 0x800 +#define FO_NEW_SAMPLER_VIEW 0x800 #define FO_NEW_VERTEX 0x2000 #define FO_NEW_VERTEX_SHADER 0x4000 #define FO_NEW_BLEND_COLOR 0x8000 @@ -65,6 +65,13 @@ struct fo_state { void *sw_state; void *hw_state; }; + +struct fo_sampler_view { + struct pipe_sampler_view base; + struct pipe_sampler_view *sw; + struct pipe_sampler_view *hw; +}; + struct failover_context { struct pipe_context pipe; /**< base class */ @@ -86,8 +93,6 @@ struct failover_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_viewport_state viewport; struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; @@ -98,12 +103,15 @@ struct failover_context { void *sw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS]; void *hw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS]; + struct fo_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; + struct fo_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; + unsigned num_fragment_sampler_views; + unsigned num_vertex_sampler_views; + unsigned dirty; unsigned num_samplers; unsigned num_vertex_samplers; - unsigned num_textures; - unsigned num_vertex_textures; unsigned mode; struct pipe_context *hw; diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index 0247fb803b2..25c62735705 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -447,60 +447,96 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler) } +static struct pipe_sampler_view * +failover_create_sampler_view(struct pipe_context *pipe, + struct pipe_texture *texture, + const struct pipe_sampler_view *templ) +{ + struct fo_sampler_view *view = malloc(sizeof(struct fo_sampler_view)); + struct failover_context *failover = failover_context(pipe); + + view->sw = failover->sw->create_sampler_view(failover->sw, texture, templ); + view->hw = failover->hw->create_sampler_view(failover->hw, texture, templ); + + view->base = *templ; + view->base.reference.count = 1; + view->base.texture = NULL; + pipe_texture_reference(&view->base.texture, texture); + view->base.context = pipe; + + return &view->base; +} + +static void +failover_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + struct fo_sampler_view *fo_view = (struct fo_sampler_view *)view; + struct failover_context *failover = failover_context(pipe); + + failover->sw->sampler_view_destroy(failover->sw, fo_view->sw); + failover->hw->sampler_view_destroy(failover->hw, fo_view->hw); + + pipe_texture_reference(&fo_view->base.texture, NULL); + free(fo_view); +} + static void -failover_set_fragment_sampler_textures(struct pipe_context *pipe, - unsigned num, - struct pipe_texture **texture) +failover_set_fragment_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct failover_context *failover = failover_context(pipe); + struct pipe_sampler_view *hw_views[PIPE_MAX_SAMPLERS]; uint i; assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ - if (num == failover->num_textures && - !memcmp(failover->texture, texture, num * sizeof(struct pipe_texture *))) + if (num == failover->num_fragment_sampler_views && + !memcmp(failover->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) return; - for (i = 0; i < num; i++) - pipe_texture_reference((struct pipe_texture **) &failover->texture[i], - texture[i]); - for (i = num; i < failover->num_textures; i++) - pipe_texture_reference((struct pipe_texture **) &failover->texture[i], - NULL); - failover->dirty |= FO_NEW_TEXTURE; - failover->num_textures = num; - failover->sw->set_fragment_sampler_textures( failover->sw, num, texture ); - failover->hw->set_fragment_sampler_textures( failover->hw, num, texture ); + for (i = 0; i < num; i++) { + struct fo_sampler_view *fo_view = (struct fo_sampler_view *)views[i]; + + pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->fragment_sampler_views[i], views[i]); + hw_views[i] = fo_view->hw; + } + for (i = num; i < failover->num_fragment_sampler_views; i++) + pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->fragment_sampler_views[i], NULL); + failover->dirty |= FO_NEW_SAMPLER_VIEW; + failover->num_fragment_sampler_views = num; + failover->hw->set_fragment_sampler_views(failover->hw, num, hw_views); } static void -failover_set_vertex_sampler_textures(struct pipe_context *pipe, - unsigned num_textures, - struct pipe_texture **textures) +failover_set_vertex_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct failover_context *failover = failover_context(pipe); + struct pipe_sampler_view *hw_views[PIPE_MAX_VERTEX_SAMPLERS]; uint i; - assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS); + assert(num <= PIPE_MAX_VERTEX_SAMPLERS); /* Check for no-op */ - if (num_textures == failover->num_vertex_textures && - !memcmp(failover->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) { + if (num == failover->num_vertex_sampler_views && + !memcmp(failover->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { return; } - for (i = 0; i < num_textures; i++) { - pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i], - textures[i]); - } - for (i = num_textures; i < failover->num_vertex_textures; i++) { - pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i], - NULL); + for (i = 0; i < num; i++) { + struct fo_sampler_view *fo_view = (struct fo_sampler_view *)views[i]; + + pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->vertex_sampler_views[i], views[i]); + hw_views[i] = fo_view->hw; } - failover->dirty |= FO_NEW_TEXTURE; - failover->num_vertex_textures = num_textures; - failover->sw->set_vertex_sampler_textures(failover->sw, num_textures, textures); - failover->hw->set_vertex_sampler_textures(failover->hw, num_textures, textures); + for (i = num; i < failover->num_vertex_sampler_views; i++) + pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->vertex_sampler_views[i], NULL); + failover->dirty |= FO_NEW_SAMPLER_VIEW; + failover->num_vertex_sampler_views = num; + failover->hw->set_vertex_sampler_views(failover->hw, num, hw_views); } @@ -580,9 +616,11 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.set_framebuffer_state = failover_set_framebuffer_state; failover->pipe.set_polygon_stipple = failover_set_polygon_stipple; failover->pipe.set_scissor_state = failover_set_scissor_state; - failover->pipe.set_fragment_sampler_textures = failover_set_fragment_sampler_textures; - failover->pipe.set_vertex_sampler_textures = failover_set_vertex_sampler_textures; + failover->pipe.set_fragment_sampler_views = failover_set_fragment_sampler_views; + failover->pipe.set_vertex_sampler_views = failover_set_vertex_sampler_views; failover->pipe.set_viewport_state = failover_set_viewport_state; failover->pipe.set_vertex_buffers = failover_set_vertex_buffers; failover->pipe.set_constant_buffer = failover_set_constant_buffer; + failover->pipe.create_sampler_view = failover_create_sampler_view; + failover->pipe.sampler_view_destroy = failover_sampler_view_destroy; } diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c index 09ca1944971..42bd6929a7f 100644 --- a/src/gallium/drivers/failover/fo_state_emit.c +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -106,12 +106,24 @@ failover_state_emit( struct failover_context *failover ) failover->sw_vertex_sampler_state); } - if (failover->dirty & FO_NEW_TEXTURE) { - failover->sw->set_fragment_sampler_textures( failover->sw, failover->num_textures, - failover->texture ); - failover->sw->set_vertex_sampler_textures(failover->sw, - failover->num_vertex_textures, - failover->vertex_textures); + if (failover->dirty & FO_NEW_SAMPLER_VIEW) { + struct pipe_sampler_view *fragment_views[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *vertex_views[PIPE_MAX_VERTEX_SAMPLERS]; + uint i; + + for (i = 0; i < failover->num_fragment_sampler_views; i++) { + fragment_views[i] = failover->fragment_sampler_views[i]->sw; + } + failover->sw->set_fragment_sampler_views(failover->sw, + failover->num_fragment_sampler_views, + fragment_views); + + for (i = 0; i < failover->num_vertex_sampler_views; i++) { + vertex_views[i] = failover->vertex_sampler_views[i]->sw; + } + failover->sw->set_vertex_sampler_views(failover->sw, + failover->num_vertex_sampler_views, + vertex_views); } if (failover->dirty & FO_NEW_VERTEX_BUFFER) { diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index 039165b63f5..5348f62ca74 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -247,14 +247,14 @@ struct i915_context struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct i915_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; unsigned dirty; unsigned num_samplers; - unsigned num_textures; + unsigned num_fragment_sampler_views; unsigned num_vertex_buffers; struct intel_batchbuffer *batch; @@ -283,7 +283,7 @@ struct i915_context #define I915_NEW_ALPHA_TEST 0x100 #define I915_NEW_DEPTH_STENCIL 0x200 #define I915_NEW_SAMPLER 0x400 -#define I915_NEW_TEXTURE 0x800 +#define I915_NEW_SAMPLER_VIEW 0x800 #define I915_NEW_CONSTANTS 0x1000 #define I915_NEW_VBO 0x2000 #define I915_NEW_VS 0x4000 diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 377d8425a5c..0f7395246cc 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -560,9 +560,9 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, } -static void i915_set_sampler_textures(struct pipe_context *pipe, - unsigned num, - struct pipe_texture **texture) +static void i915_set_fragment_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct i915_context *i915 = i915_context(pipe); uint i; @@ -570,27 +570,54 @@ static void i915_set_sampler_textures(struct pipe_context *pipe, assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ - if (num == i915->num_textures && - !memcmp(i915->texture, texture, num * sizeof(struct pipe_texture *))) + if (num == i915->num_fragment_sampler_views && + !memcmp(i915->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) return; /* Fixes wrong texture in texobj with VBUF */ draw_flush(i915->draw); for (i = 0; i < num; i++) - pipe_texture_reference((struct pipe_texture **) &i915->texture[i], - texture[i]); + pipe_sampler_view_reference(&i915->fragment_sampler_views[i], + views[i]); - for (i = num; i < i915->num_textures; i++) - pipe_texture_reference((struct pipe_texture **) &i915->texture[i], - NULL); + for (i = num; i < i915->num_fragment_sampler_views; i++) + pipe_sampler_view_reference(&i915->fragment_sampler_views[i], + NULL); - i915->num_textures = num; + i915->num_fragment_sampler_views = num; - i915->dirty |= I915_NEW_TEXTURE; + i915->dirty |= I915_NEW_SAMPLER_VIEW; } +static struct pipe_sampler_view * +i915_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; +} + + +static void +i915_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + pipe_texture_reference(&view->texture, NULL); + FREE(view); +} + static void i915_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) @@ -818,7 +845,9 @@ i915_init_state_functions( struct i915_context *i915 ) i915->base.set_polygon_stipple = i915_set_polygon_stipple; i915->base.set_scissor_state = i915_set_scissor_state; - i915->base.set_fragment_sampler_textures = i915_set_sampler_textures; + i915->base.set_fragment_sampler_views = i915_set_fragment_sampler_views; + i915->base.create_sampler_view = i915_create_sampler_view; + i915->base.sampler_view_destroy = i915_sampler_view_destroy; i915->base.set_viewport_state = i915_set_viewport_state; i915->base.set_vertex_buffers = i915_set_vertex_buffers; } diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c index f5b0e9f011e..0eb1e3f91a4 100644 --- a/src/gallium/drivers/i915/i915_state_derived.c +++ b/src/gallium/drivers/i915/i915_state_derived.c @@ -157,10 +157,10 @@ void i915_update_derived( struct i915_context *i915 ) if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS)) calculate_vertex_layout( i915 ); - if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_TEXTURE)) + if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_SAMPLER_VIEW)) i915_update_samplers(i915); - if (i915->dirty & I915_NEW_TEXTURE) + if (i915->dirty & I915_NEW_SAMPLER_VIEW) i915_update_textures(i915); if (i915->dirty) diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 51f0ef12baf..d79c1ca0b2c 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -290,7 +290,8 @@ i915_emit_hardware_state(struct i915_context *i915 ) OUT_BATCH(enabled); for (unit = 0; unit < I915_TEX_UNITS; unit++) { if (enabled & (1 << unit)) { - struct intel_buffer *buf = i915->texture[unit]->buffer; + struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture; + struct intel_buffer *buf = texture->buffer; uint offset = 0; assert(buf); diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index 9813290b51b..d6da8225490 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -144,20 +144,22 @@ void i915_update_samplers( struct i915_context *i915 ) i915->current.sampler_enable_nr = 0; i915->current.sampler_enable_flags = 0x0; - for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers; + for (unit = 0; unit < i915->num_fragment_sampler_views && unit < i915->num_samplers; unit++) { /* determine unit enable/disable by looking for a bound texture */ /* could also examine the fragment program? */ - if (i915->texture[unit]) { + if (i915->fragment_sampler_views[unit]) { + struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture; + update_sampler( i915, unit, i915->sampler[unit], /* sampler state */ - i915->texture[unit], /* texture */ + texture, /* texture */ i915->current.sampler[unit] /* the result */ ); i915_update_texture( i915, unit, - i915->texture[unit], /* texture */ + texture, /* texture */ i915->sampler[unit], /* sampler state */ i915->current.texbuffer[unit] ); @@ -281,14 +283,16 @@ i915_update_textures(struct i915_context *i915) { uint unit; - for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers; + for (unit = 0; unit < i915->num_fragment_sampler_views && unit < i915->num_samplers; unit++) { /* determine unit enable/disable by looking for a bound texture */ /* could also examine the fragment program? */ - if (i915->texture[unit]) { + if (i915->fragment_sampler_views[unit]) { + struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture; + i915_update_texture( i915, unit, - i915->texture[unit], /* texture */ + texture, /* texture */ i915->sampler[unit], /* sampler state */ i915->current.texbuffer[unit] ); } diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index f5b1a06576b..dab881fea24 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -551,9 +551,9 @@ struct brw_context const struct brw_sampler *sampler[PIPE_MAX_SAMPLERS]; unsigned num_samplers; - struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - unsigned num_textures; + unsigned num_fragment_sampler_views; unsigned num_vertex_buffers; struct pipe_scissor_state scissor; diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c index c7c0e2ae95e..d2aa2bc9f35 100644 --- a/src/gallium/drivers/i965/brw_pipe_sampler.c +++ b/src/gallium/drivers/i965/brw_pipe_sampler.c @@ -183,26 +183,26 @@ static void brw_delete_sampler_state(struct pipe_context *pipe, FREE(cso); } -static void brw_set_sampler_textures(struct pipe_context *pipe, - unsigned num, - struct pipe_texture **texture) +static void brw_set_fragment_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct brw_context *brw = brw_context(pipe); int i; for (i = 0; i < num; i++) - pipe_texture_reference(&brw->curr.texture[i], texture[i]); + pipe_sampler_view_reference(&brw->curr.fragment_sampler_views[i], views[i]); - for (i = num; i < brw->curr.num_textures; i++) - pipe_texture_reference(&brw->curr.texture[i], NULL); + for (i = num; i < brw->curr.num_fragment_sampler_views; i++) + pipe_sampler_view_reference(&brw->curr.fragment_sampler_views[i], NULL); - brw->curr.num_textures = num; + brw->curr.num_fragment_sampler_views = num; brw->state.dirty.mesa |= PIPE_NEW_BOUND_TEXTURES; } -static void brw_set_vertex_sampler_textures(struct pipe_context *pipe, - unsigned num, - struct pipe_texture **texture) +static void brw_set_vertex_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { } @@ -212,17 +212,47 @@ static void brw_bind_vertex_sampler_state(struct pipe_context *pipe, } +static struct pipe_sampler_view * +brw_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; +} + + +static void +brw_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + pipe_texture_reference(&view->texture, NULL); + FREE(view); +} + + void brw_pipe_sampler_init( struct brw_context *brw ) { brw->base.create_sampler_state = brw_create_sampler_state; brw->base.delete_sampler_state = brw_delete_sampler_state; - brw->base.set_fragment_sampler_textures = brw_set_sampler_textures; + brw->base.set_fragment_sampler_views = brw_set_fragment_sampler_views; brw->base.bind_fragment_sampler_states = brw_bind_sampler_state; - brw->base.set_vertex_sampler_textures = brw_set_vertex_sampler_textures; + brw->base.set_vertex_sampler_views = brw_set_vertex_sampler_views; brw->base.bind_vertex_sampler_states = brw_bind_vertex_sampler_state; + brw->base.create_sampler_view = brw_create_sampler_view; + brw->base.sampler_view_destroy = brw_sampler_view_destroy; } void brw_pipe_sampler_cleanup( struct brw_context *brw ) { diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c index dfb718e64fe..7ed2378ec04 100644 --- a/src/gallium/drivers/i965/brw_wm.c +++ b/src/gallium/drivers/i965/brw_wm.c @@ -251,8 +251,8 @@ static void brw_wm_populate_key( struct brw_context *brw, /* PIPE_NEW_BOUND_TEXTURES */ - for (i = 0; i < brw->curr.num_textures; i++) { - const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); + for (i = 0; i < brw->curr.num_fragment_sampler_views; i++) { + const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture); if (tex->base.format == PIPE_FORMAT_UYVY) key->yuvtex_mask |= 1 << i; diff --git a/src/gallium/drivers/i965/brw_wm_sampler_state.c b/src/gallium/drivers/i965/brw_wm_sampler_state.c index 6a6086fc51b..3f18062c584 100644 --- a/src/gallium/drivers/i965/brw_wm_sampler_state.c +++ b/src/gallium/drivers/i965/brw_wm_sampler_state.c @@ -78,11 +78,11 @@ brw_wm_sampler_populate_key(struct brw_context *brw, memset(key, 0, sizeof(*key)); - key->sampler_count = MIN2(brw->curr.num_textures, + key->sampler_count = MIN2(brw->curr.num_fragment_sampler_views, brw->curr.num_samplers); for (i = 0; i < key->sampler_count; i++) { - const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); + const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture); const struct brw_sampler *sampler = brw->curr.sampler[i]; struct brw_sampler_state *entry = &key->sampler[i]; @@ -122,12 +122,12 @@ static enum pipe_error brw_wm_sampler_update_default_colors(struct brw_context *brw) { enum pipe_error ret; - int nr = MIN2(brw->curr.num_textures, + int nr = MIN2(brw->curr.num_fragment_sampler_views, brw->curr.num_samplers); int i; for (i = 0; i < nr; i++) { - const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); + const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture); const struct brw_sampler *sampler = brw->curr.sampler[i]; const float *bc; float bordercolor[4] = { diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c index b01a7f194b7..2368ae3f808 100644 --- a/src/gallium/drivers/i965/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965/brw_wm_surface_state.c @@ -242,9 +242,9 @@ static enum pipe_error prepare_wm_surfaces(struct brw_context *brw ) /* PIPE_NEW_TEXTURE */ - for (i = 0; i < brw->curr.num_textures; i++) { + for (i = 0; i < brw->curr.num_fragment_sampler_views; i++) { ret = brw_update_texture_surface(brw, - brw_texture(brw->curr.texture[i]), + brw_texture(brw->curr.fragment_sampler_views[i]->texture), &brw->wm.surf_bo[BTI_TEXTURE(i)]); if (ret) return ret; @@ -261,7 +261,7 @@ static enum pipe_error prepare_wm_surfaces(struct brw_context *brw ) bo_reference(&brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS], NULL); /* XXX: no pipe_max_textures define?? */ - for (i = brw->curr.num_textures; i < PIPE_MAX_SAMPLERS; i++) + for (i = brw->curr.num_fragment_sampler_views; i < PIPE_MAX_SAMPLERS; i++) bo_reference(&brw->wm.surf_bo[BTI_TEXTURE(i)], NULL); if (brw->wm.nr_surfaces != nr_surfaces) { diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index 26770d6b1e9..00a542215ad 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -528,53 +528,49 @@ identity_set_viewport_state(struct pipe_context *_pipe, } static void -identity_set_fragment_sampler_textures(struct pipe_context *_pipe, - unsigned num_textures, - struct pipe_texture **_textures) +identity_set_fragment_sampler_views(struct pipe_context *_pipe, + unsigned num, + struct pipe_sampler_view **_views) { struct identity_context *id_pipe = identity_context(_pipe); struct pipe_context *pipe = id_pipe->pipe; - struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS]; - struct pipe_texture **textures = NULL; + struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view **views = NULL; unsigned i; - if (_textures) { - for (i = 0; i < num_textures; i++) - unwrapped_textures[i] = identity_texture_unwrap(_textures[i]); + if (_views) { + for (i = 0; i < num; i++) + unwrapped_views[i] = identity_sampler_view_unwrap(_views[i]); for (; i < PIPE_MAX_SAMPLERS; i++) - unwrapped_textures[i] = NULL; + unwrapped_views[i] = NULL; - textures = unwrapped_textures; + views = unwrapped_views; } - pipe->set_fragment_sampler_textures(pipe, - num_textures, - textures); + pipe->set_fragment_sampler_views(pipe, num, views); } static void -identity_set_vertex_sampler_textures(struct pipe_context *_pipe, - unsigned num_textures, - struct pipe_texture **_textures) +identity_set_vertex_sampler_views(struct pipe_context *_pipe, + unsigned num, + struct pipe_sampler_view **_views) { struct identity_context *id_pipe = identity_context(_pipe); struct pipe_context *pipe = id_pipe->pipe; - struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS]; - struct pipe_texture **textures = NULL; + struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS]; + struct pipe_sampler_view **views = NULL; unsigned i; - if (_textures) { - for (i = 0; i < num_textures; i++) - unwrapped_textures[i] = identity_texture_unwrap(_textures[i]); + if (_views) { + for (i = 0; i < num; i++) + unwrapped_views[i] = identity_sampler_view_unwrap(_views[i]); for (; i < PIPE_MAX_VERTEX_SAMPLERS; i++) - unwrapped_textures[i] = NULL; + unwrapped_views[i] = NULL; - textures = unwrapped_textures; + views = unwrapped_views; } - pipe->set_vertex_sampler_textures(pipe, - num_textures, - textures); + pipe->set_vertex_sampler_views(pipe, num, views); } static void @@ -711,6 +707,45 @@ identity_is_buffer_referenced(struct pipe_context *_pipe, buffer); } +static struct pipe_sampler_view * +identity_create_sampler_view(struct pipe_context *pipe, + struct pipe_texture *texture, + const struct pipe_sampler_view *templ) +{ + struct identity_context *id_pipe = identity_context(pipe); + struct identity_texture *id_texture = identity_texture(texture); + struct pipe_context *pipe_unwrapped = id_pipe->pipe; + struct pipe_texture *texture_unwrapped = id_texture->texture; + struct identity_sampler_view *view = malloc(sizeof(struct identity_sampler_view)); + + view->sampler_view = pipe_unwrapped->create_sampler_view(pipe_unwrapped, + texture_unwrapped, + templ); + + view->base = *templ; + view->base.reference.count = 1; + view->base.texture = NULL; + pipe_texture_reference(&view->base.texture, texture); + view->base.context = pipe; + + return &view->base; +} + +static void +identity_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + struct identity_context *id_pipe = identity_context(pipe); + struct identity_sampler_view *id_view = identity_sampler_view(view); + struct pipe_context *pipe_unwrapped = id_pipe->pipe; + struct pipe_sampler_view *view_unwrapped = id_view->sampler_view; + + pipe_unwrapped->sampler_view_destroy(pipe_unwrapped, + view_unwrapped); + + pipe_texture_reference(&view->texture, NULL); + free(view); +} static struct pipe_transfer * @@ -836,8 +871,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple; id_pipe->base.set_scissor_state = identity_set_scissor_state; id_pipe->base.set_viewport_state = identity_set_viewport_state; - id_pipe->base.set_fragment_sampler_textures = identity_set_fragment_sampler_textures; - id_pipe->base.set_vertex_sampler_textures = identity_set_vertex_sampler_textures; + id_pipe->base.set_fragment_sampler_views = identity_set_fragment_sampler_views; + id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views; id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers; id_pipe->base.surface_copy = identity_surface_copy; id_pipe->base.surface_fill = identity_surface_fill; @@ -845,6 +880,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.flush = identity_flush; id_pipe->base.is_texture_referenced = identity_is_texture_referenced; id_pipe->base.is_buffer_referenced = identity_is_buffer_referenced; + id_pipe->base.create_sampler_view = identity_create_sampler_view; + id_pipe->base.sampler_view_destroy = identity_sampler_view_destroy; id_pipe->base.get_tex_transfer = identity_context_get_tex_transfer; id_pipe->base.tex_transfer_destroy = identity_context_tex_transfer_destroy; id_pipe->base.transfer_map = identity_context_transfer_map; diff --git a/src/gallium/drivers/identity/id_objects.h b/src/gallium/drivers/identity/id_objects.h index 7333ecfb7fb..9a07ebe8d72 100644 --- a/src/gallium/drivers/identity/id_objects.h +++ b/src/gallium/drivers/identity/id_objects.h @@ -53,6 +53,14 @@ struct identity_texture }; +struct identity_sampler_view +{ + struct pipe_sampler_view base; + + struct pipe_sampler_view *sampler_view; +}; + + struct identity_surface { struct pipe_surface base; @@ -96,6 +104,15 @@ identity_texture(struct pipe_texture *_texture) return (struct identity_texture *)_texture; } +static INLINE struct identity_sampler_view * +identity_sampler_view(struct pipe_sampler_view *_sampler_view) +{ + if (!_sampler_view) { + return NULL; + } + return (struct identity_sampler_view *)_sampler_view; +} + static INLINE struct identity_surface * identity_surface(struct pipe_surface *_surface) { @@ -140,6 +157,15 @@ identity_texture_unwrap(struct pipe_texture *_texture) return identity_texture(_texture)->texture; } +static INLINE struct pipe_sampler_view * +identity_sampler_view_unwrap(struct pipe_sampler_view *_sampler_view) +{ + if (!_sampler_view) { + return NULL; + } + return identity_sampler_view(_sampler_view)->sampler_view; +} + static INLINE struct pipe_surface * identity_surface_unwrap(struct pipe_surface *_surface) { diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 945e3e05588..951a695f964 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -68,11 +68,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++) { @@ -156,8 +156,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_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 16128c34c80..cd16b6b2d38 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -450,11 +450,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 +464,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]; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index be1bf96f12d..414eaec98d1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -121,8 +121,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_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 34dd5234ce3..be02e97648e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.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 @@ -192,14 +192,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..9c91ce9238f 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) @@ -182,10 +182,10 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) 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 64f988d6d01..a2ec8c39435 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -1094,7 +1094,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]); } 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/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 1743f6fb394..bc7831d9aca 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -72,12 +72,23 @@ struct nv50_sampler_stateobj { unsigned tsc[8]; }; +struct nv50_sampler_view { + struct pipe_sampler_view pipe; + uint32_t tic[8]; +}; + struct nv50_vtxelt_stateobj { struct pipe_vertex_element pipe[16]; unsigned num_elements; uint32_t hw[16]; }; +static INLINE struct nv50_sampler_view * +nv50_sampler_view(struct pipe_sampler_view *view) +{ + return (struct nv50_sampler_view *)view; +} + static INLINE unsigned get_tile_height(uint32_t tile_mode) { @@ -126,7 +137,7 @@ struct nv50_state { struct nouveau_stateobj *hw[64]; uint64_t hw_dirty; - unsigned miptree_nr[PIPE_SHADER_TYPES]; + unsigned sampler_view_nr[3]; struct nouveau_stateobj *vtxbuf; struct nouveau_stateobj *vtxattr; unsigned vtxelt_nr; @@ -158,10 +169,10 @@ struct nv50_context { struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned vtxbuf_nr; struct nv50_vtxelt_stateobj *vtxelt; - struct nv50_sampler_stateobj *sampler[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; - unsigned sampler_nr[PIPE_SHADER_TYPES]; - struct nv50_miptree *miptree[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; - unsigned miptree_nr[PIPE_SHADER_TYPES]; + struct nv50_sampler_stateobj *sampler[3][PIPE_MAX_SAMPLERS]; + unsigned sampler_nr[3]; + struct pipe_sampler_view *sampler_views[3][PIPE_MAX_SAMPLERS]; + unsigned sampler_view_nr[3]; unsigned vbo_fifo; }; @@ -243,6 +254,7 @@ extern void nv50_so_init_sifc(struct nv50_context *nv50, unsigned offset, unsigned size); /* nv50_tex.c */ +extern boolean nv50_tex_construct(struct nv50_sampler_view *view); extern void nv50_tex_relocs(struct nv50_context *); extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index adf0d3b3741..d7f5863fb71 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -442,7 +442,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000131 | (NV50_CB_PFP << 12)); - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32, + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4), &screen->tic); if (ret) { nv50_screen_destroy(pscreen); @@ -454,9 +454,9 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_data (so, PIPE_SHADER_TYPES * 32 - 1); + so_data (so, 3 * 32 - 1); - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32, + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4), &screen->tsc); if (ret) { nv50_screen_destroy(pscreen); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index b0e5552eff4..c1628089285 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -238,6 +238,9 @@ nv50_sampler_state_create(struct pipe_context *pipe, return (void *)sso; } +/* type == 0 for VPs, 1 for GPs, 2 for FPs, which is how the + * relevant tesla methods are indexed (NV50TCL_BIND_TSC etc.) + */ static INLINE void nv50_sampler_state_bind(struct pipe_context *pipe, unsigned type, unsigned nr, void **sampler) @@ -253,13 +256,13 @@ nv50_sampler_state_bind(struct pipe_context *pipe, unsigned type, static void nv50_vp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s) { - nv50_sampler_state_bind(pipe, PIPE_SHADER_VERTEX, nr, s); + nv50_sampler_state_bind(pipe, 0, nr, s); } static void nv50_fp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s) { - nv50_sampler_state_bind(pipe, PIPE_SHADER_FRAGMENT, nr, s); + nv50_sampler_state_bind(pipe, 2, nr, s); } static void @@ -269,35 +272,69 @@ nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso) } static INLINE void -nv50_set_sampler_texture(struct pipe_context *pipe, unsigned type, - unsigned nr, struct pipe_texture **pt) +nv50_set_sampler_views(struct pipe_context *pipe, unsigned p, + unsigned nr, + struct pipe_sampler_view **views) { struct nv50_context *nv50 = nv50_context(pipe); unsigned i; for (i = 0; i < nr; i++) - pipe_texture_reference((void *)&nv50->miptree[type][i], pt[i]); - for (i = nr; i < nv50->miptree_nr[type]; i++) - pipe_texture_reference((void *)&nv50->miptree[type][i], NULL); + pipe_sampler_view_reference(&nv50->sampler_views[p][i], + views[i]); + + for (i = nr; i < nv50->sampler_view_nr[p]; i++) + pipe_sampler_view_reference(&nv50->sampler_views[p][i], NULL); - nv50->miptree_nr[type] = nr; + nv50->sampler_view_nr[p] = nr; nv50->dirty |= NV50_NEW_TEXTURE; } static void -nv50_set_vp_sampler_textures(struct pipe_context *pipe, - unsigned nr, struct pipe_texture **pt) +nv50_set_vp_sampler_views(struct pipe_context *pipe, + unsigned nr, + struct pipe_sampler_view **views) { - nv50_set_sampler_texture(pipe, PIPE_SHADER_VERTEX, nr, pt); + nv50_set_sampler_views(pipe, 0, nr, views); } static void -nv50_set_fp_sampler_textures(struct pipe_context *pipe, - unsigned nr, struct pipe_texture **pt) +nv50_set_fp_sampler_views(struct pipe_context *pipe, + unsigned nr, + struct pipe_sampler_view **views) { - nv50_set_sampler_texture(pipe, PIPE_SHADER_FRAGMENT, nr, pt); + nv50_set_sampler_views(pipe, 2, nr, views); } +static void +nv50_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + pipe_texture_reference(&view->texture, NULL); + FREE(nv50_sampler_view(view)); +} + +static struct pipe_sampler_view * +nv50_create_sampler_view(struct pipe_context *pipe, + struct pipe_texture *texture, + const struct pipe_sampler_view *templ) +{ + struct nv50_sampler_view *view = CALLOC_STRUCT(nv50_sampler_view); + + view->pipe = *templ; + view->pipe.reference.count = 1; + view->pipe.texture = NULL; + pipe_texture_reference(&view->pipe.texture, texture); + view->pipe.context = pipe; + + if (!nv50_tex_construct(view)) { + nv50_sampler_view_destroy(pipe, &view->pipe); + return NULL; + } + return &view->pipe; +} + + static void * nv50_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) @@ -765,8 +802,10 @@ nv50_init_state_functions(struct nv50_context *nv50) nv50->pipe.delete_sampler_state = nv50_sampler_state_delete; nv50->pipe.bind_fragment_sampler_states = nv50_fp_sampler_state_bind; nv50->pipe.bind_vertex_sampler_states = nv50_vp_sampler_state_bind; - nv50->pipe.set_fragment_sampler_textures = nv50_set_fp_sampler_textures; - nv50->pipe.set_vertex_sampler_textures = nv50_set_vp_sampler_textures; + nv50->pipe.set_fragment_sampler_views = nv50_set_fp_sampler_views; + nv50->pipe.set_vertex_sampler_views = nv50_set_vp_sampler_views; + nv50->pipe.create_sampler_view = nv50_create_sampler_view; + nv50->pipe.sampler_view_destroy = nv50_sampler_view_destroy; nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create; nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind; diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 2c8e7ca7982..63d73b5ce83 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -310,15 +310,13 @@ validate_sampler(struct nv50_context *nv50) struct nouveau_stateobj *so; unsigned nr = 0, i; - for (i = 0; i < PIPE_SHADER_TYPES; ++i) + for (i = 0; i < 3; ++i) nr += nv50->sampler_nr[i]; - so = so_new(1 + 5 * PIPE_SHADER_TYPES, - 1 + 19 * PIPE_SHADER_TYPES + nr * 8, - PIPE_SHADER_TYPES * 2); + so = so_new(1 + 5 * 3, 1 + 19 * 3 + nr * 8, 3 * 2); - nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX); - nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT); + nv50_validate_samplers(nv50, so, 0); /* VP */ + nv50_validate_samplers(nv50, so, 2); /* FP */ so_method(so, tesla, 0x1334, 1); /* flush TSC */ so_data (so, 0); diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index eb64f6cee48..85ab947c006 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -29,26 +29,16 @@ #include "util/u_format.h" #define _MIXED(pf, t0, t1, t2, t3, cr, cg, cb, ca, f) \ -{ \ - PIPE_FORMAT_##pf, \ +[PIPE_FORMAT_##pf] = ( \ NV50TIC_0_0_MAPR_##cr | NV50TIC_0_0_TYPER_##t0 | \ NV50TIC_0_0_MAPG_##cg | NV50TIC_0_0_TYPEG_##t1 | \ NV50TIC_0_0_MAPB_##cb | NV50TIC_0_0_TYPEB_##t2 | \ NV50TIC_0_0_MAPA_##ca | NV50TIC_0_0_TYPEA_##t3 | \ - NV50TIC_0_0_FMT_##f \ -} + NV50TIC_0_0_FMT_##f) #define _(pf, t, cr, cg, cb, ca, f) _MIXED(pf, t, t, t, t, cr, cg, cb, ca, f) -struct nv50_texture_format { - enum pipe_format pf; - uint32_t hw; -}; - -#define NV50_TEX_FORMAT_LIST_SIZE \ - (sizeof(nv50_tex_format_list) / sizeof(struct nv50_texture_format)) - -static const struct nv50_texture_format nv50_tex_format_list[] = +static const uint32_t nv50_texture_formats[PIPE_FORMAT_COUNT] = { _(B8G8R8A8_UNORM, UNORM, C2, C1, C0, C3, 8_8_8_8), _(B8G8R8A8_SRGB, UNORM, C2, C1, C0, C3, 8_8_8_8), @@ -60,10 +50,12 @@ static const struct nv50_texture_format nv50_tex_format_list[] = _(B5G6R5_UNORM, UNORM, C2, C1, C0, ONE, 5_6_5), _(L8_UNORM, UNORM, C0, C0, C0, ONE, 8), + _(L8_SRGB, UNORM, C0, C0, C0, ONE, 8), _(A8_UNORM, UNORM, ZERO, ZERO, ZERO, C0, 8), _(I8_UNORM, UNORM, C0, C0, C0, C0, 8), _(L8A8_UNORM, UNORM, C0, C0, C0, C1, 8_8), + _(L8A8_SRGB, UNORM, C0, C0, C0, C1, 8_8), _(DXT1_RGB, UNORM, C0, C1, C2, ONE, DXT1), _(DXT1_RGBA, UNORM, C0, C1, C2, C3, DXT1), @@ -81,118 +73,143 @@ static const struct nv50_texture_format nv50_tex_format_list[] = _(R16G16_UNORM, UNORM, C0, C1, ZERO, ONE, 16_16), _MIXED(Z32_FLOAT, FLOAT, UINT, UINT, UINT, C0, C0, C0, ONE, 32_DEPTH) - }; #undef _ #undef _MIXED -static int -nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so, - struct nv50_miptree *mt, int unit, unsigned p) +static INLINE uint32_t +nv50_tic_swizzle(uint32_t tc, unsigned swz) +{ + switch (swz) { + case PIPE_SWIZZLE_RED: + return (tc & NV50TIC_0_0_MAPR_MASK) >> NV50TIC_0_0_MAPR_SHIFT; + case PIPE_SWIZZLE_GREEN: + return (tc & NV50TIC_0_0_MAPG_MASK) >> NV50TIC_0_0_MAPG_SHIFT; + case PIPE_SWIZZLE_BLUE: + return (tc & NV50TIC_0_0_MAPB_MASK) >> NV50TIC_0_0_MAPB_SHIFT; + case PIPE_SWIZZLE_ALPHA: + return (tc & NV50TIC_0_0_MAPA_MASK) >> NV50TIC_0_0_MAPA_SHIFT; + case PIPE_SWIZZLE_ONE: + return 7; + case PIPE_SWIZZLE_ZERO: + default: + return 0; + } +} + +boolean +nv50_tex_construct(struct nv50_sampler_view *view) { - unsigned i; - uint32_t mode; const struct util_format_description *desc; + struct nv50_miptree *mt = nv50_miptree(view->pipe.texture); + uint32_t swz[4], *tic = view->tic; - for (i = 0; i < NV50_TEX_FORMAT_LIST_SIZE; i++) - if (nv50_tex_format_list[i].pf == mt->base.base.format) - break; - if (i == NV50_TEX_FORMAT_LIST_SIZE) - return 1; - - if (nv50->sampler[p][unit]->normalized) - mode = 0x50001000 | (1 << 31); - else { - mode = 0x50001000 | (7 << 14); - assert(mt->base.base.target == PIPE_TEXTURE_2D); - } + tic[0] = nv50_texture_formats[view->pipe.format]; - mode |= ((mt->base.bo->tile_mode & 0x0f) << 22) | - ((mt->base.bo->tile_mode & 0xf0) << 21); + swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r); + swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g); + swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b); + swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a); + view->tic[0] = (tic[0] & ~NV50TIC_0_0_SWIZZLE_MASK) | + (swz[0] << NV50TIC_0_0_MAPR_SHIFT) | + (swz[1] << NV50TIC_0_0_MAPG_SHIFT) | + (swz[2] << NV50TIC_0_0_MAPB_SHIFT) | + (swz[3] << NV50TIC_0_0_MAPA_SHIFT); - desc = util_format_description(mt->base.base.format); - assert(desc); + tic[2] = 0x50001000; + tic[2] |= ((mt->base.bo->tile_mode & 0x0f) << 22) | + ((mt->base.bo->tile_mode & 0xf0) << 21); + desc = util_format_description(mt->base.base.format); if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) - mode |= 0x0400; + tic[2] |= NV50TIC_0_2_COLORSPACE_SRGB; switch (mt->base.base.target) { case PIPE_TEXTURE_1D: + tic[2] |= NV50TIC_0_2_TARGET_1D; break; case PIPE_TEXTURE_2D: - mode |= (1 << 14); + tic[2] |= NV50TIC_0_2_TARGET_2D; break; case PIPE_TEXTURE_3D: - mode |= (2 << 14); + tic[2] |= NV50TIC_0_2_TARGET_3D; break; case PIPE_TEXTURE_CUBE: - mode |= (3 << 14); + tic[2] |= NV50TIC_0_2_TARGET_CUBE; break; default: - assert(!"unsupported texture target"); - break; + NOUVEAU_ERR("invalid texture target: %d\n", + mt->base.base.target); + return FALSE; } - so_data (so, nv50_tex_format_list[i].hw); - so_reloc(so, mt->base.bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW | - NOUVEAU_BO_RD, 0, 0); - so_reloc(so, mt->base.bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH | - NOUVEAU_BO_RD | NOUVEAU_BO_OR, mode, mode); - so_data (so, 0x00300000); - so_data (so, mt->base.base.width0 | (1 << 31)); - so_data (so, (mt->base.base.last_level << 28) | - (mt->base.base.depth0 << 16) | mt->base.base.height0); - so_data (so, 0x03000000); - so_data (so, mt->base.base.last_level << 4); - - return 0; -} + tic[3] = 0x00300000; + + tic[4] = (1 << 31) | mt->base.base.width0; + tic[5] = (mt->base.base.last_level << 28) | + (mt->base.base.depth0 << 16) | mt->base.base.height0; + + tic[6] = 0x03000000; -#ifndef NV50TCL_BIND_TIC -#define NV50TCL_BIND_TIC(n) (0x1448 + 8 * n) -#endif + tic[7] = (view->pipe.last_level << 4) | view->pipe.first_level; + + return TRUE; +} -static boolean +static int nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so, unsigned p) { - static const unsigned p_remap[PIPE_SHADER_TYPES] = { 0, 2, 1 }; - struct nouveau_grobj *eng2d = nv50->screen->eng2d; struct nouveau_grobj *tesla = nv50->screen->tesla; - unsigned unit, j, p_hw = p_remap[p]; + unsigned unit, j; + + const unsigned rll = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW; + const unsigned rlh = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH + | NOUVEAU_BO_OR; nv50_so_init_sifc(nv50, so, nv50->screen->tic, NOUVEAU_BO_VRAM, - p * (32 * 8 * 4), nv50->miptree_nr[p] * 8 * 4); + p * (32 * 8 * 4), nv50->sampler_view_nr[p] * 8 * 4); - for (unit = 0; unit < nv50->miptree_nr[p]; ++unit) { - struct nv50_miptree *mt = nv50->miptree[p][unit]; + for (unit = 0; unit < nv50->sampler_view_nr[p]; ++unit) { + struct nv50_sampler_view *view = + nv50_sampler_view(nv50->sampler_views[p][unit]); so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), 8); - if (mt) { - if (nv50_tex_construct(nv50, so, mt, unit, p)) - return FALSE; + if (view) { + uint32_t tic2 = view->tic[2]; + struct nv50_miptree *mt = + nv50_miptree(view->pipe.texture); + + if (nv50->sampler[p][unit]->normalized) + tic2 |= NV50TIC_0_2_NORMALIZED_COORDS; + + so_data (so, view->tic[0]); + so_reloc (so, mt->base.bo, 0, rll, 0, 0); + so_reloc (so, mt->base.bo, 0, rlh, tic2, tic2); + so_datap (so, &view->tic[3], 5); + /* Set TEX insn $t src binding $unit in program type p * to TIC, TSC entry (32 * p + unit), mark valid (1). */ - so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1); + so_method(so, tesla, NV50TCL_BIND_TIC(p), 1); so_data (so, ((32 * p + unit) << 9) | (unit << 1) | 1); } else { for (j = 0; j < 8; ++j) so_data(so, 0); - so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1); + so_method(so, tesla, NV50TCL_BIND_TIC(p), 1); so_data (so, (unit << 1) | 0); } } - for (; unit < nv50->state.miptree_nr[p]; unit++) { + for (; unit < nv50->state.sampler_view_nr[p]; unit++) { /* Make other bindings invalid. */ - so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1); + so_method(so, tesla, NV50TCL_BIND_TIC(p), 1); so_data (so, (unit << 1) | 0); } - nv50->state.miptree_nr[p] = nv50->miptree_nr[p]; + nv50->state.sampler_view_nr[p] = nv50->sampler_view_nr[p]; return TRUE; } @@ -203,23 +220,25 @@ nv50_tex_relocs(struct nv50_context *nv50) int p, unit; p = PIPE_SHADER_FRAGMENT; - for (unit = 0; unit < nv50->miptree_nr[p]; unit++) { - if (!nv50->miptree[p][unit]) + for (unit = 0; unit < nv50->sampler_view_nr[p]; unit++) { + struct pipe_sampler_view *view = nv50->sampler_views[p][unit]; + if (!view) continue; nouveau_reloc_emit(chan, nv50->screen->tic, ((p * 32) + unit) * 32, NULL, - nv50->miptree[p][unit]->base.bo, 0, 0, + nv50_miptree(view->texture)->base.bo, 0, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0); } p = PIPE_SHADER_VERTEX; - for (unit = 0; unit < nv50->miptree_nr[p]; unit++) { - if (!nv50->miptree[p][unit]) + for (unit = 0; unit < nv50->sampler_view_nr[p]; unit++) { + struct pipe_sampler_view *view = nv50->sampler_views[p][unit]; + if (!view) continue; nouveau_reloc_emit(chan, nv50->screen->tic, ((p * 32) + unit) * 32, NULL, - nv50->miptree[p][unit]->base.bo, 0, 0, + nv50_miptree(view->texture)->base.bo, 0, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0); } @@ -230,21 +249,23 @@ nv50_tex_validate(struct nv50_context *nv50) { struct nouveau_stateobj *so; struct nouveau_grobj *tesla = nv50->screen->tesla; - unsigned p, start, push, nrlc; - - for (nrlc = 0, start = 0, push = 0, p = 0; p < PIPE_SHADER_TYPES; ++p) { - start += MAX2(nv50->miptree_nr[p], nv50->state.miptree_nr[p]); - push += MAX2(nv50->miptree_nr[p], nv50->state.miptree_nr[p]); - nrlc += nv50->miptree_nr[p]; + unsigned p, m = 0, d = 0, r = 0; + + for (p = 0; p < 3; ++p) { + unsigned nr = MAX2(nv50->sampler_view_nr[p], + nv50->state.sampler_view_nr[p]); + m += nr; + d += nr; + r += nv50->sampler_view_nr[p]; } - start = start * 2 + 4 * PIPE_SHADER_TYPES + 2; - push = push * 9 + 19 * PIPE_SHADER_TYPES + 2; - nrlc = nrlc * 2 + 2 * PIPE_SHADER_TYPES; + m = m * 2 + 3 * 4 + 1; + d = d * 9 + 3 * 19 + 1; + r = r * 2 + 3 * 2; - so = so_new(start, push, nrlc); + so = so_new(m, d, r); - if (nv50_validate_textures(nv50, so, PIPE_SHADER_VERTEX) == FALSE || - nv50_validate_textures(nv50, so, PIPE_SHADER_FRAGMENT) == FALSE) { + if (nv50_validate_textures(nv50, so, 0) == FALSE || + nv50_validate_textures(nv50, so, 2) == FALSE) { so_ref(NULL, &so); NOUVEAU_ERR("failed tex validate\n"); diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h index b870302019a..3475d3e4326 100644 --- a/src/gallium/drivers/nv50/nv50_texture.h +++ b/src/gallium/drivers/nv50/nv50_texture.h @@ -7,7 +7,9 @@ */ /* Texture image control block */ +#define NV50TIC_0_0_SWIZZLE_MASK 0x3ffc0000 #define NV50TIC_0_0_MAPA_MASK 0x38000000 +#define NV50TIC_0_0_MAPA_SHIFT 27 #define NV50TIC_0_0_MAPA_ZERO 0x00000000 #define NV50TIC_0_0_MAPA_C0 0x10000000 #define NV50TIC_0_0_MAPA_C1 0x18000000 @@ -15,6 +17,7 @@ #define NV50TIC_0_0_MAPA_C3 0x28000000 #define NV50TIC_0_0_MAPA_ONE 0x38000000 #define NV50TIC_0_0_MAPB_MASK 0x07000000 +#define NV50TIC_0_0_MAPB_SHIFT 24 #define NV50TIC_0_0_MAPB_ZERO 0x00000000 #define NV50TIC_0_0_MAPB_C0 0x02000000 #define NV50TIC_0_0_MAPB_C1 0x03000000 @@ -22,6 +25,7 @@ #define NV50TIC_0_0_MAPB_C3 0x05000000 #define NV50TIC_0_0_MAPB_ONE 0x07000000 #define NV50TIC_0_0_MAPG_MASK 0x00e00000 +#define NV50TIC_0_0_MAPG_SHIFT 21 #define NV50TIC_0_0_MAPG_ZERO 0x00000000 #define NV50TIC_0_0_MAPG_C0 0x00400000 #define NV50TIC_0_0_MAPG_C1 0x00600000 @@ -29,6 +33,7 @@ #define NV50TIC_0_0_MAPG_C3 0x00a00000 #define NV50TIC_0_0_MAPG_ONE 0x00e00000 #define NV50TIC_0_0_MAPR_MASK 0x001c0000 +#define NV50TIC_0_0_MAPR_SHIFT 18 #define NV50TIC_0_0_MAPR_ZERO 0x00000000 #define NV50TIC_0_0_MAPR_C0 0x00080000 #define NV50TIC_0_0_MAPR_C1 0x000c0000 @@ -89,22 +94,39 @@ #define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff #define NV50TIC_0_1_OFFSET_LOW_SHIFT 0 -#define NV50TIC_0_2_UNKNOWN_MASK 0xffffffff +#define NV50TIC_0_2_COLORSPACE_SRGB 0x00000400 +#define NV50TIC_0_2_TARGET_1D 0x00000000 +#define NV50TIC_0_2_TARGET_2D 0x00004000 +#define NV50TIC_0_2_TARGET_3D 0x00008000 +#define NV50TIC_0_2_TARGET_CUBE 0x0000c000 +#define NV50TIC_0_2_TARGET_1D_ARRAY 0x00010000 +#define NV50TIC_0_2_TARGET_2D_ARRAY 0x00014000 +#define NV50TIC_0_2_TARGET_BUFFER 0x00018000 +#define NV50TIC_0_2_TARGET_RECT 0x0001c000 +/* #define NV50TIC_0_0_TILE_MODE_LINEAR 0x00040000 */ +#define NV50TIC_0_2_TILE_MODE_Y_MASK 0x01c00000 +#define NV50TIC_0_2_TILE_MODE_Y_SHIFT 22 +#define NV50TIC_0_2_TILE_MODE_Z_MASK 0x0e000000 +#define NV50TIC_0_2_TILE_MODE_Z_SHIFT 25 +#define NV50TIC_0_2_NORMALIZED_COORDS 0x80000000 #define NV50TIC_0_3_UNKNOWN_MASK 0xffffffff #define NV50TIC_0_4_WIDTH_MASK 0x0000ffff #define NV50TIC_0_4_WIDTH_SHIFT 0 -#define NV50TIC_0_5_DEPTH_MASK 0xffff0000 +#define NV50TIC_0_5_LAST_LEVEL_MASK 0xf0000000 +#define NV50TIC_0_5_LAST_LEVEL_SHIFT 28 +#define NV50TIC_0_5_DEPTH_MASK 0x0fff0000 #define NV50TIC_0_5_DEPTH_SHIFT 16 #define NV50TIC_0_5_HEIGHT_MASK 0x0000ffff #define NV50TIC_0_5_HEIGHT_SHIFT 0 - #define NV50TIC_0_6_UNKNOWN_MASK 0xffffffff -#define NV50TIC_0_7_OFFSET_HIGH_MASK 0xffffffff -#define NV50TIC_0_7_OFFSET_HIGH_SHIFT 0 +#define NV50TIC_0_7_BASE_LEVEL_MASK 0x0000000f +#define NV50TIC_0_7_BASE_LEVEL_SHIFT 0 +#define NV50TIC_0_7_MAX_LEVEL_MASK 0x000000f0 +#define NV50TIC_0_7_MAX_LEVEL_SHIFT 4 /* Texture sampler control block */ #define NV50TSC_1_0_WRAPS_MASK 0x00000007 diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h index 5eed8a560e5..001b19eedf0 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@ -159,6 +159,7 @@ struct nvfx_context { unsigned idxbuf_format; struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct nvfx_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; unsigned nr_samplers; unsigned nr_textures; unsigned dirty_samplers; diff --git a/src/gallium/drivers/nvfx/nvfx_state.c b/src/gallium/drivers/nvfx/nvfx_state.c index 88a9d01c509..ecaa0dcb16a 100644 --- a/src/gallium/drivers/nvfx/nvfx_state.c +++ b/src/gallium/drivers/nvfx/nvfx_state.c @@ -137,21 +137,22 @@ nvfx_sampler_state_delete(struct pipe_context *pipe, void *hwcso) } static void -nvfx_set_sampler_texture(struct pipe_context *pipe, unsigned nr, - struct pipe_texture **miptree) +nvfx_set_fragment_sampler_views(struct pipe_context *pipe, + unsigned nr, + struct pipe_sampler_view **views) { struct nvfx_context *nvfx = nvfx_context(pipe); unsigned unit; for (unit = 0; unit < nr; unit++) { - pipe_texture_reference((struct pipe_texture **) - &nvfx->tex_miptree[unit], miptree[unit]); + pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit], + views[unit]); nvfx->dirty_samplers |= (1 << unit); } for (unit = nr; unit < nvfx->nr_textures; unit++) { - pipe_texture_reference((struct pipe_texture **) - &nvfx->tex_miptree[unit], NULL); + pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit], + NULL); nvfx->dirty_samplers |= (1 << unit); } @@ -159,6 +160,34 @@ nvfx_set_sampler_texture(struct pipe_context *pipe, unsigned nr, nvfx->dirty |= NVFX_NEW_SAMPLER; } + +static struct pipe_sampler_view * +nvfx_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; +} + + +static void +nvfx_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + pipe_texture_reference(&view->texture, NULL); + FREE(view); +} + static void * nvfx_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) @@ -581,7 +610,9 @@ nvfx_init_state_functions(struct nvfx_context *nvfx) nvfx->pipe.create_sampler_state = nvfx_sampler_state_create; nvfx->pipe.bind_fragment_sampler_states = nvfx_sampler_state_bind; nvfx->pipe.delete_sampler_state = nvfx_sampler_state_delete; - nvfx->pipe.set_fragment_sampler_textures = nvfx_set_sampler_texture; + nvfx->pipe.set_fragment_sampler_views = nvfx_set_fragment_sampler_views; + nvfx->pipe.create_sampler_view = nvfx_create_sampler_view; + nvfx->pipe.sampler_view_destroy = nvfx_sampler_view_destroy; nvfx->pipe.create_rasterizer_state = nvfx_rasterizer_state_create; nvfx->pipe.bind_rasterizer_state = nvfx_rasterizer_state_bind; diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index b7ad6b20206..f99f9dffaa5 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -113,9 +113,9 @@ static void r300_hw_copy(struct pipe_context* pipe, util_blitter_save_fragment_sampler_states( r300->blitter, state->sampler_count, (void**)state->sampler_states); - util_blitter_save_fragment_sampler_textures( + util_blitter_save_fragment_sampler_views( r300->blitter, state->texture_count, - (struct pipe_texture**)state->textures); + state->fragment_sampler_views); /* Do a copy */ util_blitter_copy(r300->blitter, diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index db2f74e0745..0c8fb6860eb 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -139,7 +139,7 @@ struct r300_texture_fb_state { struct r300_textures_state { /* Textures. */ - struct r300_texture *textures[8]; + struct pipe_sampler_view *fragment_sampler_views[8]; int texture_count; /* Sampler states. */ struct r300_sampler_state *sampler_states[8]; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index d8c64dd9001..3ad0e561bc1 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -165,7 +165,7 @@ static const float * get_shader_constant( /* Factor for converting rectangle coords to * normalized coords. Should only show up on non-r500. */ case RC_STATE_R300_TEXRECT_FACTOR: - tex = &texstate->textures[constant->u.State[1]]->tex; + tex = texstate->fragment_sampler_views[constant->u.State[1]]->texture; vec[0] = 1.0 / tex->width0; vec[1] = 1.0 / tex->height0; break; @@ -749,8 +749,9 @@ void r300_emit_textures_state(struct r300_context *r300, OUT_CS_REG(R300_TX_FORMAT2_0 + (i * 4), texstate->format[2]); OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (i * 4), 1); - OUT_CS_TEX_RELOC(allstate->textures[i], texstate->tile_config, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); + OUT_CS_TEX_RELOC((struct r300_texture *)allstate->fragment_sampler_views[i]->texture, + texstate->tile_config, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); } } END_CS; @@ -1043,7 +1044,7 @@ validate: } /* ...textures... */ for (i = 0; i < texstate->count; i++) { - tex = texstate->textures[i]; + tex = (struct r300_texture*)texstate->fragment_sampler_views[i]->texture; if (!tex || !texstate->sampler_states[i]) continue; if (!r300_add_texture(r300->rws, tex, diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 712e9280e3c..d7d654dc315 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -933,9 +933,9 @@ static void r300_delete_sampler_state(struct pipe_context* pipe, void* state) FREE(state); } -static void r300_set_sampler_textures(struct pipe_context* pipe, - unsigned count, - struct pipe_texture** texture) +static void r300_set_fragment_sampler_views(struct pipe_context* pipe, + unsigned count, + struct pipe_sampler_view** views) { struct r300_context* r300 = r300_context(pipe); struct r300_textures_state* state = @@ -950,13 +950,17 @@ static void r300_set_sampler_textures(struct pipe_context* pipe, } for (i = 0; i < count; i++) { - if (state->textures[i] != (struct r300_texture*)texture[i]) { - pipe_texture_reference((struct pipe_texture**)&state->textures[i], - texture[i]); + if (state->fragment_sampler_views[i] != views[i]) { + struct r300_texture *texture; + + pipe_sampler_view_reference(&state->fragment_sampler_views[i], + views[i]); dirty_tex = TRUE; + texture = (struct r300_texture *)views[i]->texture; + /* R300-specific - set the texrect factor in the fragment shader */ - if (!is_r500 && state->textures[i]->is_npot) { + if (!is_r500 && texture->is_npot) { /* XXX It would be nice to re-emit just 1 constant, * XXX not all of them */ r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; @@ -965,9 +969,9 @@ static void r300_set_sampler_textures(struct pipe_context* pipe, } for (i = count; i < 8; i++) { - if (state->textures[i]) { - pipe_texture_reference((struct pipe_texture**)&state->textures[i], - NULL); + if (state->fragment_sampler_views[i]) { + pipe_sampler_view_reference(&state->fragment_sampler_views[i], + NULL); } } @@ -980,6 +984,33 @@ static void r300_set_sampler_textures(struct pipe_context* pipe, } } +static struct pipe_sampler_view * +r300_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; +} + + +static void +r300_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + pipe_texture_reference(&view->texture, NULL); + FREE(view); +} + static void r300_set_scissor_state(struct pipe_context* pipe, const struct pipe_scissor_state* state) { @@ -1473,7 +1504,9 @@ void r300_init_state_functions(struct r300_context* r300) r300->context.bind_vertex_sampler_states = r300_lacks_vertex_textures; r300->context.delete_sampler_state = r300_delete_sampler_state; - r300->context.set_fragment_sampler_textures = r300_set_sampler_textures; + r300->context.set_fragment_sampler_views = r300_set_fragment_sampler_views; + r300->context.create_sampler_view = r300_create_sampler_view; + r300->context.sampler_view_destroy = r300_sampler_view_destroy; r300->context.set_scissor_state = r300_set_scissor_state; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 6b9f61acd7b..7947ec6641d 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -340,10 +340,10 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) size = 2; for (i = 0; i < count; i++) { - if (state->textures[i] && state->sampler_states[i]) { + if (state->fragment_sampler_views[i] && state->sampler_states[i]) { state->tx_enable |= 1 << i; - tex = state->textures[i]; + tex = (struct r300_texture *)state->fragment_sampler_views[i]->texture; sampler = state->sampler_states[i]; texstate = &state->regs[i]; diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index de92a0cd2c7..937a573092f 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -104,12 +104,12 @@ softpipe_destroy( struct pipe_context *pipe ) for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { sp_destroy_tex_tile_cache(softpipe->tex_cache[i]); - pipe_texture_reference(&softpipe->texture[i], NULL); + pipe_sampler_view_reference(&softpipe->sampler_views[i], NULL); } for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { sp_destroy_tex_tile_cache(softpipe->vertex_tex_cache[i]); - pipe_texture_reference(&softpipe->vertex_textures[i], NULL); + pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], NULL); } for (i = 0; i < PIPE_SHADER_TYPES; i++) { @@ -257,8 +257,10 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; - softpipe->pipe.set_fragment_sampler_textures = softpipe_set_sampler_textures; - softpipe->pipe.set_vertex_sampler_textures = softpipe_set_vertex_sampler_textures; + softpipe->pipe.set_fragment_sampler_views = softpipe_set_sampler_views; + softpipe->pipe.set_vertex_sampler_views = softpipe_set_vertex_sampler_views; + softpipe->pipe.create_sampler_view = softpipe_create_sampler_view; + softpipe->pipe.sampler_view_destroy = softpipe_sampler_view_destroy; softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 9a8158e6a22..75e03c8ae6b 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -70,15 +70,15 @@ struct softpipe_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 *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_sampler_views; unsigned num_vertex_samplers; - unsigned num_vertex_textures; + unsigned num_vertex_sampler_views; unsigned num_vertex_buffers; unsigned dirty; /**< Mask of SP_NEW_x flags */ diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 3d76af4d8cb..508fe8f764d 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -50,10 +50,10 @@ softpipe_flush( struct pipe_context *pipe, draw_flush(softpipe->draw); if (flags & PIPE_FLUSH_TEXTURE_CACHE) { - for (i = 0; i < softpipe->num_textures; i++) { + for (i = 0; i < softpipe->num_sampler_views; i++) { sp_flush_tex_tile_cache(softpipe->tex_cache[i]); } - for (i = 0; i < softpipe->num_vertex_textures; i++) { + for (i = 0; i < softpipe->num_vertex_sampler_views; i++) { sp_flush_tex_tile_cache(softpipe->vertex_tex_cache[i]); } } diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 6b01c0f4d72..ade96b0fd4c 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -177,14 +177,23 @@ void softpipe_set_polygon_stipple( struct pipe_context *, void softpipe_set_scissor_state( struct pipe_context *, const struct pipe_scissor_state * ); -void softpipe_set_sampler_textures( struct pipe_context *, - unsigned num, - struct pipe_texture ** ); +void softpipe_set_sampler_views( struct pipe_context *, + unsigned num, + struct pipe_sampler_view ** ); void -softpipe_set_vertex_sampler_textures(struct pipe_context *, - unsigned num_textures, - struct pipe_texture **); +softpipe_set_vertex_sampler_views(struct pipe_context *, + unsigned num, + struct pipe_sampler_view **); + +struct pipe_sampler_view * +softpipe_create_sampler_view(struct pipe_context *pipe, + struct pipe_texture *texture, + const struct pipe_sampler_view *templ); + +void +softpipe_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view); void softpipe_set_viewport_state( struct pipe_context *, const struct pipe_viewport_state * ); diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index ceb4e338f1a..d501952bba9 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -121,9 +121,38 @@ softpipe_bind_vertex_sampler_states(struct pipe_context *pipe, } +struct pipe_sampler_view * +softpipe_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 -softpipe_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) +softpipe_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + pipe_texture_reference(&view->texture, NULL); + FREE(view); +} + + +void +softpipe_set_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct softpipe_context *softpipe = softpipe_context(pipe); uint i; @@ -131,51 +160,51 @@ softpipe_set_sampler_textures(struct pipe_context *pipe, assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ - if (num == softpipe->num_textures && - !memcmp(softpipe->texture, texture, num * sizeof(struct pipe_texture *))) + if (num == softpipe->num_sampler_views && + !memcmp(softpipe->sampler_views, views, num * sizeof(struct pipe_sampler_view *))) return; draw_flush(softpipe->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(&softpipe->texture[i], tex); - sp_tex_tile_cache_set_texture(softpipe->tex_cache[i], tex); + pipe_sampler_view_reference(&softpipe->sampler_views[i], view); + sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[i], view); } - softpipe->num_textures = num; + softpipe->num_sampler_views = num; softpipe->dirty |= SP_NEW_TEXTURE; } void -softpipe_set_vertex_sampler_textures(struct pipe_context *pipe, - unsigned num_textures, - struct pipe_texture **textures) +softpipe_set_vertex_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct softpipe_context *softpipe = softpipe_context(pipe); uint i; - assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS); + assert(num <= PIPE_MAX_VERTEX_SAMPLERS); /* Check for no-op */ - if (num_textures == softpipe->num_vertex_textures && - !memcmp(softpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) { + if (num == softpipe->num_vertex_sampler_views && + !memcmp(softpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { return; } draw_flush(softpipe->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(&softpipe->vertex_textures[i], tex); - sp_tex_tile_cache_set_texture(softpipe->vertex_tex_cache[i], tex); + pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], view); + sp_tex_tile_cache_set_sampler_view(softpipe->vertex_tex_cache[i], view); } - softpipe->num_vertex_textures = num_textures; + softpipe->num_vertex_sampler_views = num; softpipe->dirty |= SP_NEW_TEXTURE; } @@ -245,29 +274,41 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) */ for (i = 0; i <= softpipe->vs->max_sampler; i++) { if (softpipe->vertex_samplers[i]) { + struct pipe_texture *texture = NULL; + + if (softpipe->vertex_sampler_views[i]) { + texture = softpipe->vertex_sampler_views[i]->texture; + } + softpipe->tgsi.vert_samplers_list[i] = get_sampler_varient( i, - sp_sampler(softpipe->vertex_samplers[i]), - softpipe->vertex_textures[i], + sp_sampler(softpipe->vertex_samplers[i]), + texture, TGSI_PROCESSOR_VERTEX ); sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i], - softpipe->vertex_tex_cache[i], - softpipe->vertex_textures[i] ); + softpipe->vertex_tex_cache[i], + texture ); } } for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) { if (softpipe->sampler[i]) { + struct pipe_texture *texture = NULL; + + if (softpipe->sampler_views[i]) { + texture = softpipe->sampler_views[i]->texture; + } + softpipe->tgsi.frag_samplers_list[i] = get_sampler_varient( i, sp_sampler(softpipe->sampler[i]), - softpipe->texture[i], + texture, TGSI_PROCESSOR_FRAGMENT ); sp_sampler_varient_bind_texture( softpipe->tgsi.frag_samplers_list[i], softpipe->tex_cache[i], - softpipe->texture[i] ); + texture ); } } } diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c index e3a5e37ce44..6594514c38f 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -116,12 +116,13 @@ sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc) } /** - * Specify the texture to cache. + * Specify the sampler view to cache. */ void -sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, - struct pipe_texture *texture) +sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc, + struct pipe_sampler_view *view) { + struct pipe_texture *texture = view ? view->texture : NULL; uint i; assert(!tc->transfer); @@ -139,6 +140,14 @@ sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, tc->tex_trans = NULL; } + if (view) { + tc->swizzle_r = view->swizzle_r; + tc->swizzle_g = view->swizzle_g; + tc->swizzle_b = view->swizzle_b; + tc->swizzle_a = view->swizzle_a; + tc->format = view->format; + } + /* mark as entries as invalid/empty */ /* XXX we should try to avoid this when the teximage hasn't changed */ for (i = 0; i < NUM_ENTRIES; i++) { @@ -251,12 +260,18 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, } /* get tile from the transfer (view into texture) */ - pipe_get_tile_rgba(tc->pipe, - tc->tex_trans, - addr.bits.x * TILE_SIZE, - addr.bits.y * TILE_SIZE, - TILE_SIZE, TILE_SIZE, - (float *) tile->data.color); + pipe_get_tile_swizzle(tc->pipe, + tc->tex_trans, + addr.bits.x * TILE_SIZE, + addr.bits.y * TILE_SIZE, + TILE_SIZE, + TILE_SIZE, + tc->swizzle_r, + tc->swizzle_g, + tc->swizzle_b, + tc->swizzle_a, + tc->format, + (float *) tile->data.color); tile->addr = addr; } diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h index b1163972587..12ae7ba12d6 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h @@ -83,6 +83,12 @@ struct softpipe_tex_tile_cache void *tex_trans_map; int tex_face, tex_level, tex_z; + unsigned swizzle_r; + unsigned swizzle_g; + unsigned swizzle_b; + unsigned swizzle_a; + unsigned format; + struct softpipe_tex_cached_tile *last_tile; /**< most recently retrieved tile */ }; @@ -101,8 +107,8 @@ extern void sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc); extern void -sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, - struct pipe_texture *texture); +sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc, + struct pipe_sampler_view *view); void sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc); diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index 791d30edc0e..1f66437dfe1 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -185,7 +185,7 @@ struct svga_state const struct svga_sampler_state *sampler[PIPE_MAX_SAMPLERS]; const struct svga_velems_state *velems; - struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; /* or texture ID's? */ + struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; /* or texture ID's? */ struct svga_fragment_shader *fs; struct svga_vertex_shader *vs; @@ -208,7 +208,7 @@ struct svga_state struct pipe_viewport_state viewport; unsigned num_samplers; - unsigned num_textures; + unsigned num_sampler_views; unsigned num_vertex_buffers; unsigned reduced_prim; diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index 1a8ef296cac..82d525ca33f 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -176,9 +176,36 @@ static void svga_delete_sampler_state(struct pipe_context *pipe, } -static void svga_set_sampler_textures(struct pipe_context *pipe, - unsigned num, - struct pipe_texture **texture) +static struct pipe_sampler_view * +svga_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; +} + + +static void +svga_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + pipe_texture_reference(&view->texture, NULL); + FREE(view); +} + +static void svga_set_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct svga_context *svga = svga_context(pipe); unsigned flag_1d = 0; @@ -188,31 +215,31 @@ static void svga_set_sampler_textures(struct pipe_context *pipe, assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ - if (num == svga->curr.num_textures && - !memcmp(svga->curr.texture, texture, num * sizeof(struct pipe_texture *))) { + if (num == svga->curr.num_sampler_views && + !memcmp(svga->curr.sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { if (0) debug_printf("texture noop\n"); return; } for (i = 0; i < num; i++) { - pipe_texture_reference(&svga->curr.texture[i], - texture[i]); + pipe_sampler_view_reference(&svga->curr.sampler_views[i], + views[i]); - if (!texture[i]) + if (!views[i]) continue; - if (texture[i]->format == PIPE_FORMAT_B8G8R8A8_SRGB) + if (views[i]->texture->format == PIPE_FORMAT_B8G8R8A8_SRGB) flag_srgb |= 1 << i; - if (texture[i]->target == PIPE_TEXTURE_1D) + if (views[i]->texture->target == PIPE_TEXTURE_1D) flag_1d |= 1 << i; } - for (i = num; i < svga->curr.num_textures; i++) - pipe_texture_reference(&svga->curr.texture[i], - NULL); + for (i = num; i < svga->curr.num_sampler_views; i++) + pipe_sampler_view_reference(&svga->curr.sampler_views[i], + NULL); - svga->curr.num_textures = num; + svga->curr.num_sampler_views = num; svga->dirty |= SVGA_NEW_TEXTURE_BINDING; if (flag_srgb != svga->curr.tex_flags.flag_srgb || @@ -231,7 +258,9 @@ void svga_init_sampler_functions( struct svga_context *svga ) svga->pipe.create_sampler_state = svga_create_sampler_state; svga->pipe.bind_fragment_sampler_states = svga_bind_sampler_states; svga->pipe.delete_sampler_state = svga_delete_sampler_state; - svga->pipe.set_fragment_sampler_textures = svga_set_sampler_textures; + svga->pipe.set_fragment_sampler_views = svga_set_sampler_views; + svga->pipe.create_sampler_view = svga_create_sampler_view; + svga->pipe.sampler_view_destroy = svga_sampler_view_destroy; } diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c index bb92f818eae..493f78a9908 100644 --- a/src/gallium/drivers/svga/svga_state_constants.c +++ b/src/gallium/drivers/svga/svga_state_constants.c @@ -137,7 +137,7 @@ static int emit_fs_consts( struct svga_context *svga, for (i = 0; i < key->num_textures; i++) { if (key->tex[i].unnormalized) { - struct pipe_texture *tex = svga->curr.texture[i]; + struct pipe_texture *tex = svga->curr.sampler_views[i]->texture; float data[4]; data[0] = 1.0 / (float)tex->width0; diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c index 2973444d0ab..1310fd9825f 100644 --- a/src/gallium/drivers/svga/svga_state_fs.c +++ b/src/gallium/drivers/svga/svga_state_fs.c @@ -158,10 +158,11 @@ static int make_fs_key( const struct svga_context *svga, * * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER */ - for (i = 0; i < svga->curr.num_textures; i++) { - if (svga->curr.texture[i]) { + for (i = 0; i < svga->curr.num_sampler_views; i++) { + if (svga->curr.sampler_views[i]) { assert(svga->curr.sampler[i]); - key->tex[i].texture_target = svga->curr.texture[i]->target; + assert(svga->curr.sampler_views[i]->texture); + key->tex[i].texture_target = svga->curr.sampler_views[i]->texture->target; if (!svga->curr.sampler[i]->normalized_coords) { key->tex[i].width_height_idx = idx++; key->tex[i].unnormalized = TRUE; @@ -169,7 +170,7 @@ static int make_fs_key( const struct svga_context *svga, } } } - key->num_textures = svga->curr.num_textures; + key->num_textures = svga->curr.num_sampler_views; idx = 0; for (i = 0; i < svga->curr.num_samplers; ++i) { diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c index 17b47859781..c08ec7c2e8c 100644 --- a/src/gallium/drivers/svga/svga_state_tss.c +++ b/src/gallium/drivers/svga/svga_state_tss.c @@ -37,14 +37,14 @@ void svga_cleanup_tss_binding(struct svga_context *svga) { int i; - unsigned count = MAX2( svga->curr.num_textures, + unsigned count = MAX2( svga->curr.num_sampler_views, svga->state.hw_draw.num_views ); for (i = 0; i < count; i++) { struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; svga_sampler_view_reference(&view->v, NULL); - pipe_texture_reference( &svga->curr.texture[i], NULL ); + pipe_sampler_view_reference( &svga->curr.sampler_views[i], NULL ); pipe_texture_reference( &view->texture, NULL ); view->dirty = 1; @@ -57,7 +57,7 @@ update_tss_binding(struct svga_context *svga, unsigned dirty ) { unsigned i; - unsigned count = MAX2( svga->curr.num_textures, + unsigned count = MAX2( svga->curr.num_sampler_views, svga->state.hw_draw.num_views ); unsigned min_lod; unsigned max_lod; @@ -77,30 +77,32 @@ update_tss_binding(struct svga_context *svga, for (i = 0; i < count; i++) { const struct svga_sampler_state *s = svga->curr.sampler[i]; struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; + struct pipe_texture *texture = NULL; /* get min max lod */ - if (svga->curr.texture[i]) { + if (svga->curr.sampler_views[i]) { min_lod = MAX2(s->view_min_lod, 0); - max_lod = MIN2(s->view_max_lod, svga->curr.texture[i]->last_level); + max_lod = MIN2(s->view_max_lod, svga->curr.sampler_views[i]->texture->last_level); + texture = svga->curr.sampler_views[i]->texture; } else { min_lod = 0; max_lod = 0; } - if (view->texture != svga->curr.texture[i] || + if (view->texture != texture || view->min_lod != min_lod || view->max_lod != max_lod) { svga_sampler_view_reference(&view->v, NULL); - pipe_texture_reference( &view->texture, svga->curr.texture[i] ); + pipe_texture_reference( &view->texture, texture ); view->dirty = TRUE; view->min_lod = min_lod; view->max_lod = max_lod; - if (svga->curr.texture[i]) + if (texture) view->v = svga_get_tex_sampler_view(&svga->pipe, - svga->curr.texture[i], + texture, min_lod, max_lod); } @@ -115,7 +117,7 @@ update_tss_binding(struct svga_context *svga, } } - svga->state.hw_draw.num_views = svga->curr.num_textures; + svga->state.hw_draw.num_views = svga->curr.num_sampler_views; if (queue.bind_count) { SVGA3dTextureState *ts; diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index b7e6bbac68e..5c24bd1f7df 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -25,6 +25,7 @@ * **************************************************************************/ +#include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_simple_list.h" #include "util/u_format.h" @@ -114,7 +115,7 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag) (void *) tr_ctx->draw_rule.fs, (void *) tr_ctx->curr.fs, (void *) tr_ctx->draw_rule.vs, (void *) tr_ctx->curr.vs, (void *) tr_ctx->draw_rule.surf, 0, - (void *) tr_ctx->draw_rule.tex, 0); + (void *) tr_ctx->draw_rule.sampler_view, 0); if (tr_ctx->draw_rule.fs && tr_ctx->draw_rule.fs == tr_ctx->curr.fs) block = TRUE; @@ -128,12 +129,12 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag) for (k = 0; k < tr_ctx->curr.nr_cbufs; k++) if (tr_ctx->draw_rule.surf == tr_ctx->curr.cbufs[k]) block = TRUE; - if (tr_ctx->draw_rule.tex) { - for (k = 0; k < tr_ctx->curr.num_texs; k++) - if (tr_ctx->draw_rule.tex == tr_ctx->curr.tex[k]) + if (tr_ctx->draw_rule.sampler_view) { + for (k = 0; k < tr_ctx->curr.num_sampler_views; k++) + if (tr_ctx->draw_rule.sampler_view == tr_ctx->curr.sampler_views[k]) block = TRUE; - for (k = 0; k < tr_ctx->curr.num_vert_texs; k++) { - if (tr_ctx->draw_rule.tex == tr_ctx->curr.vert_tex[k]) { + for (k = 0; k < tr_ctx->curr.num_vert_sampler_views; k++) { + if (tr_ctx->draw_rule.sampler_view == tr_ctx->curr.vert_sampler_views[k]) { block = TRUE; } } @@ -1015,63 +1016,119 @@ trace_context_set_viewport_state(struct pipe_context *_pipe, } +static struct pipe_sampler_view * +trace_create_sampler_view(struct pipe_context *_pipe, + struct pipe_texture *_texture, + const struct pipe_sampler_view *templ) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_texture *tr_tex = trace_texture(_texture); + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_texture *texture = tr_tex->texture; + struct trace_sampler_view *result = CALLOC_STRUCT(trace_sampler_view); + + trace_dump_call_begin("pipe_context", "create_sampler_view"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, texture); + trace_dump_arg(ptr, templ); + + result->sampler_view = pipe->create_sampler_view(pipe, texture, templ); + + result->base = *templ; + result->base.reference.count = 1; + result->base.texture = NULL; + pipe_texture_reference(&result->base.texture, _texture); + result->base.context = _pipe; + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + return &result->base; +} + + +static void +trace_sampler_view_destroy(struct pipe_context *_pipe, + struct pipe_sampler_view *_view) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_sampler_view *tr_view = trace_sampler_view(_view); + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_sampler_view *view = tr_view->sampler_view; + + trace_dump_call_begin("pipe_context", "sampler_view_destroy"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, view); + + pipe->sampler_view_destroy(pipe, view); + + trace_dump_call_end(); + + pipe_texture_reference(&_view->texture, NULL); + FREE(_view); +} + + static INLINE void -trace_context_set_fragment_sampler_textures(struct pipe_context *_pipe, - unsigned num_textures, - struct pipe_texture **textures) +trace_context_set_fragment_sampler_views(struct pipe_context *_pipe, + unsigned num, + struct pipe_sampler_view **views) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_texture *tr_tex; + struct trace_sampler_view *tr_view; struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS]; unsigned i; - tr_ctx->curr.num_texs = num_textures; - for(i = 0; i < num_textures; ++i) { - tr_tex = trace_texture(textures[i]); - tr_ctx->curr.tex[i] = tr_tex; - unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL; + tr_ctx->curr.num_sampler_views = num; + for(i = 0; i < num; ++i) { + tr_view = trace_sampler_view(views[i]); + tr_ctx->curr.sampler_views[i] = tr_view; + unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL; } - textures = unwrapped_textures; + views = unwrapped_views; - trace_dump_call_begin("pipe_context", "set_fragment_sampler_textures"); + trace_dump_call_begin("pipe_context", "set_fragment_sampler_views"); trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, num_textures); - trace_dump_arg_array(ptr, textures, num_textures); + trace_dump_arg(uint, num); + trace_dump_arg_array(ptr, views, num); - pipe->set_fragment_sampler_textures(pipe, num_textures, textures); + pipe->set_fragment_sampler_views(pipe, num, views); trace_dump_call_end(); } static INLINE void -trace_context_set_vertex_sampler_textures(struct pipe_context *_pipe, - unsigned num_textures, - struct pipe_texture **textures) +trace_context_set_vertex_sampler_views(struct pipe_context *_pipe, + unsigned num, + struct pipe_sampler_view **views) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_texture *tr_tex; + struct trace_sampler_view *tr_view; struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS]; + struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS]; unsigned i; - tr_ctx->curr.num_vert_texs = num_textures; - for(i = 0; i < num_textures; ++i) { - tr_tex = trace_texture(textures[i]); - tr_ctx->curr.vert_tex[i] = tr_tex; - unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL; + tr_ctx->curr.num_vert_sampler_views = num; + for(i = 0; i < num; ++i) { + tr_view = trace_sampler_view(views[i]); + tr_ctx->curr.vert_sampler_views[i] = tr_view; + unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL; } - textures = unwrapped_textures; + views = unwrapped_views; - trace_dump_call_begin("pipe_context", "set_vertex_sampler_textures"); + trace_dump_call_begin("pipe_context", "set_vertex_sampler_views"); trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, num_textures); - trace_dump_arg_array(ptr, textures, num_textures); + trace_dump_arg(uint, num); + trace_dump_arg_array(ptr, views, num); - pipe->set_vertex_sampler_textures(pipe, num_textures, textures); + pipe->set_vertex_sampler_views(pipe, num, views); trace_dump_call_end(); } @@ -1487,8 +1544,10 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple; tr_ctx->base.set_scissor_state = trace_context_set_scissor_state; tr_ctx->base.set_viewport_state = trace_context_set_viewport_state; - tr_ctx->base.set_fragment_sampler_textures = trace_context_set_fragment_sampler_textures; - tr_ctx->base.set_vertex_sampler_textures = trace_context_set_vertex_sampler_textures; + tr_ctx->base.set_fragment_sampler_views = trace_context_set_fragment_sampler_views; + tr_ctx->base.set_vertex_sampler_views = trace_context_set_vertex_sampler_views; + tr_ctx->base.create_sampler_view = trace_create_sampler_view; + tr_ctx->base.sampler_view_destroy = trace_sampler_view_destroy; tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers; if (pipe->surface_copy) tr_ctx->base.surface_copy = trace_context_surface_copy; diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 14284232485..feec9b6bbf3 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -53,11 +53,11 @@ struct trace_context struct trace_shader *fs; struct trace_shader *vs; - struct trace_texture *tex[PIPE_MAX_SAMPLERS]; - unsigned num_texs; + struct trace_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; + unsigned num_sampler_views; - struct trace_texture *vert_tex[PIPE_MAX_VERTEX_SAMPLERS]; - unsigned num_vert_texs; + struct trace_sampler_view *vert_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; + unsigned num_vert_sampler_views; unsigned nr_cbufs; struct trace_texture *cbufs[PIPE_MAX_COLOR_BUFS]; @@ -68,7 +68,7 @@ struct trace_context struct trace_shader *fs; struct trace_shader *vs; - struct trace_texture *tex; + struct trace_sampler_view *sampler_view; struct trace_texture *surf; int blocker; diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c index f4f17566fd3..53ab8c686d8 100644 --- a/src/gallium/drivers/trace/tr_rbug.c +++ b/src/gallium/drivers/trace/tr_rbug.c @@ -313,12 +313,12 @@ trace_rbug_context_info(struct trace_rbug *tr_rbug, struct rbug_header *header, for (i = 0; i < tr_ctx->curr.nr_cbufs; i++) cbufs[i] = VOID2U64(tr_ctx->curr.cbufs[i]); - for (i = 0; i < tr_ctx->curr.num_texs; i++) - texs[i] = VOID2U64(tr_ctx->curr.tex[i]); + for (i = 0; i < tr_ctx->curr.num_sampler_views; i++) + texs[i] = VOID2U64(tr_ctx->curr.sampler_views[i]); rbug_send_context_info_reply(tr_rbug->con, serial, VOID2U64(tr_ctx->curr.vs), VOID2U64(tr_ctx->curr.fs), - texs, tr_ctx->curr.num_texs, + texs, tr_ctx->curr.num_sampler_views, cbufs, tr_ctx->curr.nr_cbufs, VOID2U64(tr_ctx->curr.zsbuf), tr_ctx->draw_blocker, tr_ctx->draw_blocked, NULL); @@ -444,7 +444,7 @@ trace_rbug_context_draw_rule(struct trace_rbug *tr_rbug, struct rbug_header *hea pipe_mutex_lock(tr_ctx->draw_mutex); tr_ctx->draw_rule.vs = U642VOID(rule->vertex); tr_ctx->draw_rule.fs = U642VOID(rule->fragment); - tr_ctx->draw_rule.tex = U642VOID(rule->texture); + tr_ctx->draw_rule.sampler_view = U642VOID(rule->texture); tr_ctx->draw_rule.surf = U642VOID(rule->surface); tr_ctx->draw_rule.blocker = rule->block; tr_ctx->draw_blocker |= RBUG_BLOCK_RULE; diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h index 4dc95308a79..66250465e44 100644 --- a/src/gallium/drivers/trace/tr_texture.h +++ b/src/gallium/drivers/trace/tr_texture.h @@ -56,6 +56,14 @@ struct trace_surface }; +struct trace_sampler_view +{ + struct pipe_sampler_view base; + + struct pipe_sampler_view *sampler_view; +}; + + struct trace_transfer { struct pipe_transfer base; @@ -89,6 +97,15 @@ trace_surface(struct pipe_surface *surface) } +static INLINE struct trace_sampler_view * +trace_sampler_view(struct pipe_sampler_view *sampler_view) +{ + if (!sampler_view) + return NULL; + return (struct trace_sampler_view *)sampler_view; +} + + static INLINE struct trace_transfer * trace_transfer(struct pipe_transfer *transfer) { diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index a7f12fb81e1..d1b734a9f9a 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -214,13 +214,13 @@ struct pipe_context { void (*set_viewport_state)( struct pipe_context *, const struct pipe_viewport_state * ); - void (*set_fragment_sampler_textures)(struct pipe_context *, - unsigned num_textures, - struct pipe_texture **); + void (*set_fragment_sampler_views)(struct pipe_context *, + unsigned num_views, + struct pipe_sampler_view **); - void (*set_vertex_sampler_textures)(struct pipe_context *, - unsigned num_textures, - struct pipe_texture **); + void (*set_vertex_sampler_views)(struct pipe_context *, + unsigned num_views, + struct pipe_sampler_view **); void (*set_vertex_buffers)( struct pipe_context *, unsigned num_buffers, @@ -307,6 +307,15 @@ struct pipe_context { unsigned int (*is_buffer_referenced)(struct pipe_context *pipe, struct pipe_buffer *buf); + /** + * Create a view on a texture to be used by a shader stage. + */ + struct pipe_sampler_view * (*create_sampler_view)(struct pipe_context *ctx, + struct pipe_texture *texture, + const struct pipe_sampler_view *templat); + + void (*sampler_view_destroy)(struct pipe_context *ctx, + struct pipe_sampler_view *view); /** diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 5c97dc87e82..c1e291b9da4 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -370,6 +370,17 @@ enum pipe_transfer_usage { /** + * Texture swizzles + */ +#define PIPE_SWIZZLE_RED 0 +#define PIPE_SWIZZLE_GREEN 1 +#define PIPE_SWIZZLE_BLUE 2 +#define PIPE_SWIZZLE_ALPHA 3 +#define PIPE_SWIZZLE_ZERO 4 +#define PIPE_SWIZZLE_ONE 5 + + +/** * Implementation capabilities/limits which are queried through * pipe_screen::get_param() and pipe_screen::get_paramf(). */ diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 3a97d888ce6..11072407d93 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -300,6 +300,24 @@ struct pipe_surface /** + * A view into a texture that can be bound to a shader stage. + */ +struct pipe_sampler_view +{ + struct pipe_reference reference; + enum pipe_format format; /**< typed PIPE_FORMAT_x */ + struct pipe_texture *texture; /**< texture into which this is a view */ + struct pipe_context *context; /**< context this view belongs to */ + unsigned first_level:8; /**< first mipmap level */ + unsigned last_level:8; /**< last mipmap level */ + unsigned swizzle_r:3; /**< PIPE_SWIZZLE_x for red component */ + unsigned swizzle_g:3; /**< PIPE_SWIZZLE_x for green component */ + unsigned swizzle_b:3; /**< PIPE_SWIZZLE_x for blue component */ + unsigned swizzle_a:3; /**< PIPE_SWIZZLE_x for alpha component */ +}; + + +/** * Transfer object. For data transfer to/from a texture. */ struct pipe_transfer diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index ffb084e358b..632d71ccbee 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -49,6 +49,7 @@ #include "util/u_format.h" #include "util/u_dump.h" #include "util/u_memory.h" +#include "util/u_sampler.h" #include "cso_cache/cso_context.h" #include "tgsi/tgsi_text.h" #include "tgsi/tgsi_dump.h" diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 5c44462e80f..df700bc663c 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -169,22 +169,39 @@ struct st_context { void set_fragment_sampler_texture(unsigned index, struct pipe_texture *texture) { + struct pipe_sampler_view templ; + if(!texture) texture = $self->default_texture; - pipe_texture_reference(&$self->fragment_sampler_textures[index], texture); - $self->pipe->set_fragment_sampler_textures($self->pipe, - PIPE_MAX_SAMPLERS, - $self->fragment_sampler_textures); + pipe_sampler_view_reference(&$self->fragment_sampler_views[index], NULL); + u_sampler_view_default_template(&templ, + texture, + texture->format); + $self->fragment_sampler_views[index] = $self->pipe->create_sampler_view($self->pipe, + texture, + &templ); + $self->pipe->set_fragment_sampler_views($self->pipe, + PIPE_MAX_SAMPLERS, + $self->fragment_sampler_views); } void set_vertex_sampler_texture(unsigned index, struct pipe_texture *texture) { + struct pipe_sampler_view templ; + if(!texture) texture = $self->default_texture; - pipe_texture_reference(&$self->vertex_sampler_textures[index], texture); - $self->pipe->set_vertex_sampler_textures($self->pipe, - PIPE_MAX_VERTEX_SAMPLERS, - $self->vertex_sampler_textures); + pipe_sampler_view_reference(&$self->vertex_sampler_views[index], NULL); + u_sampler_view_default_template(&templ, + texture, + texture->format); + $self->vertex_sampler_views[index] = $self->pipe->create_sampler_view($self->pipe, + texture, + &templ); + + $self->pipe->set_vertex_sampler_views($self->pipe, + PIPE_MAX_VERTEX_SAMPLERS, + $self->vertex_sampler_views); } void set_vertex_buffer(unsigned index, diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index 335e8e7f0d8..0d87c705e75 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -33,6 +33,7 @@ #include "cso_cache/cso_context.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_sampler.h" #include "util/u_simple_shaders.h" #include "trace/tr_public.h" @@ -124,9 +125,9 @@ st_context_destroy(struct st_context *st_ctx) st_ctx->pipe->destroy(st_ctx->pipe); for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) - pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], NULL); + pipe_sampler_view_reference(&st_ctx->fragment_sampler_views[i], NULL); for(i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) - pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], NULL); + pipe_sampler_view_reference(&st_ctx->vertex_sampler_views[i], NULL); pipe_texture_reference(&st_ctx->default_texture, NULL); FREE(st_ctx); @@ -230,6 +231,8 @@ st_context_create(struct st_device *st_dev) struct pipe_screen *screen = st_dev->screen; struct pipe_texture templat; struct pipe_transfer *transfer; + struct pipe_sampler_view view_templ; + struct pipe_sampler_view *view; unsigned i; memset( &templat, 0, sizeof( templat ) ); @@ -259,14 +262,27 @@ st_context_create(struct st_device *st_dev) screen->tex_transfer_destroy(transfer); } } - + + u_sampler_view_default_template(&view_templ, + st_ctx->default_texture, + st_ctx->default_texture->format); + view = st_ctx->pipe->create_sampler_view(st_ctx->pipe, + st_ctx->default_texture, + &view_templ); + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], st_ctx->default_texture); + pipe_sampler_view_reference(&st_ctx->fragment_sampler_views[i], view); for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) - pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], st_ctx->default_texture); - - cso_set_sampler_textures(st_ctx->cso, PIPE_MAX_SAMPLERS, st_ctx->fragment_sampler_textures); - cso_set_vertex_sampler_textures(st_ctx->cso, PIPE_MAX_VERTEX_SAMPLERS, st_ctx->vertex_sampler_textures); + pipe_sampler_view_reference(&st_ctx->vertex_sampler_views[i], view); + + st_ctx->pipe->set_fragment_sampler_views(st_ctx->pipe, + PIPE_MAX_SAMPLERS, + st_ctx->fragment_sampler_views); + st_ctx->pipe->set_vertex_sampler_views(st_ctx->pipe, + PIPE_MAX_VERTEX_SAMPLERS, + st_ctx->vertex_sampler_views); + + pipe_sampler_view_reference(&view, NULL); } /* vertex shader */ diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h index 6ec7409b11d..dcd0dc6e273 100644 --- a/src/gallium/state_trackers/python/st_device.h +++ b/src/gallium/state_trackers/python/st_device.h @@ -60,8 +60,8 @@ struct st_context void *gs; struct pipe_texture *default_texture; - struct pipe_texture *fragment_sampler_textures[PIPE_MAX_SAMPLERS]; - struct pipe_texture *vertex_sampler_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]; unsigned num_vertex_buffers; struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index b446b2079cf..03e33361448 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -256,6 +256,8 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key) /* create the colormap/texture now if not already done */ if (!st->pixel_xfer.pixelmap_texture) { st->pixel_xfer.pixelmap_texture = create_color_map_texture(ctx); + st->pixel_xfer.pixelmap_sampler_view = st_sampler_view_from_texture(ctx->st->pipe, + st->pixel_xfer.pixelmap_texture); } /* with a little effort, we can do four pixel map look-ups with diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 57b71c1e7b0..241c001f94f 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -56,7 +56,7 @@ update_textures(struct st_context *st) /* loop over sampler units (aka tex image units) */ for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { - struct pipe_texture *pt = NULL; + struct pipe_sampler_view *sampler_view = NULL; if (samplersUsed & (1 << su)) { struct gl_texture_object *texObj; @@ -84,7 +84,7 @@ update_textures(struct st_context *st) st->state.num_textures = su + 1; - pt = st_get_stobj_texture(stObj); + sampler_view = st_get_stobj_sampler_view(stObj); } /* @@ -96,17 +96,17 @@ update_textures(struct st_context *st) } */ - pipe_texture_reference(&st->state.sampler_texture[su], pt); + pipe_sampler_view_reference(&st->state.sampler_views[su], sampler_view); } - cso_set_sampler_textures(st->cso_context, - st->state.num_textures, - st->state.sampler_texture); + cso_set_fragment_sampler_views(st->cso_context, + st->state.num_textures, + st->state.sampler_views); if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { - cso_set_vertex_sampler_textures(st->cso_context, - MIN2(st->state.num_textures, - st->ctx->Const.MaxVertexTextureImageUnits), - st->state.sampler_texture); + cso_set_vertex_sampler_views(st->cso_context, + MIN2(st->state.num_textures, + st->ctx->Const.MaxVertexTextureImageUnits), + st->state.sampler_views); } } diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index dfd8925edf4..9a0446bb710 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -397,7 +397,7 @@ setup_bitmap_vertex_data(struct st_context *st, static void draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, GLsizei width, GLsizei height, - struct pipe_texture *pt, + struct pipe_sampler_view *sv, const GLfloat *color) { struct st_context *st = ctx->st; @@ -435,7 +435,7 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_save_rasterizer(cso); cso_save_samplers(cso); - cso_save_sampler_textures(cso); + cso_save_fragment_sampler_views(cso); cso_save_viewport(cso); cso_save_fragment_shader(cso); cso_save_vertex_shader(cso); @@ -465,11 +465,11 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, /* user textures, plus the bitmap texture */ { - struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; uint num = MAX2(stfp->bitmap_sampler + 1, st->state.num_textures); - memcpy(textures, st->state.sampler_texture, sizeof(textures)); - textures[stfp->bitmap_sampler] = pt; - cso_set_sampler_textures(cso, num, textures); + memcpy(sampler_views, st->state.sampler_views, sizeof(sampler_views)); + sampler_views[stfp->bitmap_sampler] = sv; + cso_set_fragment_sampler_views(cso, num, sampler_views); } /* viewport state: viewport matching window dims */ @@ -507,7 +507,7 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, /* restore state */ cso_restore_rasterizer(cso); cso_restore_samplers(cso); - cso_restore_sampler_textures(cso); + cso_restore_fragment_sampler_views(cso); cso_restore_viewport(cso); cso_restore_fragment_shader(cso); cso_restore_vertex_shader(cso); @@ -598,6 +598,7 @@ st_flush_bitmap_cache(struct st_context *st) if (st->ctx->DrawBuffer) { struct pipe_context *pipe = st->pipe; + struct pipe_sampler_view *sv; assert(cache->xmin <= cache->xmax); @@ -620,13 +621,18 @@ st_flush_bitmap_cache(struct st_context *st) cache->trans = NULL; } - draw_bitmap_quad(st->ctx, - cache->xpos, - cache->ypos, - cache->zpos, - BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT, - cache->texture, - cache->color); + sv = st_sampler_view_from_texture(st->pipe, cache->texture); + if (sv) { + draw_bitmap_quad(st->ctx, + cache->xpos, + cache->ypos, + cache->zpos, + BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT, + sv, + cache->color); + + pipe_sampler_view_reference(&sv, NULL); + } } /* release/free the texture */ @@ -749,10 +755,18 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, pt = make_bitmap_texture(ctx, width, height, unpack, bitmap); if (pt) { + struct pipe_sampler_view *sv = st_sampler_view_from_texture(st->pipe, pt); + assert(pt->target == PIPE_TEXTURE_2D); - draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2], - width, height, pt, - st->ctx->Current.RasterColor); + + if (sv) { + draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2], + width, height, sv, + st->ctx->Current.RasterColor); + + pipe_sampler_view_reference(&sv, NULL); + } + /* release/free the texture */ pipe_texture_reference(&pt, NULL); } diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c index 36e03018d9f..06b0a18fd22 100644 --- a/src/mesa/state_tracker/st_cb_blit.c +++ b/src/mesa/state_tracker/st_cb_blit.c @@ -69,6 +69,7 @@ st_BlitFramebuffer(GLcontext *ctx, const GLbitfield depthStencil = (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); struct st_context *st = ctx->st; + struct pipe_context *pipe = st->pipe; const uint pFilter = ((filter == GL_NEAREST) ? PIPE_TEX_MIPFILTER_NEAREST : PIPE_TEX_MIPFILTER_LINEAR); @@ -111,8 +112,8 @@ st_BlitFramebuffer(GLcontext *ctx, &readFB->Attachment[readFB->_ColorReadBufferIndex]; if(srcAtt->Type == GL_TEXTURE) { - struct pipe_screen *screen = ctx->st->pipe->screen; - const struct st_texture_object *srcObj = + struct pipe_screen *screen = pipe->screen; + struct st_texture_object *srcObj = st_texture_object(srcAtt->Texture); struct st_renderbuffer *dstRb = st_renderbuffer(drawFB->_ColorDrawBuffers[0]); @@ -132,7 +133,8 @@ st_BlitFramebuffer(GLcontext *ctx, return; util_blit_pixels(st->blit, - srcSurf, srcX0, srcY0, srcX1, srcY1, + srcSurf, st_get_stobj_sampler_view(srcObj), + srcX0, srcY0, srcX1, srcY1, dstSurf, dstX0, dstY0, dstX1, dstY1, 0.0, pFilter); @@ -144,10 +146,11 @@ st_BlitFramebuffer(GLcontext *ctx, struct st_renderbuffer *dstRb = st_renderbuffer(drawFB->_ColorDrawBuffers[0]); struct pipe_surface *srcSurf = srcRb->surface; + struct pipe_sampler_view *srcView = st_renderbuffer_get_sampler_view(srcRb, pipe); struct pipe_surface *dstSurf = dstRb->surface; util_blit_pixels(st->blit, - srcSurf, srcX0, srcY0, srcX1, srcY1, + srcSurf, srcView, srcX0, srcY0, srcX1, srcY1, dstSurf, dstX0, dstY0, dstX1, dstY1, 0.0, pFilter); } @@ -179,11 +182,13 @@ st_BlitFramebuffer(GLcontext *ctx, if ((mask & depthStencil) == depthStencil && srcDepthSurf == srcStencilSurf && dstDepthSurf == dstStencilSurf) { + struct pipe_sampler_view *srcView = st_renderbuffer_get_sampler_view(srcDepthRb, pipe); + /* Blitting depth and stencil values between combined * depth/stencil buffers. This is the ideal case for such buffers. */ util_blit_pixels(st->blit, - srcDepthSurf, srcX0, srcY0, srcX1, srcY1, + srcDepthSurf, srcView, srcX0, srcY0, srcX1, srcY1, dstDepthSurf, dstX0, dstY0, dstX1, dstY1, 0.0, pFilter); } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index c44d0fc3e86..75be79fd4b0 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -525,7 +525,7 @@ static void draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, GLsizei width, GLsizei height, GLfloat zoomX, GLfloat zoomY, - struct pipe_texture *pt, + struct pipe_sampler_view *sv, void *driver_vp, void *driver_fp, const GLfloat *color, @@ -548,7 +548,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_save_rasterizer(cso); cso_save_viewport(cso); cso_save_samplers(cso); - cso_save_sampler_textures(cso); + cso_save_fragment_sampler_views(cso); cso_save_fragment_shader(cso); cso_save_vertex_shader(cso); cso_save_vertex_elements(cso); @@ -608,13 +608,13 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, /* texture state: */ if (st->pixel_xfer.pixelmap_enabled) { - struct pipe_texture *textures[2]; - textures[0] = pt; - textures[1] = st->pixel_xfer.pixelmap_texture; - pipe->set_fragment_sampler_textures(pipe, 2, textures); + struct pipe_sampler_view *sampler_views[2]; + sampler_views[0] = sv; + sampler_views[1] = st->pixel_xfer.pixelmap_sampler_view; + cso_set_fragment_sampler_views(cso, 2, sampler_views); } else { - pipe->set_fragment_sampler_textures(pipe, 1, &pt); + cso_set_fragment_sampler_views(cso, 1, &sv); } /* Compute Gallium window coords (y=0=top) with pixel zoom. @@ -635,14 +635,14 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, z = z * 2.0 - 1.0; draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex, - (GLfloat) width / pt->width0, - (GLfloat) height / pt->height0); + (GLfloat) width / sv->texture->width0, + (GLfloat) height / sv->texture->height0); /* restore state */ cso_restore_rasterizer(cso); cso_restore_viewport(cso); cso_restore_samplers(cso); - cso_restore_sampler_textures(cso); + cso_restore_fragment_sampler_views(cso); cso_restore_fragment_shader(cso); cso_restore_vertex_shader(cso); cso_restore_vertex_elements(cso); @@ -835,12 +835,17 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, struct pipe_texture *pt = make_texture(st, width, height, format, type, unpack, pixels); if (pt) { - draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], - width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, - pt, - driver_vp, - driver_fp, - color, GL_FALSE); + struct pipe_sampler_view *sv = st_sampler_view_from_texture(st->pipe, pt); + + if (sv) { + draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], + width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, + sv, + driver_vp, + driver_fp, + color, GL_FALSE); + pipe_sampler_view_reference(&sv, NULL); + } pipe_texture_reference(&pt, NULL); } } @@ -959,6 +964,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, struct st_renderbuffer *rbRead; void *driver_vp, *driver_fp; struct pipe_texture *pt; + struct pipe_sampler_view *sv; GLfloat *color; enum pipe_format srcFormat, texFormat; GLboolean invertTex = GL_FALSE; @@ -1056,6 +1062,12 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, if (!pt) return; + sv = st_sampler_view_from_texture(st->pipe, pt); + if (!sv) { + pipe_texture_reference(&pt, NULL); + return; + } + /* Make temporary texture which is a copy of the src region. * We'll draw a quad with this texture to draw the dest image. */ @@ -1133,12 +1145,13 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, /* draw textured quad */ draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, - pt, + sv, driver_vp, driver_fp, color, invertTex); pipe_texture_reference(&pt, NULL); + pipe_sampler_view_reference(&sv, NULL); } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 114a8596adf..4ccba1db85d 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -104,6 +104,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, */ pipe_surface_reference( &strb->surface, NULL ); pipe_texture_reference( &strb->texture, NULL ); + pipe_sampler_view_reference(&strb->sampler_view, NULL); /* Setup new texture template. */ @@ -163,6 +164,7 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb) ASSERT(strb); pipe_surface_reference(&strb->surface, NULL); pipe_texture_reference(&strb->texture, NULL); + pipe_sampler_view_reference(&strb->sampler_view, NULL); free(strb->data); free(strb); } @@ -369,6 +371,8 @@ st_render_texture(GLcontext *ctx, pipe_surface_reference(&strb->surface, NULL); + pipe_sampler_view_reference(&strb->sampler_view, st_get_stobj_sampler_view(stObj)); + assert(strb->rtt_level <= strb->texture->last_level); /* new surface for rendering into the texture */ @@ -663,3 +667,14 @@ void st_init_fbo_functions(struct dd_function_table *functions) functions->DrawBuffers = st_DrawBuffers; functions->ReadBuffer = st_ReadBuffer; } + +struct pipe_sampler_view * +st_renderbuffer_get_sampler_view(struct st_renderbuffer *rb, + struct pipe_context *pipe) +{ + if (!rb->sampler_view) { + rb->sampler_view = st_sampler_view_from_texture(pipe, rb->texture); + } + + return rb->sampler_view; +} diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index bea6eb89c3e..7a45a608fe1 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -39,6 +39,7 @@ struct st_renderbuffer struct gl_renderbuffer Base; struct pipe_texture *texture; struct pipe_surface *surface; /* temporary view into texture */ + struct pipe_sampler_view *sampler_view; enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */ GLboolean defined; /**< defined contents? */ @@ -55,6 +56,7 @@ struct st_renderbuffer /** Render to texture state */ struct pipe_texture *texture_save; struct pipe_surface *surface_save; + struct pipe_sampler_view *sampler_view_save; }; @@ -71,5 +73,9 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw); extern void st_init_fbo_functions(struct dd_function_table *functions); +extern struct pipe_sampler_view * +st_renderbuffer_get_sampler_view(struct st_renderbuffer *rb, + struct pipe_context *pipe); + #endif /* ST_CB_FBO_H */ diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 626e6ad660d..0c518a7e031 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -123,6 +123,8 @@ st_DeleteTextureObject(GLcontext *ctx, struct st_texture_object *stObj = st_texture_object(texObj); if (stObj->pt) pipe_texture_reference(&stObj->pt, NULL); + if (stObj->sampler_view) + pipe_sampler_view_reference(&stObj->sampler_view, NULL); _mesa_delete_texture_object(ctx, texObj); } @@ -312,6 +314,8 @@ guess_and_alloc_texture(struct st_context *st, depth, usage); + stObj->pipe = st->pipe; + DBG("%s - success\n", __FUNCTION__); } @@ -1453,6 +1457,7 @@ st_copy_texsubimage(GLcontext *ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; struct gl_texture_object *texObj = _mesa_select_tex_object(ctx, texUnit, target); + struct st_texture_object *stObj = st_texture_object(texObj); struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texObj, target, level); struct st_texture_image *stImage = st_texture_image(texImage); @@ -1593,6 +1598,7 @@ st_copy_texsubimage(GLcontext *ctx, } util_blit_pixels_writemask(ctx->st->blit, strb->surface, + st_renderbuffer_get_sampler_view(strb, pipe), srcX, srcY0, srcX + width, srcY1, dest_surface, diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 7c1a0b8bc54..0885ad77c7c 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -215,8 +215,8 @@ static void st_destroy_context_priv( struct st_context *st ) st_destroy_drawtex(st); #endif - for (i = 0; i < Elements(st->state.sampler_texture); i++) { - pipe_texture_reference(&st->state.sampler_texture[i], NULL); + for (i = 0; i < Elements(st->state.sampler_views); i++) { + pipe_sampler_view_reference(&st->state.sampler_views[i], NULL); } for (i = 0; i < Elements(st->state.constants); i++) { diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 2d81c4ca631..786beaec08b 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -97,7 +97,7 @@ struct st_context struct pipe_clip_state clip; struct pipe_buffer *constants[2]; struct pipe_framebuffer_state framebuffer; - struct pipe_texture *sampler_texture[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; @@ -144,6 +144,7 @@ struct st_context struct st_fragment_program *combined_prog; GLuint combined_prog_sn; struct pipe_texture *pixelmap_texture; + struct pipe_sampler_view *pixelmap_sampler_view; boolean pixelmap_enabled; /**< use the pixelmap texture? */ } pixel_xfer; diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 0a91183f89d..d3c43bbc68a 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -197,6 +197,7 @@ st_set_framebuffer_surface(struct st_framebuffer *stfb, /* replace the renderbuffer's surface/texture pointers */ pipe_surface_reference( &strb->surface, surf ); pipe_texture_reference( &strb->texture, surf->texture ); + pipe_sampler_view_reference(&strb->sampler_view, NULL); if (ctx) { /* If ctx isn't set, we've likely not made current yet. diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 10a38befb41..ef97d873e50 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -528,14 +528,21 @@ st_bind_teximage(struct st_framebuffer *stfb, uint surfIndex, /* save the renderbuffer's surface/texture info */ pipe_texture_reference(&strb->texture_save, strb->texture); pipe_surface_reference(&strb->surface_save, strb->surface); + pipe_sampler_view_reference(&strb->sampler_view_save, strb->sampler_view); /* plug in new surface/texture info */ pipe_texture_reference(&strb->texture, stImage->pt); + + /* XXX: Shouldn't we release reference to old surface here? + */ + strb->surface = screen->get_tex_surface(screen, strb->texture, face, level, slice, (PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE)); + pipe_sampler_view_reference(&strb->sampler_view, NULL); + st->dirty.st |= ST_NEW_FRAMEBUFFER; return 1; @@ -565,9 +572,11 @@ st_release_teximage(struct st_framebuffer *stfb, uint surfIndex, /* free tex surface, restore original */ pipe_surface_reference(&strb->surface, strb->surface_save); pipe_texture_reference(&strb->texture, strb->texture_save); + pipe_sampler_view_reference(&strb->sampler_view, strb->sampler_view_save); pipe_surface_reference(&strb->surface_save, NULL); pipe_texture_reference(&strb->texture_save, NULL); + pipe_sampler_view_reference(&strb->sampler_view, NULL); st->dirty.st |= ST_NEW_FRAMEBUFFER; diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 60868ce0673..c62f7f2cc0d 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -29,6 +29,9 @@ #define ST_TEXTURE_H +#include "pipe/p_context.h" +#include "util/u_sampler.h" + #include "main/mtypes.h" struct pipe_context; @@ -68,6 +71,13 @@ struct st_texture_object */ struct pipe_texture *pt; + /* Default sampler view attached to this texture object. Created lazily + * on first binding. + */ + struct pipe_sampler_view *sampler_view; + + struct pipe_context *pipe; + GLboolean teximage_realloc; /* True if there is/was a surface bound to this texture object. It helps @@ -105,6 +115,35 @@ st_get_stobj_texture(struct st_texture_object *stObj) } +static INLINE struct pipe_sampler_view * +st_sampler_view_from_texture(struct pipe_context *pipe, + struct pipe_texture *texture) +{ + struct pipe_sampler_view templ; + + u_sampler_view_default_template(&templ, + texture, + texture->format); + + return pipe->create_sampler_view(pipe, texture, &templ); +} + + +static INLINE struct pipe_sampler_view * +st_get_stobj_sampler_view(struct st_texture_object *stObj) +{ + if (!stObj || !stObj->pt) { + return NULL; + } + + if (!stObj->sampler_view) { + stObj->sampler_view = st_sampler_view_from_texture(stObj->pipe, stObj->pt); + } + + return stObj->sampler_view; +} + + extern struct pipe_texture * st_texture_create(struct st_context *st, enum pipe_texture_target target, |