summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/Makefile14
-rw-r--r--src/gallium/auxiliary/SConscript12
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c235
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h39
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c58
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c58
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c36
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h24
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h10
-rw-r--r--src/gallium/auxiliary/util/u_sampler.c100
-rw-r--r--src/gallium/auxiliary/util/u_sampler.h57
-rw-r--r--src/gallium/auxiliary/util/u_tile.c63
-rw-r--r--src/gallium/auxiliary/util/u_tile.h14
-rw-r--r--src/gallium/docs/source/context.rst20
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.h1
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c47
-rw-r--r--src/gallium/drivers/failover/fo_context.h18
-rw-r--r--src/gallium/drivers/failover/fo_state.c106
-rw-r--r--src/gallium/drivers/failover/fo_state_emit.c24
-rw-r--r--src/gallium/drivers/i915/i915_context.h6
-rw-r--r--src/gallium/drivers/i915/i915_state.c55
-rw-r--r--src/gallium/drivers/i915/i915_state_derived.c4
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c3
-rw-r--r--src/gallium/drivers/i915/i915_state_sampler.c18
-rw-r--r--src/gallium/drivers/i965/brw_context.h4
-rw-r--r--src/gallium/drivers/i965/brw_pipe_sampler.c54
-rw-r--r--src/gallium/drivers/i965/brw_wm.c4
-rw-r--r--src/gallium/drivers/i965/brw_wm_sampler_state.c8
-rw-r--r--src/gallium/drivers/i965/brw_wm_surface_state.c6
-rw-r--r--src/gallium/drivers/identity/id_context.c93
-rw-r--r--src/gallium/drivers/identity/id_objects.h26
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c12
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h23
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c12
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_sampler.c65
-rw-r--r--src/gallium/drivers/nv40/nv40_transfer.c181
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h22
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c6
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c71
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c10
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c202
-rw-r--r--src/gallium/drivers/nv50/nv50_texture.h32
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.h1
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state.c37
-rw-r--r--src/gallium/drivers/r300/r300_blit.c6
-rw-r--r--src/gallium/drivers/r300/r300_context.h5
-rw-r--r--src/gallium/drivers/r300/r300_emit.c8
-rw-r--r--src/gallium/drivers/r300/r300_state.c60
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c10
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h8
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h21
-rw-r--r--src/gallium/drivers/softpipe/sp_state_sampler.c89
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.c33
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.h10
-rw-r--r--src/gallium/drivers/svga/svga_context.h4
-rw-r--r--src/gallium/drivers/svga/svga_pipe_sampler.c59
-rw-r--r--src/gallium/drivers/svga/svga_state_constants.c2
-rw-r--r--src/gallium/drivers/svga/svga_state_fs.c9
-rw-r--r--src/gallium/drivers/svga/svga_state_tss.c22
-rw-r--r--src/gallium/drivers/trace/tr_context.c135
-rw-r--r--src/gallium/drivers/trace/tr_context.h10
-rw-r--r--src/gallium/drivers/trace/tr_rbug.c8
-rw-r--r--src/gallium/drivers/trace/tr_texture.h17
-rw-r--r--src/gallium/include/pipe/p_context.h21
-rw-r--r--src/gallium/include/pipe/p_defines.h11
-rw-r--r--src/gallium/include/pipe/p_state.h18
-rw-r--r--src/gallium/state_trackers/python/gallium.i1
-rw-r--r--src/gallium/state_trackers/python/p_context.i33
-rw-r--r--src/gallium/state_trackers/python/st_device.c32
-rw-r--r--src/gallium/state_trackers/python/st_device.h4
75 files changed, 1744 insertions, 812 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..648ba10a995 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"
@@ -70,16 +72,20 @@ struct cso_context {
void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+ uint nr_fragment_sampler_views;
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
uint nr_textures;
- 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.
@@ -295,11 +301,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);
@@ -624,12 +632,27 @@ enum pipe_error cso_set_sampler_textures( struct cso_context *ctx,
ctx->nr_textures = count;
- for (i = 0; i < count; i++)
+ for (i = 0; i < count; i++) {
+ struct pipe_sampler_view templ, *view;
+
+ u_sampler_view_default_template(&templ,
+ textures[i],
+ textures[i]->format);
+ view = ctx->pipe->create_sampler_view(ctx->pipe,
+ textures[i],
+ &templ);
+
pipe_texture_reference(&ctx->textures[i], textures[i]);
- for ( ; i < PIPE_MAX_SAMPLERS; i++)
+ pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], view);
+ }
+ for ( ; i < PIPE_MAX_SAMPLERS; i++) {
pipe_texture_reference(&ctx->textures[i], NULL);
+ pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL);
+ }
- ctx->pipe->set_fragment_sampler_textures(ctx->pipe, count, textures);
+ ctx->pipe->set_fragment_sampler_views(ctx->pipe,
+ count,
+ ctx->fragment_sampler_views);
return PIPE_OK;
}
@@ -641,7 +664,11 @@ void cso_save_sampler_textures( struct cso_context *ctx )
ctx->nr_textures_saved = ctx->nr_textures;
for (i = 0; i < ctx->nr_textures; i++) {
assert(!ctx->textures_saved[i]);
+ assert(!ctx->fragment_sampler_views_saved[i]);
+
pipe_texture_reference(&ctx->textures_saved[i], ctx->textures[i]);
+ pipe_sampler_view_reference(&ctx->fragment_sampler_views_saved[i],
+ ctx->fragment_sampler_views[i]);
}
}
@@ -655,75 +682,24 @@ void cso_restore_sampler_textures( struct cso_context *ctx )
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_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);
+ 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;
}
-
- ctx->pipe->set_vertex_sampler_textures(ctx->pipe, count, textures);
-
- return PIPE_OK;
-}
-
-void
-cso_save_vertex_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]);
- }
-}
-
-void
-cso_restore_vertex_sampler_textures(struct cso_context *ctx)
-{
- uint i;
-
- ctx->nr_vertex_textures = ctx->nr_vertex_textures_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 < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- pipe_texture_reference(&ctx->vertex_textures[i], NULL);
+ for ( ; i < PIPE_MAX_SAMPLERS; i++) {
+ pipe_texture_reference(&ctx->textures[i], NULL);
+ 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_textures,
+ ctx->fragment_sampler_views);
- ctx->nr_vertex_textures_saved = 0;
+ ctx->nr_textures_saved = 0;
}
-
enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx,
const struct pipe_depth_stencil_alpha_state *templ)
{
@@ -1261,3 +1237,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_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 a5a1a720742..13cd934b13f 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 9a8de0edfda..b75ca282067 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/nv40/nv40_transfer.c b/src/gallium/drivers/nv40/nv40_transfer.c
deleted file mode 100644
index 3d8c8e8c78a..00000000000
--- a/src/gallium/drivers/nv40/nv40_transfer.c
+++ /dev/null
@@ -1,181 +0,0 @@
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_memory.h"
-#include "util/u_math.h"
-#include "nouveau/nouveau_winsys.h"
-#include "nv40_context.h"
-#include "nvfx_screen.h"
-#include "nvfx_state.h"
-
-struct nv40_transfer {
- struct pipe_transfer base;
- struct pipe_surface *surface;
- boolean direct;
-};
-
-static void
-nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
- struct pipe_texture *template)
-{
- memset(template, 0, sizeof(struct pipe_texture));
- template->target = pt->target;
- template->format = pt->format;
- template->width0 = width;
- template->height0 = height;
- template->depth0 = 1;
- template->last_level = 0;
- template->nr_samples = pt->nr_samples;
-
- template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
- NOUVEAU_TEXTURE_USAGE_LINEAR;
-}
-
-static struct pipe_transfer *
-nv40_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x, unsigned y, unsigned w, unsigned h)
-{
- struct pipe_screen *pscreen = pcontext->screen;
- struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
- struct nv40_transfer *tx;
- struct pipe_texture tx_tex_template, *tx_tex;
-
- tx = CALLOC_STRUCT(nv40_transfer);
- if (!tx)
- return NULL;
-
- pipe_texture_reference(&tx->base.texture, pt);
- tx->base.x = x;
- tx->base.y = y;
- tx->base.width = w;
- tx->base.height = h;
- tx->base.stride = mt->level[level].pitch;
- tx->base.usage = usage;
- tx->base.face = face;
- tx->base.level = level;
- tx->base.zslice = zslice;
-
- /* Direct access to texture */
- if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC ||
- debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) &&
- pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
- {
- tx->direct = true;
- tx->surface = pscreen->get_tex_surface(pscreen, pt,
- face, level, zslice,
- pipe_transfer_buffer_flags(&tx->base));
- return &tx->base;
- }
-
- tx->direct = false;
-
- nv40_compatible_transfer_tex(pt, w, h, &tx_tex_template);
-
- tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
- if (!tx_tex)
- {
- FREE(tx);
- return NULL;
- }
-
- tx->base.stride = ((struct nvfx_miptree*)tx_tex)->level[0].pitch;
-
- tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
- 0, 0, 0,
- pipe_transfer_buffer_flags(&tx->base));
-
- pipe_texture_reference(&tx_tex, NULL);
-
- if (!tx->surface)
- {
- pipe_surface_reference(&tx->surface, NULL);
- FREE(tx);
- return NULL;
- }
-
- if (usage & PIPE_TRANSFER_READ) {
- struct nvfx_screen *nvscreen = nvfx_screen(pscreen);
- struct pipe_surface *src;
-
- src = pscreen->get_tex_surface(pscreen, pt,
- face, level, zslice,
- PIPE_BUFFER_USAGE_GPU_READ);
-
- /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
- /* TODO: Check if SIFM can un-swizzle */
- nvscreen->eng2d->copy(nvscreen->eng2d,
- tx->surface, 0, 0,
- src, x, y,
- w, h);
-
- pipe_surface_reference(&src, NULL);
- }
-
- return &tx->base;
-}
-
-static void
-nv40_transfer_del(struct pipe_context *pcontext, struct pipe_transfer *ptx)
-{
- struct nv40_transfer *tx = (struct nv40_transfer *)ptx;
-
- if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) {
- struct pipe_screen *pscreen = pcontext->screen;
- struct nvfx_screen *nvscreen = nvfx_screen(pscreen);
- struct pipe_surface *dst;
-
- dst = pscreen->get_tex_surface(pscreen, ptx->texture,
- ptx->face, ptx->level, ptx->zslice,
- PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER);
-
- /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
- nvscreen->eng2d->copy(nvscreen->eng2d,
- dst, tx->base.x, tx->base.y,
- tx->surface, 0, 0,
- tx->base.width, tx->base.height);
-
- pipe_surface_reference(&dst, NULL);
- }
-
- pipe_surface_reference(&tx->surface, NULL);
- pipe_texture_reference(&ptx->texture, NULL);
- FREE(ptx);
-}
-
-static void *
-nv40_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
-{
- struct pipe_screen *pscreen = pcontext->screen;
- struct nv40_transfer *tx = (struct nv40_transfer *)ptx;
- struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
- struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
- void *map = pipe_buffer_map(pscreen, mt->buffer,
- pipe_transfer_buffer_flags(ptx));
-
- if(!tx->direct)
- return map + ns->base.offset;
- else
- return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
-}
-
-static void
-nv40_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
-{
- struct pipe_screen *pscreen = pcontext->screen;
- struct nv40_transfer *tx = (struct nv40_transfer *)ptx;
- struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
-
- pipe_buffer_unmap(pscreen, mt->buffer);
-}
-
-void
-nv40_init_transfer_functions(struct nvfx_context *nvfx)
-{
- nvfx->pipe.get_tex_transfer = nv40_transfer_new;
- nvfx->pipe.tex_transfer_destroy = nv40_transfer_del;
- nvfx->pipe.transfer_map = nv40_transfer_map;
- nvfx->pipe.transfer_unmap = nv40_transfer_unmap;
-}
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 4c48b12cd87..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,117 +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_data (so, 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;
}
@@ -202,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);
}
@@ -229,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..32a81997528 100644
--- a/src/gallium/drivers/nvfx/nvfx_state.c
+++ b/src/gallium/drivers/nvfx/nvfx_state.c
@@ -137,19 +137,24 @@ 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_sampler_view_reference(&nv30->fragment_sampler_views[unit],
+ views[unit]);
pipe_texture_reference((struct pipe_texture **)
&nvfx->tex_miptree[unit], miptree[unit]);
nvfx->dirty_samplers |= (1 << unit);
}
for (unit = nr; unit < nvfx->nr_textures; unit++) {
+ pipe_sampler_view_reference(&nv30->fragment_sampler_views[unit],
+ NULL);
pipe_texture_reference((struct pipe_texture **)
&nvfx->tex_miptree[unit], NULL);
nvfx->dirty_samplers |= (1 << unit);
@@ -159,6 +164,34 @@ nvfx_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
nvfx->dirty |= NVFX_NEW_SAMPLER;
}
+
+static struct pipe_sampler_view *
+nv30_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
+nv30_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)
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index b7ad6b20206..a60b12844d6 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(
- r300->blitter, state->texture_count,
- (struct pipe_texture**)state->textures);
+ util_blitter_save_fragment_sampler_views(
+ r300->blitter, r300->fragment_sampler_view_count,
+ r300->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..2763103fda1 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -343,8 +343,9 @@ struct r300_context {
struct r300_atom rs_block_state;
/* Scissor state. */
struct r300_atom scissor_state;
- /* Textures state. */
- struct r300_atom textures_state;
+ /* Sampler view states. */
+ struct pipe_sampler_view* fragment_sampler_views[8];
+ int fragment_sampler_view_count;
/* Vertex stream formatting state. */
struct r300_atom vertex_stream_state;
/* VAP (vertex shader) output mapping state. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index d8c64dd9001..0a3f0f45c03 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 = r300->fragment_sampler_views[constant->u.State[1]]->texture;
vec[0] = 1.0 / tex->width0;
vec[1] = 1.0 / tex->height0;
break;
@@ -1042,10 +1042,10 @@ validate:
}
}
/* ...textures... */
- for (i = 0; i < texstate->count; i++) {
- tex = texstate->textures[i];
- if (!tex || !texstate->sampler_states[i])
+ for (i = 0; i < r300->fragment_sampler_view_count; i++) {
+ if (!r300->fragment_sampler_views[i])
continue;
+ tex = (struct r300_texture *)r300->fragment_sampler_views[i]->texture;
if (!r300_add_texture(r300->rws, tex,
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
r300->context.flush(&r300->context, 0, NULL);
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 712e9280e3c..71ac89715cc 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -933,13 +933,11 @@ 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 =
- (struct r300_textures_state*)r300->textures_state.state;
unsigned i;
boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
boolean dirty_tex = FALSE;
@@ -950,13 +948,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 (r300->fragment_sampler_views[i] != views[i]) {
+ struct r300_texture *texture;
+
+ pipe_sampler_view_reference(&r300->fragment_sampler_views[i],
+ views[i]);
dirty_tex = TRUE;
- /* R300-specific - set the texrect factor in the fragment shader */
- if (!is_r500 && state->textures[i]->is_npot) {
+ texture = (struct r300_texture *)views[i]->texture;
+
+ /* R300-specific - set the texrect factor in a fragment shader */
+ 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,13 +967,13 @@ 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],
+ if (r300->fragment_sampler_views[i]) {
+ pipe_sampler_view_reference(&r300->fragment_sampler_views[i],
NULL);
}
}
- state->texture_count = count;
+ r300->fragment_sampler_view_count = count;
r300->textures_state.dirty = TRUE;
@@ -980,6 +982,34 @@ 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 r300_context *r300 = r300_context(pipe);
+ 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 +1503,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/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];