summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/softpipe
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/softpipe')
-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_flush.h2
-rw-r--r--src/gallium/drivers/softpipe/sp_limits.h42
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_blend.c14
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c5
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h2
-rw-r--r--src/gallium/drivers/softpipe/sp_state_derived.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_state_sampler.c54
-rw-r--r--src/gallium/drivers/softpipe/sp_state_shader.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_state_vertex.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c172
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.h31
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.c57
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.h36
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c80
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h5
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c14
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.h22
20 files changed, 354 insertions, 214 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index b5d30bc6fc..f3489c1c79 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -129,6 +129,10 @@ softpipe_destroy( struct pipe_context *pipe )
}
}
+ for (i = 0; i < softpipe->num_vertex_buffers; i++) {
+ pipe_resource_reference(&softpipe->vertex_buffer[i].buffer, NULL);
+ }
+
tgsi_exec_machine_destroy(softpipe->fs_machine);
FREE( softpipe );
@@ -145,15 +149,15 @@ softpipe_destroy( struct pipe_context *pipe )
*/
static unsigned int
softpipe_is_resource_referenced( struct pipe_context *pipe,
- struct pipe_resource *texture,
- unsigned face, unsigned level)
+ struct pipe_resource *texture,
+ unsigned level, int layer)
{
struct softpipe_context *softpipe = softpipe_context( pipe );
unsigned i;
if (texture->target == PIPE_BUFFER)
return PIPE_UNREFERENCED;
-
+
/* check if any of the bound drawing surfaces are this texture */
if (softpipe->dirty_render_cache) {
for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 9361a3df09..903574b7e1 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -154,9 +154,9 @@ struct softpipe_context {
/** TGSI exec things */
struct {
- struct sp_sampler_varient *geom_samplers_list[PIPE_MAX_GEOMETRY_SAMPLERS];
- struct sp_sampler_varient *vert_samplers_list[PIPE_MAX_VERTEX_SAMPLERS];
- struct sp_sampler_varient *frag_samplers_list[PIPE_MAX_SAMPLERS];
+ struct sp_sampler_variant *geom_samplers_list[PIPE_MAX_GEOMETRY_SAMPLERS];
+ struct sp_sampler_variant *vert_samplers_list[PIPE_MAX_VERTEX_SAMPLERS];
+ struct sp_sampler_variant *frag_samplers_list[PIPE_MAX_SAMPLERS];
} tgsi;
struct tgsi_exec_machine *fs_machine;
@@ -192,7 +192,7 @@ softpipe_context( struct pipe_context *pipe )
}
void
-softpipe_reset_sampler_varients(struct softpipe_context *softpipe);
+softpipe_reset_sampler_variants(struct softpipe_context *softpipe);
struct pipe_context *
softpipe_create_context( struct pipe_screen *, void *priv );
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index 1071011db0..4258395063 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -120,8 +120,8 @@ softpipe_flush( struct pipe_context *pipe,
boolean
softpipe_flush_resource(struct pipe_context *pipe,
struct pipe_resource *texture,
- unsigned face,
unsigned level,
+ int layer,
unsigned flush_flags,
boolean read_only,
boolean cpu_access,
@@ -129,7 +129,7 @@ softpipe_flush_resource(struct pipe_context *pipe,
{
unsigned referenced;
- referenced = pipe->is_resource_referenced(pipe, texture, face, level);
+ referenced = pipe->is_resource_referenced(pipe, texture, level, layer);
if ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) {
diff --git a/src/gallium/drivers/softpipe/sp_flush.h b/src/gallium/drivers/softpipe/sp_flush.h
index cb97482a71..22a5ceeb9e 100644
--- a/src/gallium/drivers/softpipe/sp_flush.h
+++ b/src/gallium/drivers/softpipe/sp_flush.h
@@ -40,8 +40,8 @@ softpipe_flush(struct pipe_context *pipe, unsigned flags,
boolean
softpipe_flush_resource(struct pipe_context *pipe,
struct pipe_resource *texture,
- unsigned face,
unsigned level,
+ int layer,
unsigned flush_flags,
boolean read_only,
boolean cpu_access,
diff --git a/src/gallium/drivers/softpipe/sp_limits.h b/src/gallium/drivers/softpipe/sp_limits.h
new file mode 100644
index 0000000000..a7a24c98d5
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_limits.h
@@ -0,0 +1,42 @@
+/**************************************************************************
+ *
+ * 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 THE AUTHORS 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 SP_LIMITS_H
+#define SP_LIMITS_H
+
+
+
+#define SP_MAX_TEXTURE_2D_LEVELS 15 /* 16K x 16K */
+#define SP_MAX_TEXTURE_3D_LEVELS 9 /* 512 x 512 x 512 */
+
+
+/** Max surface size */
+#define MAX_WIDTH (1 << (SP_MAX_TEXTURE_2D_LEVELS - 1))
+#define MAX_HEIGHT (1 << (SP_MAX_TEXTURE_2D_LEVELS - 1))
+
+
+#endif /* SP_LIMITS_H */
diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c
index 6af1b2d061..76cfc0bf51 100644
--- a/src/gallium/drivers/softpipe/sp_quad_blend.c
+++ b/src/gallium/drivers/softpipe/sp_quad_blend.c
@@ -35,6 +35,7 @@
#include "util/u_memory.h"
#include "util/u_format.h"
#include "sp_context.h"
+#include "sp_state.h"
#include "sp_quad.h"
#include "sp_tile_cache.h"
#include "sp_quad_pipe.h"
@@ -794,6 +795,9 @@ blend_fallback(struct quad_stage *qs,
struct softpipe_context *softpipe = qs->softpipe;
const struct pipe_blend_state *blend = softpipe->blend;
unsigned cbuf;
+ boolean write_all;
+
+ write_all = softpipe->fs->color0_writes_all_cbufs;
for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++)
{
@@ -806,15 +810,19 @@ blend_fallback(struct quad_stage *qs,
quads[0]->input.y0);
boolean has_dst_alpha
= util_format_has_alpha(softpipe->framebuffer.cbufs[cbuf]->format);
- uint q, i, j;
+ uint q, i, j, qbuf;
+
+ qbuf = write_all ? 0 : cbuf;
for (q = 0; q < nr; q++) {
struct quad_header *quad = quads[q];
- float (*quadColor)[4] = quad->output.color[cbuf];
+ float (*quadColor)[4];
const int itx = (quad->input.x0 & (TILE_SIZE-1));
const int ity = (quad->input.y0 & (TILE_SIZE-1));
- /* get/swizzle dest colors
+ quadColor = quad->output.color[qbuf];
+
+ /* get/swizzle dest colors
*/
for (j = 0; j < QUAD_SIZE; j++) {
int x = itx + (j & 1);
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 9b54babdfb..e19f2e6fc7 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -268,12 +268,13 @@ softpipe_destroy_screen( struct pipe_screen *screen )
*/
static void
softpipe_flush_frontbuffer(struct pipe_screen *_screen,
- struct pipe_surface *surface,
+ struct pipe_resource *resource,
+ unsigned level, unsigned layer,
void *context_private)
{
struct softpipe_screen *screen = softpipe_screen(_screen);
struct sw_winsys *winsys = screen->winsys;
- struct softpipe_resource *texture = softpipe_resource(surface->texture);
+ struct softpipe_resource *texture = softpipe_resource(resource);
assert(texture->dt);
if (texture->dt)
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 525bf23734..bb19f8cff2 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -74,7 +74,7 @@ struct sp_fragment_shader {
boolean origin_lower_left; /**< fragment shader uses lower left position origin? */
boolean pixel_center_integer; /**< fragment shader uses integer pixel center? */
-
+ boolean color0_writes_all_cbufs; /**< fragment shader writes color0 to all bound cbufs */
void (*prepare)( const struct sp_fragment_shader *shader,
struct tgsi_exec_machine *machine,
struct tgsi_sampler **samplers);
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 3ba4d934fd..bf4c12701a 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -197,7 +197,7 @@ update_tgsi_samplers( struct softpipe_context *softpipe )
{
unsigned i;
- softpipe_reset_sampler_varients( softpipe );
+ softpipe_reset_sampler_variants( softpipe );
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
struct softpipe_tex_tile_cache *tc = softpipe->tex_cache[i];
diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c
index b59fbc33ed..cfa211b60a 100644
--- a/src/gallium/drivers/softpipe/sp_state_sampler.c
+++ b/src/gallium/drivers/softpipe/sp_state_sampler.c
@@ -43,8 +43,8 @@
struct sp_sampler {
struct pipe_sampler_state base;
- struct sp_sampler_varient *varients;
- struct sp_sampler_varient *current;
+ struct sp_sampler_variant *variants;
+ struct sp_sampler_variant *current;
};
static struct sp_sampler *sp_sampler( struct pipe_sampler_state *sampler )
@@ -60,7 +60,7 @@ softpipe_create_sampler_state(struct pipe_context *pipe,
struct sp_sampler *sp_sampler = CALLOC_STRUCT(sp_sampler);
sp_sampler->base = *sampler;
- sp_sampler->varients = NULL;
+ sp_sampler->variants = NULL;
return (void *)sp_sampler;
}
@@ -277,23 +277,24 @@ softpipe_set_geometry_sampler_views(struct pipe_context *pipe,
/**
- * Find/create an sp_sampler_varient object for sampling the given texture,
+ * Find/create an sp_sampler_variant object for sampling the given texture,
* sampler and tex unit.
*
* Note that the tex unit is significant. We can't re-use a sampler
- * varient for multiple texture units because the sampler varient contains
+ * variant for multiple texture units because the sampler variant contains
* the texture object pointer. If the texture object pointer were stored
- * somewhere outside the sampler varient, we could re-use samplers for
+ * somewhere outside the sampler variant, we could re-use samplers for
* multiple texture units.
*/
-static struct sp_sampler_varient *
-get_sampler_varient( unsigned unit,
+static struct sp_sampler_variant *
+get_sampler_variant( unsigned unit,
struct sp_sampler *sampler,
+ struct pipe_sampler_view *view,
struct pipe_resource *resource,
unsigned processor )
{
struct softpipe_resource *sp_texture = softpipe_resource(resource);
- struct sp_sampler_varient *v = NULL;
+ struct sp_sampler_variant *v = NULL;
union sp_sampler_key key;
/* if this fails, widen the key.unit field and update this assertion */
@@ -303,6 +304,10 @@ get_sampler_varient( unsigned unit,
key.bits.is_pot = sp_texture->pot;
key.bits.processor = processor;
key.bits.unit = unit;
+ key.bits.swizzle_r = view->swizzle_r;
+ key.bits.swizzle_g = view->swizzle_g;
+ key.bits.swizzle_b = view->swizzle_b;
+ key.bits.swizzle_a = view->swizzle_a;
key.bits.pad = 0;
if (sampler->current &&
@@ -311,14 +316,14 @@ get_sampler_varient( unsigned unit,
}
if (v == NULL) {
- for (v = sampler->varients; v; v = v->next)
+ for (v = sampler->variants; v; v = v->next)
if (v->key.value == key.value)
break;
if (v == NULL) {
- v = sp_create_sampler_varient( &sampler->base, key );
- v->next = sampler->varients;
- sampler->varients = v;
+ v = sp_create_sampler_variant( &sampler->base, key );
+ v->next = sampler->variants;
+ sampler->variants = v;
}
}
@@ -328,7 +333,7 @@ get_sampler_varient( unsigned unit,
void
-softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
+softpipe_reset_sampler_variants(struct softpipe_context *softpipe)
{
int i;
@@ -345,12 +350,13 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
}
softpipe->tgsi.vert_samplers_list[i] =
- get_sampler_varient( i,
+ get_sampler_variant( i,
sp_sampler(softpipe->vertex_samplers[i]),
+ softpipe->vertex_sampler_views[i],
texture,
TGSI_PROCESSOR_VERTEX );
- sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i],
+ sp_sampler_variant_bind_texture( softpipe->tgsi.vert_samplers_list[i],
softpipe->vertex_tex_cache[i],
texture );
}
@@ -366,13 +372,14 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
}
softpipe->tgsi.geom_samplers_list[i] =
- get_sampler_varient(
+ get_sampler_variant(
i,
sp_sampler(softpipe->geometry_samplers[i]),
+ softpipe->geometry_sampler_views[i],
texture,
TGSI_PROCESSOR_GEOMETRY );
- sp_sampler_varient_bind_texture(
+ sp_sampler_variant_bind_texture(
softpipe->tgsi.geom_samplers_list[i],
softpipe->geometry_tex_cache[i],
texture );
@@ -389,12 +396,13 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
}
softpipe->tgsi.frag_samplers_list[i] =
- get_sampler_varient( i,
+ get_sampler_variant( i,
sp_sampler(softpipe->sampler[i]),
+ softpipe->sampler_views[i],
texture,
TGSI_PROCESSOR_FRAGMENT );
- sp_sampler_varient_bind_texture( softpipe->tgsi.frag_samplers_list[i],
+ sp_sampler_variant_bind_texture( softpipe->tgsi.frag_samplers_list[i],
softpipe->tex_cache[i],
texture );
}
@@ -406,11 +414,11 @@ softpipe_delete_sampler_state(struct pipe_context *pipe,
void *sampler)
{
struct sp_sampler *sp_sampler = (struct sp_sampler *)sampler;
- struct sp_sampler_varient *v, *tmp;
+ struct sp_sampler_variant *v, *tmp;
- for (v = sp_sampler->varients; v; v = tmp) {
+ for (v = sp_sampler->variants; v; v = tmp) {
tmp = v->next;
- sp_sampler_varient_destroy(v);
+ sp_sampler_variant_destroy(v);
}
FREE( sampler );
diff --git a/src/gallium/drivers/softpipe/sp_state_shader.c b/src/gallium/drivers/softpipe/sp_state_shader.c
index 7fff338cce..66ddc56572 100644
--- a/src/gallium/drivers/softpipe/sp_state_shader.c
+++ b/src/gallium/drivers/softpipe/sp_state_shader.c
@@ -78,6 +78,8 @@ softpipe_create_fs_state(struct pipe_context *pipe,
state->origin_lower_left = state->info.properties[i].data[0];
else if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_PIXEL_CENTER)
state->pixel_center_integer = state->info.properties[i].data[0];
+ else if (state->info.properties[i].name == TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS)
+ state->color0_writes_all_cbufs = state->info.properties[i].data[0];
}
return state;
diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c
index 7d8055f2ba..5f4d661abd 100644
--- a/src/gallium/drivers/softpipe/sp_state_vertex.c
+++ b/src/gallium/drivers/softpipe/sp_state_vertex.c
@@ -33,6 +33,7 @@
#include "sp_state.h"
#include "util/u_memory.h"
+#include "util/u_inlines.h"
#include "draw/draw_context.h"
@@ -84,8 +85,9 @@ softpipe_set_vertex_buffers(struct pipe_context *pipe,
assert(count <= PIPE_MAX_ATTRIBS);
- memcpy(softpipe->vertex_buffer, buffers, count * sizeof(buffers[0]));
- softpipe->num_vertex_buffers = count;
+ util_copy_vertex_buffers(softpipe->vertex_buffer,
+ &softpipe->num_vertex_buffers,
+ buffers, count);
softpipe->dirty |= SP_NEW_VERTEX;
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 2eac4c7a82..cbc40d4b44 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -545,7 +545,7 @@ wrap_linear_unorm_clamp_to_edge(const float s[4], unsigned size,
* derivatives w.r.t X and Y, then compute lambda (level of detail).
*/
static float
-compute_lambda_1d(const struct sp_sampler_varient *samp,
+compute_lambda_1d(const struct sp_sampler_variant *samp,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE])
@@ -560,7 +560,7 @@ compute_lambda_1d(const struct sp_sampler_varient *samp,
static float
-compute_lambda_2d(const struct sp_sampler_varient *samp,
+compute_lambda_2d(const struct sp_sampler_variant *samp,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE])
@@ -579,7 +579,7 @@ compute_lambda_2d(const struct sp_sampler_varient *samp,
static float
-compute_lambda_3d(const struct sp_sampler_varient *samp,
+compute_lambda_3d(const struct sp_sampler_variant *samp,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE])
@@ -608,7 +608,7 @@ compute_lambda_3d(const struct sp_sampler_varient *samp,
* Since there aren't derivatives to use, just return 0.
*/
static float
-compute_lambda_vert(const struct sp_sampler_varient *samp,
+compute_lambda_vert(const struct sp_sampler_variant *samp,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE])
@@ -634,7 +634,7 @@ compute_lambda_vert(const struct sp_sampler_varient *samp,
static INLINE const float *
-get_texel_2d_no_border(const struct sp_sampler_varient *samp,
+get_texel_2d_no_border(const struct sp_sampler_variant *samp,
union tex_tile_address addr, int x, int y)
{
const struct softpipe_tex_cached_tile *tile;
@@ -651,7 +651,7 @@ get_texel_2d_no_border(const struct sp_sampler_varient *samp,
static INLINE const float *
-get_texel_2d(const struct sp_sampler_varient *samp,
+get_texel_2d(const struct sp_sampler_variant *samp,
union tex_tile_address addr, int x, int y)
{
const struct pipe_resource *texture = samp->texture;
@@ -659,8 +659,7 @@ get_texel_2d(const struct sp_sampler_varient *samp,
if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
y < 0 || y >= (int) u_minify(texture->height0, level)) {
- return sp_tex_tile_cache_border_color(samp->cache,
- samp->sampler->border_color);
+ return samp->sampler->border_color;
}
else {
return get_texel_2d_no_border( samp, addr, x, y );
@@ -671,7 +670,7 @@ get_texel_2d(const struct sp_sampler_varient *samp,
/* Gather a quad of adjacent texels within a tile:
*/
static INLINE void
-get_texel_quad_2d_no_border_single_tile(const struct sp_sampler_varient *samp,
+get_texel_quad_2d_no_border_single_tile(const struct sp_sampler_variant *samp,
union tex_tile_address addr,
unsigned x, unsigned y,
const float *out[4])
@@ -695,7 +694,7 @@ get_texel_quad_2d_no_border_single_tile(const struct sp_sampler_varient *samp,
/* Gather a quad of potentially non-adjacent texels:
*/
static INLINE void
-get_texel_quad_2d_no_border(const struct sp_sampler_varient *samp,
+get_texel_quad_2d_no_border(const struct sp_sampler_variant *samp,
union tex_tile_address addr,
int x0, int y0,
int x1, int y1,
@@ -710,7 +709,7 @@ get_texel_quad_2d_no_border(const struct sp_sampler_varient *samp,
/* Can involve a lot of unnecessary checks for border color:
*/
static INLINE void
-get_texel_quad_2d(const struct sp_sampler_varient *samp,
+get_texel_quad_2d(const struct sp_sampler_variant *samp,
union tex_tile_address addr,
int x0, int y0,
int x1, int y1,
@@ -724,10 +723,10 @@ get_texel_quad_2d(const struct sp_sampler_varient *samp,
-/* 3d varients:
+/* 3d variants:
*/
static INLINE const float *
-get_texel_3d_no_border(const struct sp_sampler_varient *samp,
+get_texel_3d_no_border(const struct sp_sampler_variant *samp,
union tex_tile_address addr, int x, int y, int z)
{
const struct softpipe_tex_cached_tile *tile;
@@ -745,7 +744,7 @@ get_texel_3d_no_border(const struct sp_sampler_varient *samp,
static INLINE const float *
-get_texel_3d(const struct sp_sampler_varient *samp,
+get_texel_3d(const struct sp_sampler_variant *samp,
union tex_tile_address addr, int x, int y, int z)
{
const struct pipe_resource *texture = samp->texture;
@@ -754,8 +753,7 @@ get_texel_3d(const struct sp_sampler_varient *samp,
if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
y < 0 || y >= (int) u_minify(texture->height0, level) ||
z < 0 || z >= (int) u_minify(texture->depth0, level)) {
- return sp_tex_tile_cache_border_color(samp->cache,
- samp->sampler->border_color);
+ return samp->sampler->border_color;
}
else {
return get_texel_3d_no_border( samp, addr, x, y, z );
@@ -800,7 +798,7 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
unsigned j;
unsigned level = samp->level;
unsigned xpot = pot_level_size(samp->xpot, level);
@@ -863,7 +861,7 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
unsigned j;
unsigned level = samp->level;
unsigned xpot = pot_level_size(samp->xpot, level);
@@ -907,7 +905,7 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
unsigned j;
unsigned level = samp->level;
unsigned xpot = pot_level_size(samp->xpot, level);
@@ -960,7 +958,7 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->texture;
unsigned level0, j;
int width;
@@ -1000,7 +998,7 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->texture;
unsigned level0, j;
int width, height;
@@ -1052,7 +1050,7 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->texture;
const unsigned *faces = samp->faces; /* zero when not cube-mapping */
unsigned level0, j;
@@ -1096,7 +1094,7 @@ img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->texture;
unsigned level0, j;
int width, height, depth;
@@ -1138,7 +1136,7 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->texture;
unsigned level0, j;
int width;
@@ -1178,7 +1176,7 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->texture;
unsigned level0, j;
int width, height;
@@ -1225,7 +1223,7 @@ img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->texture;
const unsigned *faces = samp->faces; /* zero when not cube-mapping */
unsigned level0, j;
@@ -1274,7 +1272,7 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->texture;
unsigned level0, j;
int width, height, depth;
@@ -1350,7 +1348,7 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->texture;
int level0;
float lambda;
@@ -1417,7 +1415,7 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->texture;
float lambda;
float lod[QUAD_SIZE];
@@ -1460,7 +1458,7 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
float lambda;
float lod[QUAD_SIZE];
@@ -1501,7 +1499,7 @@ mip_filter_linear_2d_linear_repeat_POT(
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->texture;
int level0;
float lambda;
@@ -1569,7 +1567,7 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_sampler_state *sampler = samp->sampler;
int j, k0, k1, k2, k3;
float val;
@@ -1656,7 +1654,7 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
unsigned j;
float ssss[4], tttt[4];
@@ -1731,6 +1729,86 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
}
+static void
+sample_swizzle(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
+ float rgba_temp[NUM_CHANNELS][QUAD_SIZE];
+ const unsigned swizzle_r = samp->key.bits.swizzle_r;
+ const unsigned swizzle_g = samp->key.bits.swizzle_g;
+ const unsigned swizzle_b = samp->key.bits.swizzle_b;
+ const unsigned swizzle_a = samp->key.bits.swizzle_a;
+ unsigned j;
+
+ samp->sample_target(tgsi_sampler, s, t, p, c0, control, rgba_temp);
+
+ switch (swizzle_r) {
+ case PIPE_SWIZZLE_ZERO:
+ for (j = 0; j < 4; j++)
+ rgba[0][j] = 0.0f;
+ break;
+ case PIPE_SWIZZLE_ONE:
+ for (j = 0; j < 4; j++)
+ rgba[0][j] = 1.0f;
+ break;
+ default:
+ assert(swizzle_r < 4);
+ for (j = 0; j < 4; j++)
+ rgba[0][j] = rgba_temp[swizzle_r][j];
+ }
+
+ switch (swizzle_g) {
+ case PIPE_SWIZZLE_ZERO:
+ for (j = 0; j < 4; j++)
+ rgba[1][j] = 0.0f;
+ break;
+ case PIPE_SWIZZLE_ONE:
+ for (j = 0; j < 4; j++)
+ rgba[1][j] = 1.0f;
+ break;
+ default:
+ assert(swizzle_g < 4);
+ for (j = 0; j < 4; j++)
+ rgba[1][j] = rgba_temp[swizzle_g][j];
+ }
+
+ switch (swizzle_b) {
+ case PIPE_SWIZZLE_ZERO:
+ for (j = 0; j < 4; j++)
+ rgba[2][j] = 0.0f;
+ break;
+ case PIPE_SWIZZLE_ONE:
+ for (j = 0; j < 4; j++)
+ rgba[2][j] = 1.0f;
+ break;
+ default:
+ assert(swizzle_b < 4);
+ for (j = 0; j < 4; j++)
+ rgba[2][j] = rgba_temp[swizzle_b][j];
+ }
+
+ switch (swizzle_a) {
+ case PIPE_SWIZZLE_ZERO:
+ for (j = 0; j < 4; j++)
+ rgba[3][j] = 0.0f;
+ break;
+ case PIPE_SWIZZLE_ONE:
+ for (j = 0; j < 4; j++)
+ rgba[3][j] = 1.0f;
+ break;
+ default:
+ assert(swizzle_a < 4);
+ for (j = 0; j < 4; j++)
+ rgba[3][j] = rgba_temp[swizzle_a][j];
+ }
+}
+
static wrap_nearest_func
get_nearest_unorm_wrap(unsigned mode)
@@ -1909,10 +1987,10 @@ get_img_filter(const union sp_sampler_key key,
/**
- * Bind the given texture object and texture cache to the sampler varient.
+ * Bind the given texture object and texture cache to the sampler variant.
*/
void
-sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp,
+sp_sampler_variant_bind_texture( struct sp_sampler_variant *samp,
struct softpipe_tex_tile_cache *tex_cache,
const struct pipe_resource *texture )
{
@@ -1927,20 +2005,20 @@ sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp,
void
-sp_sampler_varient_destroy( struct sp_sampler_varient *samp )
+sp_sampler_variant_destroy( struct sp_sampler_variant *samp )
{
FREE(samp);
}
/**
- * Create a sampler varient for a given set of non-orthogonal state.
+ * Create a sampler variant for a given set of non-orthogonal state.
*/
-struct sp_sampler_varient *
-sp_create_sampler_varient( const struct pipe_sampler_state *sampler,
+struct sp_sampler_variant *
+sp_create_sampler_variant( const struct pipe_sampler_state *sampler,
const union sp_sampler_key key )
{
- struct sp_sampler_varient *samp = CALLOC_STRUCT(sp_sampler_varient);
+ struct sp_sampler_variant *samp = CALLOC_STRUCT(sp_sampler_variant);
if (!samp)
return NULL;
@@ -2015,7 +2093,7 @@ sp_create_sampler_varient( const struct pipe_sampler_state *sampler,
}
if (key.bits.target == PIPE_TEXTURE_CUBE) {
- samp->base.get_samples = sample_cube;
+ samp->sample_target = sample_cube;
}
else {
samp->faces[0] = 0;
@@ -2026,7 +2104,17 @@ sp_create_sampler_varient( const struct pipe_sampler_state *sampler,
/* Skip cube face determination by promoting the compare
* function pointer:
*/
- samp->base.get_samples = samp->compare;
+ samp->sample_target = samp->compare;
+ }
+
+ if (key.bits.swizzle_r != PIPE_SWIZZLE_RED ||
+ key.bits.swizzle_g != PIPE_SWIZZLE_GREEN ||
+ key.bits.swizzle_b != PIPE_SWIZZLE_BLUE ||
+ key.bits.swizzle_a != PIPE_SWIZZLE_ALPHA) {
+ samp->base.get_samples = sample_swizzle;
+ }
+ else {
+ samp->base.get_samples = samp->sample_target;
}
return samp;
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h
index 6114acf737..ed99006ab0 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.h
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.h
@@ -32,7 +32,7 @@
#include "tgsi/tgsi_exec.h"
-struct sp_sampler_varient;
+struct sp_sampler_variant;
typedef void (*wrap_nearest_func)(const float s[4],
unsigned size,
@@ -44,7 +44,7 @@ typedef void (*wrap_linear_func)(const float s[4],
int icoord1[4],
float w[4]);
-typedef float (*compute_lambda_func)(const struct sp_sampler_varient *sampler,
+typedef float (*compute_lambda_func)(const struct sp_sampler_variant *sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE]);
@@ -64,7 +64,11 @@ union sp_sampler_key {
unsigned is_pot:1;
unsigned processor:2;
unsigned unit:4;
- unsigned pad:22;
+ unsigned swizzle_r:3;
+ unsigned swizzle_g:3;
+ unsigned swizzle_b:3;
+ unsigned swizzle_a:3;
+ unsigned pad:10;
} bits;
unsigned value;
};
@@ -72,7 +76,7 @@ union sp_sampler_key {
/**
* Subclass of tgsi_sampler
*/
-struct sp_sampler_varient
+struct sp_sampler_variant
{
struct tgsi_sampler base; /**< base class */
@@ -113,32 +117,33 @@ struct sp_sampler_varient
filter_func mip_filter;
filter_func compare;
+ filter_func sample_target;
/* Linked list:
*/
- struct sp_sampler_varient *next;
+ struct sp_sampler_variant *next;
};
struct sp_sampler;
-/* Create a sampler varient for a given set of non-orthogonal state. Currently the
+/* Create a sampler variant for a given set of non-orthogonal state. Currently the
*/
-struct sp_sampler_varient *
-sp_create_sampler_varient( const struct pipe_sampler_state *sampler,
+struct sp_sampler_variant *
+sp_create_sampler_variant( const struct pipe_sampler_state *sampler,
const union sp_sampler_key key );
-void sp_sampler_varient_bind_texture( struct sp_sampler_varient *varient,
+void sp_sampler_variant_bind_texture( struct sp_sampler_variant *variant,
struct softpipe_tex_tile_cache *tex_cache,
const struct pipe_resource *tex );
-void sp_sampler_varient_destroy( struct sp_sampler_varient * );
+void sp_sampler_variant_destroy( struct sp_sampler_variant * );
-static INLINE struct sp_sampler_varient *
-sp_sampler_varient(const struct tgsi_sampler *sampler)
+static INLINE struct sp_sampler_variant *
+sp_sampler_variant(const struct tgsi_sampler *sampler)
{
- return (struct sp_sampler_varient *) sampler;
+ return (struct sp_sampler_variant *) sampler;
}
extern void
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
index e817c0c8cf..e42015ad49 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
@@ -48,6 +48,9 @@ sp_create_tex_tile_cache( struct pipe_context *pipe )
struct softpipe_tex_tile_cache *tc;
uint pos;
+ /* make sure max texture size works */
+ assert((TILE_SIZE << TEX_ADDR_BITS) >= (1 << (SP_MAX_TEXTURE_2D_LEVELS-1)));
+
tc = CALLOC_STRUCT( softpipe_tex_tile_cache );
if (tc) {
tc->pipe = pipe;
@@ -260,15 +263,14 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
}
tc->tex_trans =
- pipe_get_transfer(tc->pipe, tc->texture,
- addr.bits.face,
- addr.bits.level,
- addr.bits.z,
- PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED,
- 0, 0,
- u_minify(tc->texture->width0, addr.bits.level),
- u_minify(tc->texture->height0, addr.bits.level));
-
+ pipe_get_transfer(tc->pipe, tc->texture,
+ addr.bits.level,
+ addr.bits.face + addr.bits.z,
+ PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED,
+ 0, 0,
+ u_minify(tc->texture->width0, addr.bits.level),
+ u_minify(tc->texture->height0, addr.bits.level));
+
tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans);
tc->tex_face = addr.bits.face;
@@ -276,45 +278,26 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
tc->tex_z = addr.bits.z;
}
- /* get tile from the transfer (view into texture) */
+ /* get tile from the transfer (view into texture)
+ * Note we're using the swizzle version of this fuction only because
+ * we need to pass the texture cache's format explicitly.
+ */
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,
+ PIPE_SWIZZLE_RED,
+ PIPE_SWIZZLE_GREEN,
+ PIPE_SWIZZLE_BLUE,
+ PIPE_SWIZZLE_ALPHA,
tc->format,
(float *) tile->data.color);
+
tile->addr = addr;
}
tc->last_tile = tile;
return tile;
}
-
-
-
-/**
- * Return the swizzled border color.
- */
-const float *
-sp_tex_tile_cache_border_color(struct softpipe_tex_tile_cache *tc,
- const float border_color[4])
-{
- float rgba01[6];
-
- COPY_4V(rgba01, border_color);
- rgba01[PIPE_SWIZZLE_ZERO] = 0.0f;
- rgba01[PIPE_SWIZZLE_ONE] = 1.0f;
-
- tc->swz_border_color[0] = rgba01[tc->swizzle_r];
- tc->swz_border_color[1] = rgba01[tc->swizzle_g];
- tc->swz_border_color[2] = rgba01[tc->swizzle_b];
- tc->swz_border_color[3] = rgba01[tc->swizzle_a];
-
- return tc->swz_border_color;
-}
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
index 05f25133da..2220955b71 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
@@ -30,6 +30,7 @@
#include "pipe/p_compiler.h"
+#include "sp_limits.h"
struct softpipe_context;
@@ -39,22 +40,26 @@ struct softpipe_tex_tile_cache;
/**
* Cache tile size (width and height). This needs to be a power of two.
*/
-#define TILE_SIZE 64
+#define TILE_SIZE_LOG2 6
+#define TILE_SIZE (1 << TILE_SIZE_LOG2)
-/* If we need to support > 4096, just expand this to be a 64 bit
- * union, or consider tiling in Z as well.
+#define TEX_ADDR_BITS (SP_MAX_TEXTURE_2D_LEVELS - 1 - TILE_SIZE_LOG2)
+#define TEX_Z_BITS (SP_MAX_TEXTURE_2D_LEVELS - 1)
+
+/**
+ * Texture tile address as a union for fast compares.
*/
union tex_tile_address {
struct {
- unsigned x:6; /* 4096 / TILE_SIZE */
- unsigned y:6; /* 4096 / TILE_SIZE */
- unsigned z:12; /* 4096 -- z not tiled */
+ unsigned x:TEX_ADDR_BITS; /* 16K / TILE_SIZE */
+ unsigned y:TEX_ADDR_BITS; /* 16K / TILE_SIZE */
+ unsigned z:TEX_Z_BITS; /* 16K -- z not tiled */
unsigned face:3;
unsigned level:4;
unsigned invalid:1;
} bits;
- unsigned value;
+ uint64_t value;
};
@@ -90,8 +95,6 @@ struct softpipe_tex_tile_cache
unsigned format;
struct softpipe_tex_cached_tile *last_tile; /**< most recently retrieved tile */
-
- float swz_border_color[4]; /**< swizzled border color */
};
@@ -126,10 +129,10 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
static INLINE union tex_tile_address
tex_tile_address( unsigned x,
- unsigned y,
- unsigned z,
- unsigned face,
- unsigned level )
+ unsigned y,
+ unsigned z,
+ unsigned face,
+ unsigned level )
{
union tex_tile_address addr;
@@ -139,7 +142,7 @@ tex_tile_address( unsigned x,
addr.bits.z = z;
addr.bits.face = face;
addr.bits.level = level;
-
+
return addr;
}
@@ -156,10 +159,5 @@ sp_get_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
}
-const float *
-sp_tex_tile_cache_border_color(struct softpipe_tex_tile_cache *tc,
- const float border_color[4]);
-
-
#endif /* SP_TEX_TILE_CACHE_H */
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 4e6123fbd0..509d9982b1 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -220,23 +220,18 @@ softpipe_resource_get_handle(struct pipe_screen *screen,
*/
static unsigned
sp_get_tex_image_offset(const struct softpipe_resource *spr,
- unsigned level, unsigned face, unsigned zslice)
+ unsigned level, unsigned layer)
{
const unsigned hgt = u_minify(spr->base.height0, level);
const unsigned nblocksy = util_format_get_nblocksy(spr->base.format, hgt);
unsigned offset = spr->level_offset[level];
- if (spr->base.target == PIPE_TEXTURE_CUBE) {
- assert(zslice == 0);
- offset += face * nblocksy * spr->stride[level];
- }
- else if (spr->base.target == PIPE_TEXTURE_3D) {
- assert(face == 0);
- offset += zslice * nblocksy * spr->stride[level];
+ if (spr->base.target == PIPE_TEXTURE_CUBE ||
+ spr->base.target == PIPE_TEXTURE_3D) {
+ offset += layer * nblocksy * spr->stride[level];
}
else {
- assert(face == 0);
- assert(zslice == 0);
+ assert(layer == 0);
}
return offset;
@@ -247,39 +242,40 @@ sp_get_tex_image_offset(const struct softpipe_resource *spr,
* Get a pipe_surface "view" into a texture resource.
*/
static struct pipe_surface *
-softpipe_get_tex_surface(struct pipe_screen *screen,
- struct pipe_resource *pt,
- unsigned face, unsigned level, unsigned zslice,
- unsigned usage)
+softpipe_create_surface(struct pipe_context *pipe,
+ struct pipe_resource *pt,
+ const struct pipe_surface *surf_tmpl)
{
- struct softpipe_resource *spr = softpipe_resource(pt);
struct pipe_surface *ps;
+ unsigned level = surf_tmpl->u.tex.level;
assert(level <= pt->last_level);
+ assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
ps = CALLOC_STRUCT(pipe_surface);
if (ps) {
pipe_reference_init(&ps->reference, 1);
pipe_resource_reference(&ps->texture, pt);
- ps->format = pt->format;
+ ps->context = pipe;
+ ps->format = surf_tmpl->format;
ps->width = u_minify(pt->width0, level);
ps->height = u_minify(pt->height0, level);
- ps->offset = sp_get_tex_image_offset(spr, level, face, zslice);
- ps->usage = usage;
+ ps->usage = surf_tmpl->usage;
- ps->face = face;
- ps->level = level;
- ps->zslice = zslice;
+ ps->u.tex.level = level;
+ ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+ ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
}
return ps;
}
/**
- * Free a pipe_surface which was created with softpipe_get_tex_surface().
+ * Free a pipe_surface which was created with softpipe_create_surface().
*/
static void
-softpipe_tex_surface_destroy(struct pipe_surface *surf)
+softpipe_surface_destroy(struct pipe_context *pipe,
+ struct pipe_surface *surf)
{
/* Effectively do the texture_update work here - if texture images
* needed post-processing to put them into hardware layout, this is
@@ -302,21 +298,21 @@ softpipe_tex_surface_destroy(struct pipe_surface *surf)
*/
static struct pipe_transfer *
softpipe_get_transfer(struct pipe_context *pipe,
- struct pipe_resource *resource,
- struct pipe_subresource sr,
- unsigned usage,
- const struct pipe_box *box)
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box)
{
struct softpipe_resource *spr = softpipe_resource(resource);
struct softpipe_transfer *spt;
assert(resource);
- assert(sr.level <= resource->last_level);
+ assert(level <= resource->last_level);
/* make sure the requested region is in the image bounds */
- assert(box->x + box->width <= u_minify(resource->width0, sr.level));
- assert(box->y + box->height <= u_minify(resource->height0, sr.level));
- assert(box->z + box->depth <= u_minify(resource->depth0, sr.level));
+ assert(box->x + box->width <= u_minify(resource->width0, level));
+ assert(box->y + box->height <= u_minify(resource->height0, level));
+ assert(box->z + box->depth <= (u_minify(resource->depth0, level) + resource->array_size - 1));
/*
* Transfers, like other pipe operations, must happen in order, so flush the
@@ -326,7 +322,7 @@ softpipe_get_transfer(struct pipe_context *pipe,
boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
if (!softpipe_flush_resource(pipe, resource,
- sr.face, sr.level,
+ level, box->depth > 1 ? -1 : box->z,
0, /* flush_flags */
read_only,
TRUE, /* cpu_access */
@@ -343,21 +339,21 @@ softpipe_get_transfer(struct pipe_context *pipe,
if (spt) {
struct pipe_transfer *pt = &spt->base;
enum pipe_format format = resource->format;
- const unsigned hgt = u_minify(spr->base.height0, sr.level);
+ const unsigned hgt = u_minify(spr->base.height0, level);
const unsigned nblocksy = util_format_get_nblocksy(format, hgt);
pipe_resource_reference(&pt->resource, resource);
- pt->sr = sr;
+ pt->level = level;
pt->usage = usage;
pt->box = *box;
- pt->stride = spr->stride[sr.level];
- pt->slice_stride = pt->stride * nblocksy;
+ pt->stride = spr->stride[level];
+ pt->layer_stride = pt->stride * nblocksy;
- spt->offset = sp_get_tex_image_offset(spr, sr.level, sr.face, box->z);
+ spt->offset = sp_get_tex_image_offset(spr, level, box->z);
spt->offset +=
- box->y / util_format_get_blockheight(format) * spt->base.stride +
- box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
+ box->y / util_format_get_blockheight(format) * spt->base.stride +
+ box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
return pt;
}
@@ -454,6 +450,7 @@ softpipe_user_buffer_create(struct pipe_screen *screen,
spr->base.width0 = bytes;
spr->base.height0 = 1;
spr->base.depth0 = 1;
+ spr->base.array_size = 1;
spr->userBuffer = TRUE;
spr->data = ptr;
@@ -471,6 +468,9 @@ softpipe_init_texture_funcs(struct pipe_context *pipe)
pipe->transfer_flush_region = u_default_transfer_flush_region;
pipe->transfer_inline_write = u_default_transfer_inline_write;
+
+ pipe->create_surface = softpipe_create_surface;
+ pipe->surface_destroy = softpipe_surface_destroy;
}
@@ -483,6 +483,4 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
screen->resource_get_handle = softpipe_resource_get_handle;
screen->user_buffer_create = softpipe_user_buffer_create;
- screen->get_tex_surface = softpipe_get_tex_surface;
- screen->tex_surface_destroy = softpipe_tex_surface_destroy;
}
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index 6b205dc532..5603110eeb 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -30,10 +30,7 @@
#include "pipe/p_state.h"
-
-
-#define SP_MAX_TEXTURE_2D_LEVELS 13 /* 4K x 4K */
-#define SP_MAX_TEXTURE_3D_LEVELS 9 /* 512 x 512 x 512 */
+#include "sp_limits.h"
struct pipe_context;
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index aa76b8aa1e..480860af63 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -92,6 +92,10 @@ sp_create_tile_cache( struct pipe_context *pipe )
maxTexSize = 1 << (maxLevels - 1);
assert(MAX_WIDTH >= maxTexSize);
+ assert(sizeof(union tile_address) == 4);
+
+ assert((TILE_SIZE << TILE_ADDR_BITS) >= MAX_WIDTH);
+
tc = CALLOC_STRUCT( softpipe_tile_cache );
if (tc) {
tc->pipe = pipe;
@@ -170,11 +174,11 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
tc->surface = ps;
if (ps) {
- tc->transfer = pipe_get_transfer(pipe, ps->texture, ps->face,
- ps->level, ps->zslice,
- PIPE_TRANSFER_READ_WRITE |
- PIPE_TRANSFER_UNSYNCHRONIZED,
- 0, 0, ps->width, ps->height);
+ tc->transfer = pipe_get_transfer(pipe, ps->texture,
+ ps->u.tex.level, ps->u.tex.first_layer,
+ PIPE_TRANSFER_READ_WRITE |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ 0, 0, ps->width, ps->height);
tc->depth_stencil = (ps->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
ps->format == PIPE_FORMAT_Z24X8_UNORM ||
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h
index 4151a47c32..68140b1d2f 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.h
@@ -30,6 +30,7 @@
#include "pipe/p_compiler.h"
+#include "sp_texture.h"
struct softpipe_tile_cache;
@@ -38,18 +39,22 @@ struct softpipe_tile_cache;
/**
* Cache tile size (width and height). This needs to be a power of two.
*/
-#define TILE_SIZE 64
+#define TILE_SIZE_LOG2 6
+#define TILE_SIZE (1 << TILE_SIZE_LOG2)
-/* If we need to support > 4096, just expand this to be a 64 bit
- * union, or consider tiling in Z as well.
+#define TILE_ADDR_BITS (SP_MAX_TEXTURE_2D_LEVELS - 1 - TILE_SIZE_LOG2)
+
+
+/**
+ * Surface tile address as a union for fast compares.
*/
union tile_address {
struct {
- unsigned x:6; /* 4096 / TILE_SIZE */
- unsigned y:6; /* 4096 / TILE_SIZE */
+ unsigned x:TILE_ADDR_BITS; /* 16K / TILE_SIZE */
+ unsigned y:TILE_ADDR_BITS; /* 16K / TILE_SIZE */
unsigned invalid:1;
- unsigned pad:19;
+ unsigned pad:15;
} bits;
unsigned value;
};
@@ -70,11 +75,6 @@ struct softpipe_cached_tile
#define NUM_ENTRIES 50
-/** XXX move these */
-#define MAX_WIDTH 4096
-#define MAX_HEIGHT 4096
-
-
struct softpipe_tile_cache
{
struct pipe_context *pipe;