summaryrefslogtreecommitdiff
path: root/src/mesa/pipe/softpipe
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/pipe/softpipe')
-rw-r--r--src/mesa/pipe/softpipe/Makefile3
-rw-r--r--src/mesa/pipe/softpipe/sp_clear.c41
-rw-r--r--src/mesa/pipe/softpipe/sp_context.c105
-rw-r--r--src/mesa/pipe/softpipe/sp_context.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_draw_arrays.c2
-rw-r--r--src/mesa/pipe/softpipe/sp_flush.c2
-rw-r--r--src/mesa/pipe/softpipe/sp_headers.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_quad.c3
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_depth_test.c18
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_fs.c4
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_stencil.c8
-rw-r--r--src/mesa/pipe/softpipe/sp_region.c265
-rw-r--r--src/mesa/pipe/softpipe/sp_region.h40
-rw-r--r--src/mesa/pipe/softpipe/sp_state.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_state_derived.c10
-rw-r--r--src/mesa/pipe/softpipe/sp_state_fs.c4
-rw-r--r--src/mesa/pipe/softpipe/sp_state_sampler.c5
-rw-r--r--src/mesa/pipe/softpipe/sp_state_surface.c20
-rw-r--r--src/mesa/pipe/softpipe/sp_surface.c439
-rw-r--r--src/mesa/pipe/softpipe/sp_surface.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_tex_layout.h16
-rw-r--r--src/mesa/pipe/softpipe/sp_tex_sample.c18
-rw-r--r--src/mesa/pipe/softpipe/sp_texture.c (renamed from src/mesa/pipe/softpipe/sp_tex_layout.c)220
-rw-r--r--src/mesa/pipe/softpipe/sp_texture.h57
-rw-r--r--src/mesa/pipe/softpipe/sp_tile_cache.c364
-rw-r--r--src/mesa/pipe/softpipe/sp_tile_cache.h8
26 files changed, 901 insertions, 759 deletions
diff --git a/src/mesa/pipe/softpipe/Makefile b/src/mesa/pipe/softpipe/Makefile
index 59628531cc..647cc05373 100644
--- a/src/mesa/pipe/softpipe/Makefile
+++ b/src/mesa/pipe/softpipe/Makefile
@@ -24,7 +24,6 @@ DRIVER_SOURCES = \
sp_quad_output.c \
sp_quad_stencil.c \
sp_quad_stipple.c \
- sp_region.c \
sp_state_blend.c \
sp_state_clip.c \
sp_state_derived.c \
@@ -34,7 +33,7 @@ DRIVER_SOURCES = \
sp_state_rasterizer.c \
sp_state_surface.c \
sp_state_vertex.c \
- sp_tex_layout.c \
+ sp_texture.c \
sp_tex_sample.c \
sp_tile_cache.c \
sp_surface.c
diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c
index 87f850b6fd..5b3857145d 100644
--- a/src/mesa/pipe/softpipe/sp_clear.c
+++ b/src/mesa/pipe/softpipe/sp_clear.c
@@ -47,39 +47,28 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
unsigned clearValue)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- unsigned x, y, w, h;
+ uint i;
+#if 0
softpipe_update_derived(softpipe); /* not needed?? */
+#endif
- /* Use the X coord to trick region_fill() into filling at an offset
- * from the start of the region. Perhaps pipe_region should have the
- * 'offset' field, not pipe_surface???
- */
- assert(ps->offset % ps->region->cpp == 0);
- x = ps->offset / ps->region->cpp;
- y = 0;
- w = ps->width;
- h = ps->height;
-
- assert(w <= ps->region->pitch);
- assert(h <= ps->region->height);
-
+#if TILE_CLEAR_OPTIMIZATION
if (ps == sp_tile_cache_get_surface(softpipe->zbuf_cache)) {
- float clear[4];
- clear[0] = 1.0; /* XXX hack */
- sp_tile_cache_clear(softpipe->zbuf_cache, clear);
- }
- else if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[0])) {
- float clear[4];
- clear[0] = 0.2f; /* XXX hack */
- clear[1] = 0.2f; /* XXX hack */
- clear[2] = 0.2f; /* XXX hack */
- clear[3] = 0.2f; /* XXX hack */
- sp_tile_cache_clear(softpipe->cbuf_cache[0], clear);
+ sp_tile_cache_clear(softpipe->zbuf_cache, clearValue);
+ return;
}
- pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearValue);
+ for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
+ if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) {
+ sp_tile_cache_clear(softpipe->cbuf_cache[i], clearValue);
+ return;
+ }
+ }
+#endif
+ /* non-cached surface */
+ pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
#if 0
sp_clear_tile_cache(ps, clearValue);
diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c
index d5e68c189d..df4e0cbd5a 100644
--- a/src/mesa/pipe/softpipe/sp_context.c
+++ b/src/mesa/pipe/softpipe/sp_context.c
@@ -31,16 +31,16 @@
#include "pipe/draw/draw_context.h"
#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_util.h"
#include "sp_clear.h"
#include "sp_context.h"
#include "sp_flush.h"
#include "sp_prim_setup.h"
-#include "sp_region.h"
#include "sp_state.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
-#include "sp_tex_layout.h"
+#include "sp_texture.h"
#include "sp_winsys.h"
@@ -51,7 +51,8 @@
* parameter or another function.
*/
static boolean
-softpipe_is_format_supported( struct pipe_context *pipe, uint format )
+softpipe_is_format_supported( struct pipe_context *pipe,
+ enum pipe_format format )
{
struct softpipe_context *softpipe = softpipe_context( pipe );
/* ask winsys if the format is supported */
@@ -65,44 +66,22 @@ softpipe_is_format_supported( struct pipe_context *pipe, uint format )
void
softpipe_map_surfaces(struct softpipe_context *sp)
{
- struct pipe_context *pipe = &sp->pipe;
+ struct pipe_surface *ps;
unsigned i;
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
- struct pipe_surface *ps = sp->framebuffer.cbufs[i];
- if (ps->region && !ps->region->map) {
- pipe->region_map(pipe, ps->region);
- }
+ ps = sp->framebuffer.cbufs[i];
+ if (ps->buffer)
+ pipe_surface_map(ps);
}
- if (sp->framebuffer.zbuf) {
- struct pipe_surface *ps = sp->framebuffer.zbuf;
- if (ps->region && !ps->region->map) {
- pipe->region_map(pipe, ps->region);
- }
- }
-
- if (sp->framebuffer.sbuf) {
- struct pipe_surface *ps = sp->framebuffer.sbuf;
- if (ps->region && !ps->region->map) {
- pipe->region_map(pipe, ps->region);
- }
- }
-}
-
-
-void
-softpipe_map_texture_surfaces(struct softpipe_context *sp)
-{
- struct pipe_context *pipe = &sp->pipe;
- uint i;
+ ps = sp->framebuffer.zbuf;
+ if (ps && ps->buffer)
+ pipe_surface_map(ps);
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- struct pipe_mipmap_tree *mt = sp->texture[i];
- if (mt) {
- pipe->region_map(pipe, mt->region);
- }
- }
+ ps = sp->framebuffer.sbuf;
+ if (ps && ps->buffer)
+ pipe_surface_map(ps);
}
@@ -112,45 +91,27 @@ softpipe_map_texture_surfaces(struct softpipe_context *sp)
void
softpipe_unmap_surfaces(struct softpipe_context *sp)
{
- struct pipe_context *pipe = &sp->pipe;
+ struct pipe_surface *ps;
uint i;
- for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
+ for (i = 0; i < sp->framebuffer.num_cbufs; i++)
sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
sp_flush_tile_cache(sp, sp->zbuf_cache);
sp_flush_tile_cache(sp, sp->sbuf_cache);
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
- struct pipe_surface *ps = sp->framebuffer.cbufs[i];
- if (ps->region)
- pipe->region_unmap(pipe, ps->region);
- }
-
- if (sp->framebuffer.zbuf) {
- struct pipe_surface *ps = sp->framebuffer.zbuf;
- if (ps->region)
- pipe->region_unmap(pipe, ps->region);
- }
-
- if (sp->framebuffer.sbuf && sp->framebuffer.sbuf != sp->framebuffer.zbuf) {
- struct pipe_surface *ps = sp->framebuffer.sbuf;
- if (ps->region)
- pipe->region_unmap(pipe, ps->region);
+ ps = sp->framebuffer.cbufs[i];
+ if (ps->map)
+ pipe_surface_unmap(ps);
}
-}
+ ps = sp->framebuffer.zbuf;
+ if (ps && ps->map)
+ pipe_surface_unmap(ps);
-void
-softpipe_unmap_texture_surfaces(struct softpipe_context *sp)
-{
- struct pipe_context *pipe = &sp->pipe;
- uint i;
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- struct pipe_mipmap_tree *mt = sp->texture[i];
- if (mt) {
- pipe->region_unmap(pipe, mt->region);
- }
- }
+ ps = sp->framebuffer.sbuf;
+ if (ps && ps->map)
+ pipe_surface_unmap(ps);
}
@@ -295,6 +256,8 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
/* queries */
softpipe->pipe.is_format_supported = softpipe_is_format_supported;
+ softpipe->pipe.get_name = softpipe_get_name;
+ softpipe->pipe.get_vendor = softpipe_get_vendor;
softpipe->pipe.get_param = softpipe_get_param;
softpipe->pipe.get_paramf = softpipe_get_paramf;
@@ -302,21 +265,27 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
softpipe->pipe.create_alpha_test_state = softpipe_create_alpha_test_state;
softpipe->pipe.bind_alpha_test_state = softpipe_bind_alpha_test_state;
softpipe->pipe.delete_alpha_test_state = softpipe_delete_alpha_test_state;
+
softpipe->pipe.create_blend_state = softpipe_create_blend_state;
softpipe->pipe.bind_blend_state = softpipe_bind_blend_state;
softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
+
softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
softpipe->pipe.bind_sampler_state = softpipe_bind_sampler_state;
softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
+
softpipe->pipe.create_depth_stencil_state = softpipe_create_depth_stencil_state;
softpipe->pipe.bind_depth_stencil_state = softpipe_bind_depth_stencil_state;
softpipe->pipe.delete_depth_stencil_state = softpipe_delete_depth_stencil_state;
+
softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state;
softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state;
softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state;
+
softpipe->pipe.create_fs_state = softpipe_create_fs_state;
softpipe->pipe.bind_fs_state = softpipe_bind_fs_state;
softpipe->pipe.delete_fs_state = softpipe_delete_fs_state;
+
softpipe->pipe.create_vs_state = softpipe_create_vs_state;
softpipe->pipe.bind_vs_state = softpipe_bind_vs_state;
softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;
@@ -347,11 +316,9 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
softpipe->pipe.end_query = softpipe_end_query;
softpipe->pipe.wait_query = softpipe_wait_query;
- softpipe->pipe.get_name = softpipe_get_name;
- softpipe->pipe.get_vendor = softpipe_get_vendor;
-
/* textures */
- softpipe->pipe.mipmap_tree_layout = softpipe_mipmap_tree_layout;
+ softpipe->pipe.texture_create = softpipe_texture_create;
+ softpipe->pipe.texture_release = softpipe_texture_release;
softpipe->pipe.get_tex_surface = softpipe_get_tex_surface;
/*
@@ -402,8 +369,6 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
draw_set_rasterize_stage(softpipe->draw, softpipe->setup);
}
-
- sp_init_region_functions(softpipe);
sp_init_surface_functions(softpipe);
return &softpipe->pipe;
diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h
index 872766101d..d4763a98c6 100644
--- a/src/mesa/pipe/softpipe/sp_context.h
+++ b/src/mesa/pipe/softpipe/sp_context.h
@@ -89,7 +89,7 @@ struct softpipe_context {
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
+ struct softpipe_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
diff --git a/src/mesa/pipe/softpipe/sp_draw_arrays.c b/src/mesa/pipe/softpipe/sp_draw_arrays.c
index 8a82cdfe1a..93eb68405d 100644
--- a/src/mesa/pipe/softpipe/sp_draw_arrays.c
+++ b/src/mesa/pipe/softpipe/sp_draw_arrays.c
@@ -112,7 +112,6 @@ softpipe_draw_elements(struct pipe_context *pipe,
softpipe_update_derived( sp );
softpipe_map_surfaces(sp);
- softpipe_map_texture_surfaces(sp);
softpipe_map_constant_buffers(sp);
/*
@@ -184,7 +183,6 @@ softpipe_draw_elements(struct pipe_context *pipe,
/* Note: leave drawing surfaces mapped */
- softpipe_unmap_texture_surfaces(sp);
softpipe_unmap_constant_buffers(sp);
return TRUE;
diff --git a/src/mesa/pipe/softpipe/sp_flush.c b/src/mesa/pipe/softpipe/sp_flush.c
index 1010924bf6..47b11803ce 100644
--- a/src/mesa/pipe/softpipe/sp_flush.c
+++ b/src/mesa/pipe/softpipe/sp_flush.c
@@ -55,7 +55,7 @@ softpipe_flush( struct pipe_context *pipe,
* - flush the render cache
*/
- for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
+ for (i = 0; i < softpipe->framebuffer.num_cbufs; i++)
if (softpipe->cbuf_cache[i])
sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]);
diff --git a/src/mesa/pipe/softpipe/sp_headers.h b/src/mesa/pipe/softpipe/sp_headers.h
index e23742f803..b9f2b2205a 100644
--- a/src/mesa/pipe/softpipe/sp_headers.h
+++ b/src/mesa/pipe/softpipe/sp_headers.h
@@ -31,7 +31,7 @@
#ifndef SP_HEADERS_H
#define SP_HEADERS_H
-#include "../tgsi/exec/tgsi_core.h"
+#include "pipe/tgsi/exec/tgsi_exec.h"
#define PRIM_POINT 1
#define PRIM_LINE 2
diff --git a/src/mesa/pipe/softpipe/sp_quad.c b/src/mesa/pipe/softpipe/sp_quad.c
index 5a0df6de9d..e0327c4cf9 100644
--- a/src/mesa/pipe/softpipe/sp_quad.c
+++ b/src/mesa/pipe/softpipe/sp_quad.c
@@ -27,9 +27,8 @@
#include "sp_context.h"
-
#include "sp_state.h"
-#include "pipe/tgsi/exec/tgsi_token.h"
+#include "pipe/p_shader_tokens.h"
static void
sp_push_quad_first(
diff --git a/src/mesa/pipe/softpipe/sp_quad_depth_test.c b/src/mesa/pipe/softpipe/sp_quad_depth_test.c
index 3318189621..93ea1196f9 100644
--- a/src/mesa/pipe/softpipe/sp_quad_depth_test.c
+++ b/src/mesa/pipe/softpipe/sp_quad_depth_test.c
@@ -54,7 +54,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
struct pipe_surface *ps = softpipe->framebuffer.zbuf;
- const uint format = ps->format;
+ const enum pipe_format format = ps->format;
unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */
unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */
unsigned zmask = 0;
@@ -74,7 +74,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
* Also, get the zbuffer values (bzzzz) from the cached tile.
*/
switch (format) {
- case PIPE_FORMAT_U_Z16:
+ case PIPE_FORMAT_Z16_UNORM:
{
float scale = 65535.0;
@@ -89,7 +89,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
}
}
break;
- case PIPE_FORMAT_U_Z32:
+ case PIPE_FORMAT_Z32_UNORM:
{
double scale = (double) (uint) ~0UL;
@@ -104,7 +104,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
}
}
break;
- case PIPE_FORMAT_S8_Z24:
+ case PIPE_FORMAT_S8Z24_UNORM:
{
float scale = (float) ((1 << 24) - 1);
@@ -119,7 +119,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
}
}
break;
- case PIPE_FORMAT_Z24_S8:
+ case PIPE_FORMAT_Z24S8_UNORM:
{
float scale = (float) ((1 << 24) - 1);
@@ -202,21 +202,21 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
/* put updated Z values back into cached tile */
switch (format) {
- case PIPE_FORMAT_U_Z16:
+ case PIPE_FORMAT_Z16_UNORM:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
tile->data.depth16[y][x] = (ushort) bzzzz[j];
}
break;
- case PIPE_FORMAT_U_Z32:
+ case PIPE_FORMAT_Z32_UNORM:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
tile->data.depth32[y][x] = bzzzz[j];
}
break;
- case PIPE_FORMAT_S8_Z24:
+ case PIPE_FORMAT_S8Z24_UNORM:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
@@ -225,7 +225,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
tile->data.depth32[y][x] = s8z24;
}
break;
- case PIPE_FORMAT_Z24_S8:
+ case PIPE_FORMAT_Z24S8_UNORM:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c
index ed14dac18e..1aba54d12a 100644
--- a/src/mesa/pipe/softpipe/sp_quad_fs.c
+++ b/src/mesa/pipe/softpipe/sp_quad_fs.c
@@ -37,6 +37,7 @@
#include "pipe/p_util.h"
#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
#include "x86/rtasm/x86sse.h"
@@ -48,6 +49,7 @@
#include "sp_state.h"
#include "sp_headers.h"
#include "sp_quad.h"
+#include "sp_texture.h"
#include "sp_tex_sample.h"
@@ -276,7 +278,7 @@ static void shade_begin(struct quad_stage *qs)
/* set TGSI sampler state that varies */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
qss->samplers[i].state = softpipe->sampler[i];
- qss->samplers[i].texture = softpipe->texture[i];
+ qss->samplers[i].texture = &softpipe->texture[i]->base;
}
#ifdef MESA_LLVM
diff --git a/src/mesa/pipe/softpipe/sp_quad_stencil.c b/src/mesa/pipe/softpipe/sp_quad_stencil.c
index 0149b20f48..b8c199204d 100644
--- a/src/mesa/pipe/softpipe/sp_quad_stencil.c
+++ b/src/mesa/pipe/softpipe/sp_quad_stencil.c
@@ -234,14 +234,14 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
/* get stencil values from cached tile */
switch (ps->format) {
- case PIPE_FORMAT_S8_Z24:
+ case PIPE_FORMAT_S8Z24_UNORM:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
stencilVals[j] = tile->data.depth32[y][x] >> 24;
}
break;
- case PIPE_FORMAT_Z24_S8:
+ case PIPE_FORMAT_Z24S8_UNORM:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
@@ -298,7 +298,7 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
/* put new stencil values into cached tile */
switch (ps->format) {
- case PIPE_FORMAT_S8_Z24:
+ case PIPE_FORMAT_S8Z24_UNORM:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
@@ -307,7 +307,7 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
tile->data.depth32[y][x] = s8z24;
}
break;
- case PIPE_FORMAT_Z24_S8:
+ case PIPE_FORMAT_Z24S8_UNORM:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
diff --git a/src/mesa/pipe/softpipe/sp_region.c b/src/mesa/pipe/softpipe/sp_region.c
deleted file mode 100644
index fef63ef2f6..0000000000
--- a/src/mesa/pipe/softpipe/sp_region.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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 TUNGSTEN GRAPHICS 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.
- *
- **************************************************************************/
-
-/* Provide additional functionality on top of bufmgr buffers:
- * - 2d semantics and blit operations (XXX: remove/simplify blits??)
- * - refcounting of buffers for multiple images in a buffer.
- * - refcounting of buffer mappings.
- */
-
-#include "sp_context.h"
-#include "sp_region.h"
-#include "pipe/p_util.h"
-#include "pipe/p_winsys.h"
-#include "pipe/p_defines.h"
-
-
-
-static ubyte *
-sp_region_map(struct pipe_context *pipe, struct pipe_region *region)
-{
- struct softpipe_context *sp = softpipe_context( pipe );
-
- if (!region->map_refcount++) {
- region->map = sp->pipe.winsys->buffer_map( sp->pipe.winsys,
- region->buffer,
- PIPE_BUFFER_FLAG_WRITE |
- PIPE_BUFFER_FLAG_READ);
- }
-
- return region->map;
-}
-
-static void
-sp_region_unmap(struct pipe_context *pipe, struct pipe_region *region)
-{
- struct softpipe_context *sp = softpipe_context( pipe );
-
- if (region->map_refcount > 0) {
- assert(region->map);
- if (!--region->map_refcount) {
- sp->pipe.winsys->buffer_unmap( sp->pipe.winsys,
- region->buffer );
- region->map = NULL;
- }
- }
-}
-
-
-
-/**
- * Copy 2D rect from one place to another.
- * Position and sizes are in pixels.
- */
-static void
-copy_rect(ubyte * dst,
- unsigned cpp,
- unsigned dst_pitch,
- unsigned dst_x,
- unsigned dst_y,
- unsigned width,
- unsigned height,
- const ubyte * src,
- unsigned src_pitch,
- unsigned src_x,
- unsigned src_y)
-{
- unsigned i;
-
- dst_pitch *= cpp;
- src_pitch *= cpp;
- dst += dst_x * cpp;
- src += src_x * cpp;
- dst += dst_y * dst_pitch;
- src += src_y * src_pitch;
- width *= cpp;
-
- if (width == dst_pitch && width == src_pitch)
- memcpy(dst, src, height * width);
- else {
- for (i = 0; i < height; i++) {
- memcpy(dst, src, width);
- dst += dst_pitch;
- src += src_pitch;
- }
- }
-}
-
-
-/* Upload data to a rectangular sub-region. Lots of choices how to do this:
- *
- * - memcpy by span to current destination
- * - upload data as new buffer and blit
- *
- * Currently always memcpy.
- */
-static void
-sp_region_data(struct pipe_context *pipe,
- struct pipe_region *dst,
- unsigned dst_offset,
- unsigned dstx, unsigned dsty,
- const void *src, unsigned src_pitch,
- unsigned srcx, unsigned srcy, unsigned width, unsigned height)
-{
- copy_rect(pipe->region_map(pipe, dst) + dst_offset,
- dst->cpp,
- dst->pitch,
- dstx, dsty, width, height, src, src_pitch, srcx, srcy);
-
- pipe->region_unmap(pipe, dst);
-}
-
-/* Assumes all values are within bounds -- no checking at this level -
- * do it higher up if required.
- */
-static void
-sp_region_copy(struct pipe_context *pipe,
- struct pipe_region *dst,
- unsigned dst_offset,
- unsigned dstx, unsigned dsty,
- struct pipe_region *src,
- unsigned src_offset,
- unsigned srcx, unsigned srcy, unsigned width, unsigned height)
-{
- ubyte *src_map, *dst_map;
- assert( dst->cpp == src->cpp );
-
- dst_map = pipe->region_map(pipe, dst);
- src_map = pipe->region_map(pipe, src);
- copy_rect(dst_map + dst_offset,
- dst->cpp,
- dst->pitch,
- dstx, dsty,
- width, height,
- src_map + src_offset,
- src->pitch,
- srcx, srcy);
-
- pipe->region_unmap(pipe, src);
- pipe->region_unmap(pipe, dst);
-}
-
-
-static ubyte *
-get_pointer(struct pipe_region *dst, unsigned x, unsigned y)
-{
- return dst->map + (y * dst->pitch + x) * dst->cpp;
-}
-
-
-#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
-
-
-/**
- * Fill a rectangular sub-region. Need better logic about when to
- * push buffers into AGP - will currently do so whenever possible.
- */
-static void
-sp_region_fill(struct pipe_context *pipe,
- struct pipe_region *dst,
- unsigned dst_offset,
- unsigned dstx, unsigned dsty,
- unsigned width, unsigned height, unsigned value)
-{
- unsigned i, j;
-
- assert(dst->pitch > 0);
- assert(width <= dst->pitch);
-
- (void)pipe->region_map(pipe, dst);
-
- switch (dst->cpp) {
- case 1:
- {
- ubyte *row = get_pointer(dst, dstx, dsty);
- for (i = 0; i < height; i++) {
- memset(row, value, width);
- row += dst->pitch;
- }
- }
- break;
- case 2:
- {
- ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++)
- row[j] = (ushort) value;
- row += dst->pitch;
- }
- }
- break;
- case 4:
- {
- unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty);
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++)
- row[j] = value;
- row += dst->pitch;
- }
- }
- break;
- case 8:
- {
- /* expand the 4-byte clear value to an 8-byte value */
- ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
- ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff);
- ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff);
- ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
- ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- row[j*4+0] = val0;
- row[j*4+1] = val1;
- row[j*4+2] = val2;
- row[j*4+3] = val3;
- }
- row += dst->pitch * 4;
- }
- }
- break;
- default:
- assert(0);
- break;
- }
-
- pipe->region_unmap( pipe, dst );
-}
-
-
-
-
-
-void
-sp_init_region_functions(struct softpipe_context *sp)
-{
- sp->pipe.region_map = sp_region_map;
- sp->pipe.region_unmap = sp_region_unmap;
- sp->pipe.region_data = sp_region_data;
- sp->pipe.region_copy = sp_region_copy;
- sp->pipe.region_fill = sp_region_fill;
-}
-
diff --git a/src/mesa/pipe/softpipe/sp_region.h b/src/mesa/pipe/softpipe/sp_region.h
deleted file mode 100644
index 432746b27f..0000000000
--- a/src/mesa/pipe/softpipe/sp_region.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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 TUNGSTEN GRAPHICS 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_REGION_H
-#define SP_REGION_H
-
-
-struct softpipe_context;
-
-
-extern void
-sp_init_region_functions(struct softpipe_context *sp);
-
-
-#endif /* SP_REGION_H */
diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h
index 2f096a9cc9..ea9d2e62be 100644
--- a/src/mesa/pipe/softpipe/sp_state.h
+++ b/src/mesa/pipe/softpipe/sp_state.h
@@ -125,7 +125,7 @@ void softpipe_set_scissor_state( struct pipe_context *,
void softpipe_set_texture_state( struct pipe_context *,
unsigned unit,
- struct pipe_mipmap_tree * );
+ struct pipe_texture * );
void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c
index 81f70f0f24..c4f1a0a01a 100644
--- a/src/mesa/pipe/softpipe/sp_state_derived.c
+++ b/src/mesa/pipe/softpipe/sp_state_derived.c
@@ -26,15 +26,12 @@
**************************************************************************/
#include "pipe/p_util.h"
-
+#include "pipe/p_shader_tokens.h"
#include "pipe/draw/draw_context.h"
#include "pipe/draw/draw_vertex.h"
-
#include "sp_context.h"
#include "sp_state.h"
-#include "pipe/tgsi/exec/tgsi_token.h"
-
/**
* Determine which post-transform / pre-rasterization vertex attributes
@@ -156,10 +153,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
if (1/*vinfo->attr_mask != softpipe->attr_mask*/) {
/*softpipe->attr_mask = vinfo->attr_mask;*/
- draw_set_vertex_attributes( softpipe->draw,
- NULL,/*vinfo->slot_to_attrib,*/
- vinfo->interp_mode,
- vinfo->num_attribs);
+ draw_set_vertex_info( softpipe->draw, vinfo);
draw_set_twoside_attributes(softpipe->draw,
front0, back0, front1, back1);
diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c
index ba564b16e6..a360b4f02b 100644
--- a/src/mesa/pipe/softpipe/sp_state_fs.c
+++ b/src/mesa/pipe/softpipe/sp_state_fs.c
@@ -32,8 +32,10 @@
#include "pipe/p_util.h"
#include "pipe/p_winsys.h"
#include "pipe/draw/draw_context.h"
-#include "pipe/tgsi/exec/tgsi_core.h"
+#include "pipe/p_shader_tokens.h"
#include "pipe/llvm/gallivm.h"
+#include "pipe/tgsi/util/tgsi_dump.h"
+#include "pipe/tgsi/exec/tgsi_sse2.h"
void * softpipe_create_fs_state(struct pipe_context *pipe,
diff --git a/src/mesa/pipe/softpipe/sp_state_sampler.c b/src/mesa/pipe/softpipe/sp_state_sampler.c
index 246a7d6eda..173901f04e 100644
--- a/src/mesa/pipe/softpipe/sp_state_sampler.c
+++ b/src/mesa/pipe/softpipe/sp_state_sampler.c
@@ -32,6 +32,7 @@
#include "pipe/p_util.h"
#include "sp_context.h"
#include "sp_state.h"
+#include "sp_texture.h"
#include "sp_tile_cache.h"
@@ -68,12 +69,12 @@ softpipe_delete_sampler_state(struct pipe_context *pipe,
void
softpipe_set_texture_state(struct pipe_context *pipe,
unsigned unit,
- struct pipe_mipmap_tree *texture)
+ struct pipe_texture *texture)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
assert(unit < PIPE_MAX_SAMPLERS);
- softpipe->texture[unit] = texture; /* ptr, not struct */
+ softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */
sp_tile_cache_set_texture(softpipe->tex_cache[unit], texture);
diff --git a/src/mesa/pipe/softpipe/sp_state_surface.c b/src/mesa/pipe/softpipe/sp_state_surface.c
index d4e0bd1e15..30bedc74bc 100644
--- a/src/mesa/pipe/softpipe/sp_state_surface.c
+++ b/src/mesa/pipe/softpipe/sp_state_surface.c
@@ -27,6 +27,8 @@
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
*/
+#include "p_inlines.h"
+
#include "sp_context.h"
#include "sp_state.h"
#include "sp_surface.h"
@@ -54,12 +56,12 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
/* unmap old */
ps = sp->framebuffer.cbufs[i];
- if (ps && ps->region)
- pipe->region_unmap(pipe, ps->region);
+ if (ps && ps->map)
+ pipe_surface_unmap(ps);
/* map new */
ps = fb->cbufs[i];
if (ps)
- pipe->region_map(pipe, ps->region);
+ pipe_surface_map(ps);
/* assign new */
sp->framebuffer.cbufs[i] = fb->cbufs[i];
@@ -76,8 +78,8 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
sp_flush_tile_cache(sp, sp->zbuf_cache);
/* unmap old */
ps = sp->framebuffer.zbuf;
- if (ps && ps->region)
- pipe->region_unmap(pipe, ps->region);
+ if (ps && ps->map)
+ pipe_surface_unmap(ps);
if (sp->framebuffer.sbuf == sp->framebuffer.zbuf) {
/* combined z/stencil */
sp->framebuffer.sbuf = NULL;
@@ -85,7 +87,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
/* map new */
ps = fb->zbuf;
if (ps)
- pipe->region_map(pipe, ps->region);
+ pipe_surface_map(ps);
/* assign new */
sp->framebuffer.zbuf = fb->zbuf;
@@ -101,12 +103,12 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
sp_flush_tile_cache(sp, sp->sbuf_cache_sep);
/* unmap old */
ps = sp->framebuffer.sbuf;
- if (ps && ps->region)
- pipe->region_unmap(pipe, ps->region);
+ if (ps && ps->map)
+ pipe_surface_unmap(ps);
/* map new */
ps = fb->sbuf;
if (ps && fb->sbuf != fb->zbuf)
- pipe->region_map(pipe, ps->region);
+ pipe_surface_map(ps);
/* assign new */
sp->framebuffer.sbuf = fb->sbuf;
diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c
index b7c9d4f004..55b8b85ef2 100644
--- a/src/mesa/pipe/softpipe/sp_surface.c
+++ b/src/mesa/pipe/softpipe/sp_surface.c
@@ -30,9 +30,9 @@
#include "pipe/p_inlines.h"
#include "pipe/p_winsys.h"
#include "sp_context.h"
-#include "sp_state.h"
#include "sp_surface.h"
-#include "sp_tile_cache.h"
+#include "sp_texture.h"
+
/**
* Softpipe surface functions.
@@ -47,14 +47,6 @@
-#if 0
-#define CLIP_TILE \
- do { \
- assert(x + w <= ps->width); \
- assert(y + h <= ps->height); \
- } while(0)
-
-#else
#define CLIP_TILE \
do { \
if (x >= ps->width) \
@@ -64,24 +56,23 @@
if (x + w > ps->width) \
w = ps->width - x; \
if (y + h > ps->height) \
- h = ps->height -y; \
+ h = ps->height - y; \
} while(0)
-#endif
-/*** PIPE_FORMAT_U_A8_R8_G8_B8 ***/
+/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
static void
a8r8g8b8_get_tile(struct pipe_surface *ps,
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
{
const unsigned *src
- = ((const unsigned *) (ps->region->map + ps->offset))
- + y * ps->region->pitch + x;
+ = ((const unsigned *) (ps->map))
+ + y * ps->pitch + x;
unsigned i, j;
unsigned w0 = w;
- assert(ps->format == PIPE_FORMAT_U_A8_R8_G8_B8);
+ assert(ps->format == PIPE_FORMAT_A8R8G8B8_UNORM);
CLIP_TILE;
@@ -95,7 +86,7 @@ a8r8g8b8_get_tile(struct pipe_surface *ps,
pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
pRow += 4;
}
- src += ps->region->pitch;
+ src += ps->pitch;
p += w0 * 4;
}
}
@@ -107,12 +98,12 @@ a8r8g8b8_put_tile(struct pipe_surface *ps,
const float *p)
{
unsigned *dst
- = ((unsigned *) (ps->region->map + ps->offset))
- + y * ps->region->pitch + x;
+ = ((unsigned *) (ps->map))
+ + y * ps->pitch + x;
unsigned i, j;
unsigned w0 = w;
- assert(ps->format == PIPE_FORMAT_U_A8_R8_G8_B8);
+ assert(ps->format == PIPE_FORMAT_A8R8G8B8_UNORM);
CLIP_TILE;
@@ -127,24 +118,88 @@ a8r8g8b8_put_tile(struct pipe_surface *ps,
dst[j] = (a << 24) | (r << 16) | (g << 8) | b;
pRow += 4;
}
- dst += ps->region->pitch;
+ dst += ps->pitch;
p += w0 * 4;
}
}
-/*** PIPE_FORMAT_U_A1_R5_G5_B5 ***/
+/*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
+
+static void
+b8g8r8a8_get_tile(struct pipe_surface *ps,
+ unsigned x, unsigned y, unsigned w, unsigned h, float *p)
+{
+ const unsigned *src
+ = ((const unsigned *) (ps->map))
+ + y * ps->pitch + x;
+ unsigned i, j;
+ unsigned w0 = w;
+
+ assert(ps->format == PIPE_FORMAT_B8G8R8A8_UNORM);
+
+ CLIP_TILE;
+
+ for (i = 0; i < h; i++) {
+ float *pRow = p;
+ for (j = 0; j < w; j++) {
+ const unsigned pixel = src[j];
+ pRow[0] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
+ pRow[1] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
+ pRow[2] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
+ pRow[3] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
+ pRow += 4;
+ }
+ src += ps->pitch;
+ p += w0 * 4;
+ }
+}
+
+
+static void
+b8g8r8a8_put_tile(struct pipe_surface *ps,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ const float *p)
+{
+ unsigned *dst
+ = ((unsigned *) (ps->map))
+ + y * ps->pitch + x;
+ unsigned i, j;
+ unsigned w0 = w;
+
+ assert(ps->format == PIPE_FORMAT_B8G8R8A8_UNORM);
+
+ CLIP_TILE;
+
+ for (i = 0; i < h; i++) {
+ const float *pRow = p;
+ for (j = 0; j < w; j++) {
+ unsigned r, g, b, a;
+ UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
+ UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
+ UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
+ UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]);
+ dst[j] = (b << 24) | (g << 16) | (r << 8) | a;
+ pRow += 4;
+ }
+ dst += ps->pitch;
+ p += w0 * 4;
+ }
+}
+
+
+/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/
static void
a1r5g5b5_get_tile(struct pipe_surface *ps,
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
{
const ushort *src
- = ((const ushort *) (ps->region->map + ps->offset))
- + y * ps->region->pitch + x;
+ = ((const ushort *) (ps->map))
+ + y * ps->pitch + x;
unsigned i, j;
- assert(ps->format == PIPE_FORMAT_U_A1_R5_G5_B5);
+ assert(ps->format == PIPE_FORMAT_A1R5G5B5_UNORM);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
@@ -155,13 +210,13 @@ a1r5g5b5_get_tile(struct pipe_surface *ps,
p[3] = ((pixel >> 15) ) * 1.0f;
p += 4;
}
- src += ps->region->pitch;
+ src += ps->pitch;
}
}
-/*** PIPE_FORMAT_U_Z16 ***/
+/*** PIPE_FORMAT_Z16_UNORM ***/
/**
* Return each Z value as four floats in [0,1].
@@ -171,13 +226,13 @@ z16_get_tile(struct pipe_surface *ps,
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
{
const ushort *src
- = ((const ushort *) (ps->region->map + ps->offset))
- + y * ps->region->pitch + x;
+ = ((const ushort *) (ps->map))
+ + y * ps->pitch + x;
const float scale = 1.0f / 65535.0f;
unsigned i, j;
unsigned w0 = w;
- assert(ps->format == PIPE_FORMAT_U_Z16);
+ assert(ps->format == PIPE_FORMAT_Z16_UNORM);
CLIP_TILE;
@@ -189,7 +244,7 @@ z16_get_tile(struct pipe_surface *ps,
pRow[j * 4 + 2] =
pRow[j * 4 + 3] = src[j] * scale;
}
- src += ps->region->pitch;
+ src += ps->pitch;
p += 4 * w0;
}
}
@@ -204,8 +259,8 @@ l8_get_tile(struct pipe_surface *ps,
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
{
const ubyte *src
- = ((const ubyte *) (ps->region->map + ps->offset))
- + y * ps->region->pitch + x;
+ = ((const ubyte *) (ps->map))
+ + y * ps->pitch + x;
unsigned i, j;
unsigned w0 = w;
@@ -222,7 +277,7 @@ l8_get_tile(struct pipe_surface *ps,
pRow[3] = 1.0;
pRow += 4;
}
- src += ps->region->pitch;
+ src += ps->pitch;
p += w0 * 4;
}
}
@@ -235,8 +290,8 @@ a8_get_tile(struct pipe_surface *ps,
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
{
const ubyte *src
- = ((const ubyte *) (ps->region->map + ps->offset))
- + y * ps->region->pitch + x;
+ = ((const ubyte *) (ps->map))
+ + y * ps->pitch + x;
unsigned i, j;
unsigned w0 = w;
@@ -253,25 +308,25 @@ a8_get_tile(struct pipe_surface *ps,
pRow[3] = UBYTE_TO_FLOAT(src[j]);
pRow += 4;
}
- src += ps->region->pitch;
+ src += ps->pitch;
p += w0 * 4;
}
}
-/*** PIPE_FORMAT_S_R16_G16_B16_A16 ***/
+/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
static void
r16g16b16a16_get_tile(struct pipe_surface *ps,
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
{
const short *src
- = ((const short *) (ps->region->map + ps->offset))
- + (y * ps->region->pitch + x) * 4;
+ = ((const short *) (ps->map))
+ + (y * ps->pitch + x) * 4;
unsigned i, j;
unsigned w0 = w;
- assert(ps->format == PIPE_FORMAT_S_R16_G16_B16_A16);
+ assert(ps->format == PIPE_FORMAT_R16G16B16A16_SNORM);
CLIP_TILE;
@@ -286,7 +341,7 @@ r16g16b16a16_get_tile(struct pipe_surface *ps,
pRow += 4;
pixel += 4;
}
- src += ps->region->pitch * 4;
+ src += ps->pitch * 4;
p += w0 * 4;
}
}
@@ -298,12 +353,12 @@ r16g16b16a16_put_tile(struct pipe_surface *ps,
const float *p)
{
short *dst
- = ((short *) (ps->region->map + ps->offset))
- + (y * ps->region->pitch + x) * 4;
+ = ((short *) (ps->map))
+ + (y * ps->pitch + x) * 4;
unsigned i, j;
unsigned w0 = w;
- assert(ps->format == PIPE_FORMAT_S_R16_G16_B16_A16);
+ assert(ps->format == PIPE_FORMAT_R16G16B16A16_SNORM);
CLIP_TILE;
@@ -321,7 +376,7 @@ r16g16b16a16_put_tile(struct pipe_surface *ps,
dst[j*4+3] = a;
pRow += 4;
}
- dst += ps->region->pitch * 4;
+ dst += ps->pitch * 4;
p += w0 * 4;
}
}
@@ -335,8 +390,8 @@ i8_get_tile(struct pipe_surface *ps,
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
{
const ubyte *src
- = ((const ubyte *) (ps->region->map + ps->offset))
- + y * ps->region->pitch + x;
+ = ((const ubyte *) (ps->map))
+ + y * ps->pitch + x;
unsigned i, j;
unsigned w0 = w;
@@ -353,7 +408,7 @@ i8_get_tile(struct pipe_surface *ps,
pRow[3] = UBYTE_TO_FLOAT(src[j]);
pRow += 4;
}
- src += ps->region->pitch;
+ src += ps->pitch;
p += w0 * 4;
}
}
@@ -366,8 +421,8 @@ a8_l8_get_tile(struct pipe_surface *ps,
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
{
const ushort *src
- = ((const ushort *) (ps->region->map + ps->offset))
- + y * ps->region->pitch + x;
+ = ((const ushort *) (ps->map))
+ + y * ps->pitch + x;
unsigned i, j;
unsigned w0 = w;
@@ -385,7 +440,7 @@ a8_l8_get_tile(struct pipe_surface *ps,
pRow[3] = UBYTE_TO_FLOAT(p >> 8);
pRow += 4;
}
- src += ps->region->pitch;
+ src += ps->pitch;
p += w0 * 4;
}
}
@@ -393,7 +448,7 @@ a8_l8_get_tile(struct pipe_surface *ps,
-/*** PIPE_FORMAT_U_Z32 ***/
+/*** PIPE_FORMAT_Z32_UNORM ***/
/**
* Return each Z value as four floats in [0,1].
@@ -403,13 +458,13 @@ z32_get_tile(struct pipe_surface *ps,
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
{
const uint *src
- = ((const uint *) (ps->region->map + ps->offset))
- + y * ps->region->pitch + x;
+ = ((const uint *) (ps->map))
+ + y * ps->pitch + x;
const double scale = 1.0 / (double) 0xffffffff;
unsigned i, j;
unsigned w0 = w;
- assert(ps->format == PIPE_FORMAT_U_Z16);
+ assert(ps->format == PIPE_FORMAT_Z16_UNORM);
CLIP_TILE;
@@ -421,13 +476,13 @@ z32_get_tile(struct pipe_surface *ps,
pRow[j * 4 + 2] =
pRow[j * 4 + 3] = (float) (scale * src[j]);
}
- src += ps->region->pitch;
+ src += ps->pitch;
p += 4 * w0;
}
}
-/*** PIPE_FORMAT_S8_Z24 ***/
+/*** PIPE_FORMAT_S8Z24_UNORM ***/
/**
* Return Z component as four float in [0,1]. Stencil part ignored.
@@ -437,13 +492,13 @@ s8z24_get_tile(struct pipe_surface *ps,
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
{
const uint *src
- = ((const uint *) (ps->region->map + ps->offset))
- + y * ps->region->pitch + x;
+ = ((const uint *) (ps->map))
+ + y * ps->pitch + x;
const double scale = 1.0 / ((1 << 24) - 1);
unsigned i, j;
unsigned w0 = w;
- assert(ps->format == PIPE_FORMAT_S8_Z24);
+ assert(ps->format == PIPE_FORMAT_S8Z24_UNORM);
CLIP_TILE;
@@ -455,13 +510,13 @@ s8z24_get_tile(struct pipe_surface *ps,
pRow[j * 4 + 2] =
pRow[j * 4 + 3] = (float) (scale * (src[j] & 0xffffff));
}
- src += ps->region->pitch;
+ src += ps->pitch;
p += 4 * w0;
}
}
-/*** PIPE_FORMAT_Z24_S8 ***/
+/*** PIPE_FORMAT_Z24S8_UNORM ***/
/**
* Return Z component as four float in [0,1]. Stencil part ignored.
@@ -471,13 +526,13 @@ z24s8_get_tile(struct pipe_surface *ps,
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
{
const uint *src
- = ((const uint *) (ps->region->map + ps->offset))
- + y * ps->region->pitch + x;
+ = ((const uint *) (ps->map))
+ + y * ps->pitch + x;
const double scale = 1.0 / ((1 << 24) - 1);
unsigned i, j;
unsigned w0 = w;
- assert(ps->format == PIPE_FORMAT_Z24_S8);
+ assert(ps->format == PIPE_FORMAT_Z24S8_UNORM);
CLIP_TILE;
@@ -489,7 +544,7 @@ z24s8_get_tile(struct pipe_surface *ps,
pRow[j * 4 + 2] =
pRow[j * 4 + 3] = (float) (scale * (src[j] >> 8));
}
- src += ps->region->pitch;
+ src += ps->pitch;
p += 4 * w0;
}
}
@@ -501,32 +556,35 @@ z24s8_get_tile(struct pipe_surface *ps,
*/
struct pipe_surface *
softpipe_get_tex_surface(struct pipe_context *pipe,
- struct pipe_mipmap_tree *mt,
+ struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice)
{
+ struct softpipe_texture *spt = softpipe_texture(pt);
struct pipe_surface *ps;
unsigned offset; /* in bytes */
- offset = mt->level[level].level_offset;
+ offset = spt->level_offset[level];
- if (mt->target == PIPE_TEXTURE_CUBE) {
- offset += mt->level[level].image_offset[face] * mt->cpp;
+ if (pt->target == PIPE_TEXTURE_CUBE) {
+ offset += spt->image_offset[level][face] * pt->cpp;
}
- else if (mt->target == PIPE_TEXTURE_3D) {
- offset += mt->level[level].image_offset[zslice] * mt->cpp;
+ else if (pt->target == PIPE_TEXTURE_3D) {
+ offset += spt->image_offset[level][zslice] * pt->cpp;
}
else {
assert(face == 0);
assert(zslice == 0);
}
- ps = pipe->winsys->surface_alloc(pipe->winsys, mt->format);
+ ps = pipe->winsys->surface_alloc(pipe->winsys, pt->format);
if (ps) {
assert(ps->format);
assert(ps->refcount);
- pipe_region_reference(&ps->region, mt->region);
- ps->width = mt->level[level].width;
- ps->height = mt->level[level].height;
+ pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, spt->buffer);
+ ps->cpp = pt->cpp;
+ ps->width = pt->width[level];
+ ps->height = pt->height[level];
+ ps->pitch = spt->pitch;
ps->offset = offset;
}
return ps;
@@ -541,12 +599,13 @@ softpipe_get_tile(struct pipe_context *pipe, struct pipe_surface *ps,
uint x, uint y, uint w, uint h,
void *p, int dst_stride)
{
- const uint cpp = ps->region->cpp;
+ const uint cpp = ps->cpp;
const ubyte *pSrc;
+ const uint src_stride = ps->pitch * cpp;
ubyte *pDest;
uint i;
- assert(ps->region->map);
+ assert(ps->map);
if (dst_stride == 0) {
dst_stride = w * cpp;
@@ -554,13 +613,13 @@ softpipe_get_tile(struct pipe_context *pipe, struct pipe_surface *ps,
CLIP_TILE;
- pSrc = ps->region->map + ps->offset + (y * ps->region->pitch + x) * cpp;
+ pSrc = ps->map + (y * ps->pitch + x) * cpp;
pDest = (ubyte *) p;
for (i = 0; i < h; i++) {
memcpy(pDest, pSrc, w * cpp);
pDest += dst_stride;
- pSrc += ps->region->pitch * cpp;
+ pSrc += src_stride;
}
}
@@ -573,12 +632,13 @@ softpipe_put_tile(struct pipe_context *pipe, struct pipe_surface *ps,
uint x, uint y, uint w, uint h,
const void *p, int src_stride)
{
- const uint cpp = ps->region->cpp;
+ const uint cpp = ps->cpp;
const ubyte *pSrc;
+ const uint dst_stride = ps->pitch * cpp;
ubyte *pDest;
uint i;
- assert(ps->region->map);
+ assert(ps->map);
if (src_stride == 0) {
src_stride = w * cpp;
@@ -587,11 +647,11 @@ softpipe_put_tile(struct pipe_context *pipe, struct pipe_surface *ps,
CLIP_TILE;
pSrc = (const ubyte *) p;
- pDest = ps->region->map + ps->offset + (y * ps->region->pitch + x) * cpp;
+ pDest = ps->map + (y * ps->pitch + x) * cpp;
for (i = 0; i < h; i++) {
memcpy(pDest, pSrc, w * cpp);
- pDest += ps->region->pitch * cpp;
+ pDest += dst_stride;
pSrc += src_stride;
}
}
@@ -605,10 +665,13 @@ softpipe_get_tile_rgba(struct pipe_context *pipe,
float *p)
{
switch (ps->format) {
- case PIPE_FORMAT_U_A8_R8_G8_B8:
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
a8r8g8b8_get_tile(ps, x, y, w, h, p);
break;
- case PIPE_FORMAT_U_A1_R5_G5_B5:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ b8g8r8a8_get_tile(ps, x, y, w, h, p);
+ break;
+ case PIPE_FORMAT_A1R5G5B5_UNORM:
a1r5g5b5_get_tile(ps, x, y, w, h, p);
break;
case PIPE_FORMAT_U_L8:
@@ -623,19 +686,19 @@ softpipe_get_tile_rgba(struct pipe_context *pipe,
case PIPE_FORMAT_U_A8_L8:
a8_l8_get_tile(ps, x, y, w, h, p);
break;
- case PIPE_FORMAT_S_R16_G16_B16_A16:
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
r16g16b16a16_get_tile(ps, x, y, w, h, p);
break;
- case PIPE_FORMAT_U_Z16:
+ case PIPE_FORMAT_Z16_UNORM:
z16_get_tile(ps, x, y, w, h, p);
break;
- case PIPE_FORMAT_U_Z32:
+ case PIPE_FORMAT_Z32_UNORM:
z32_get_tile(ps, x, y, w, h, p);
break;
- case PIPE_FORMAT_S8_Z24:
+ case PIPE_FORMAT_S8Z24_UNORM:
s8z24_get_tile(ps, x, y, w, h, p);
break;
- case PIPE_FORMAT_Z24_S8:
+ case PIPE_FORMAT_Z24S8_UNORM:
z24s8_get_tile(ps, x, y, w, h, p);
break;
default:
@@ -652,10 +715,13 @@ softpipe_put_tile_rgba(struct pipe_context *pipe,
const float *p)
{
switch (ps->format) {
- case PIPE_FORMAT_U_A8_R8_G8_B8:
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
a8r8g8b8_put_tile(ps, x, y, w, h, p);
break;
- case PIPE_FORMAT_U_A1_R5_G5_B5:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ b8g8r8a8_put_tile(ps, x, y, w, h, p);
+ break;
+ case PIPE_FORMAT_A1R5G5B5_UNORM:
/*a1r5g5b5_put_tile(ps, x, y, w, h, p);*/
break;
case PIPE_FORMAT_U_L8:
@@ -670,19 +736,19 @@ softpipe_put_tile_rgba(struct pipe_context *pipe,
case PIPE_FORMAT_U_A8_L8:
/*a8_l8_put_tile(ps, x, y, w, h, p);*/
break;
- case PIPE_FORMAT_S_R16_G16_B16_A16:
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
r16g16b16a16_put_tile(ps, x, y, w, h, p);
break;
- case PIPE_FORMAT_U_Z16:
+ case PIPE_FORMAT_Z16_UNORM:
/*z16_put_tile(ps, x, y, w, h, p);*/
break;
- case PIPE_FORMAT_U_Z32:
+ case PIPE_FORMAT_Z32_UNORM:
/*z32_put_tile(ps, x, y, w, h, p);*/
break;
- case PIPE_FORMAT_S8_Z24:
+ case PIPE_FORMAT_S8Z24_UNORM:
/*s8z24_put_tile(ps, x, y, w, h, p);*/
break;
- case PIPE_FORMAT_Z24_S8:
+ case PIPE_FORMAT_Z24S8_UNORM:
/*z24s8_put_tile(ps, x, y, w, h, p);*/
break;
default:
@@ -691,6 +757,177 @@ softpipe_put_tile_rgba(struct pipe_context *pipe,
}
+/**
+ * Copy 2D rect from one place to another.
+ * Position and sizes are in pixels.
+ */
+static void
+copy_rect(ubyte * dst,
+ unsigned cpp,
+ unsigned dst_pitch,
+ unsigned dst_x,
+ unsigned dst_y,
+ unsigned width,
+ unsigned height,
+ const ubyte * src,
+ unsigned src_pitch,
+ unsigned src_x,
+ unsigned src_y)
+{
+ unsigned i;
+
+ dst_pitch *= cpp;
+ src_pitch *= cpp;
+ dst += dst_x * cpp;
+ src += src_x * cpp;
+ dst += dst_y * dst_pitch;
+ src += src_y * src_pitch;
+ width *= cpp;
+
+ if (width == dst_pitch && width == src_pitch)
+ memcpy(dst, src, height * width);
+ else {
+ for (i = 0; i < height; i++) {
+ memcpy(dst, src, width);
+ dst += dst_pitch;
+ src += src_pitch;
+ }
+ }
+}
+
+
+/* Upload data to a rectangular sub-region. Lots of choices how to do this:
+ *
+ * - memcpy by span to current destination
+ * - upload data as new buffer and blit
+ *
+ * Currently always memcpy.
+ */
+static void
+sp_surface_data(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ const void *src, unsigned src_pitch,
+ unsigned srcx, unsigned srcy, unsigned width, unsigned height)
+{
+ copy_rect(pipe_surface_map(dst),
+ dst->cpp,
+ dst->pitch,
+ dstx, dsty, width, height, src, src_pitch, srcx, srcy);
+
+ pipe_surface_unmap(dst);
+}
+
+/* Assumes all values are within bounds -- no checking at this level -
+ * do it higher up if required.
+ */
+static void
+sp_surface_copy(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface *src,
+ unsigned srcx, unsigned srcy, unsigned width, unsigned height)
+{
+ assert( dst->cpp == src->cpp );
+
+ copy_rect(pipe_surface_map(dst),
+ dst->cpp,
+ dst->pitch,
+ dstx, dsty,
+ width, height,
+ pipe_surface_map(src),
+ src->pitch,
+ srcx, srcy);
+
+ pipe_surface_unmap(src);
+ pipe_surface_unmap(dst);
+}
+
+
+static ubyte *
+get_pointer(struct pipe_surface *dst, unsigned x, unsigned y)
+{
+ return dst->map + (y * dst->pitch + x) * dst->cpp;
+}
+
+
+#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
+
+
+/**
+ * Fill a rectangular sub-region. Need better logic about when to
+ * push buffers into AGP - will currently do so whenever possible.
+ */
+static void
+sp_surface_fill(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height, unsigned value)
+{
+ unsigned i, j;
+
+ assert(dst->pitch > 0);
+ assert(width <= dst->pitch);
+
+ (void)pipe_surface_map(dst);
+
+ switch (dst->cpp) {
+ case 1:
+ {
+ ubyte *row = get_pointer(dst, dstx, dsty);
+ for (i = 0; i < height; i++) {
+ memset(row, value, width);
+ row += dst->pitch;
+ }
+ }
+ break;
+ case 2:
+ {
+ ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++)
+ row[j] = (ushort) value;
+ row += dst->pitch;
+ }
+ }
+ break;
+ case 4:
+ {
+ unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty);
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++)
+ row[j] = value;
+ row += dst->pitch;
+ }
+ }
+ break;
+ case 8:
+ {
+ /* expand the 4-byte clear value to an 8-byte value */
+ ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
+ ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff);
+ ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff);
+ ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
+ ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ row[j*4+0] = val0;
+ row[j*4+1] = val1;
+ row[j*4+2] = val2;
+ row[j*4+3] = val3;
+ }
+ row += dst->pitch * 4;
+ }
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ pipe_surface_unmap( dst );
+}
+
void
sp_init_surface_functions(struct softpipe_context *sp)
@@ -700,4 +937,8 @@ sp_init_surface_functions(struct softpipe_context *sp)
sp->pipe.get_tile_rgba = softpipe_get_tile_rgba;
sp->pipe.put_tile_rgba = softpipe_put_tile_rgba;
+
+ sp->pipe.surface_data = sp_surface_data;
+ sp->pipe.surface_copy = sp_surface_copy;
+ sp->pipe.surface_fill = sp_surface_fill;
}
diff --git a/src/mesa/pipe/softpipe/sp_surface.h b/src/mesa/pipe/softpipe/sp_surface.h
index cf87e1a92c..b652e7598e 100644
--- a/src/mesa/pipe/softpipe/sp_surface.h
+++ b/src/mesa/pipe/softpipe/sp_surface.h
@@ -41,7 +41,7 @@ struct softpipe_tile_cache;
extern struct pipe_surface *
softpipe_get_tex_surface(struct pipe_context *pipe,
- struct pipe_mipmap_tree *mt,
+ struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice);
diff --git a/src/mesa/pipe/softpipe/sp_tex_layout.h b/src/mesa/pipe/softpipe/sp_tex_layout.h
deleted file mode 100644
index ea19c13b23..0000000000
--- a/src/mesa/pipe/softpipe/sp_tex_layout.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef SP_TEX_LAYOUT_H
-#define SP_TEX_LAYOUT_H
-
-
-struct pipe_context;
-struct pipe_mipmap_tree;
-
-
-extern boolean
-softpipe_mipmap_tree_layout(struct pipe_context *pipe,
- struct pipe_mipmap_tree *mt);
-
-
-#endif /* SP_TEX_LAYOUT_H */
-
-
diff --git a/src/mesa/pipe/softpipe/sp_tex_sample.c b/src/mesa/pipe/softpipe/sp_tex_sample.c
index 92958400fc..9e48ed0cd2 100644
--- a/src/mesa/pipe/softpipe/sp_tex_sample.c
+++ b/src/mesa/pipe/softpipe/sp_tex_sample.c
@@ -422,7 +422,7 @@ compute_lambda(struct tgsi_sampler *sampler,
dsdy = FABSF(dsdy);
rho = MAX2(dsdx, dsdy);
if (sampler->state->normalized_coords)
- rho *= sampler->texture->width0;
+ rho *= sampler->texture->width[0];
}
if (t) {
float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
@@ -432,7 +432,7 @@ compute_lambda(struct tgsi_sampler *sampler,
dtdy = FABSF(dtdy);
max = MAX2(dtdx, dtdy);
if (sampler->state->normalized_coords)
- max *= sampler->texture->height0;
+ max *= sampler->texture->height[0];
rho = MAX2(rho, max);
}
if (p) {
@@ -443,7 +443,7 @@ compute_lambda(struct tgsi_sampler *sampler,
dpdy = FABSF(dpdy);
max = MAX2(dpdx, dpdy);
if (sampler->state->normalized_coords)
- max *= sampler->texture->depth0;
+ max *= sampler->texture->depth[0];
rho = MAX2(rho, max);
}
@@ -620,8 +620,8 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler,
&level0, &level1, &levelBlend, &imgFilter);
if (sampler->state->normalized_coords) {
- width = sampler->texture->level[level0].width;
- height = sampler->texture->level[level0].height;
+ width = sampler->texture->width[level0];
+ height = sampler->texture->height[level0];
}
else {
width = height = 1;
@@ -757,9 +757,9 @@ sp_get_samples_3d(struct tgsi_sampler *sampler,
&level0, &level1, &levelBlend, &imgFilter);
if (sampler->state->normalized_coords) {
- width = sampler->texture->level[level0].width;
- height = sampler->texture->level[level0].height;
- depth = sampler->texture->level[level0].depth;
+ width = sampler->texture->width[level0];
+ height = sampler->texture->height[level0];
+ depth = sampler->texture->depth[level0];
}
else {
width = height = depth = 1;
@@ -883,7 +883,7 @@ sp_get_samples_cube(struct tgsi_sampler *sampler,
/**
* Called via tgsi_sampler::get_samples()
* Use the sampler's state setting to get a filtered RGBA value
- * from the sampler's texture (mipmap tree).
+ * from the sampler's texture.
*
* XXX we can implement many versions of this function, each
* tightly coded for a specific combination of sampler state
diff --git a/src/mesa/pipe/softpipe/sp_tex_layout.c b/src/mesa/pipe/softpipe/sp_texture.c
index 8156b00301..2288c343bf 100644
--- a/src/mesa/pipe/softpipe/sp_tex_layout.c
+++ b/src/mesa/pipe/softpipe/sp_texture.c
@@ -32,8 +32,13 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_util.h"
-#include "sp_tex_layout.h"
+#include "pipe/p_winsys.h"
+
+#include "sp_context.h"
+#include "sp_state.h"
+#include "sp_texture.h"
/* At the moment, just make softpipe use the same layout for its
@@ -54,100 +59,105 @@ static int align(int value, int alignment)
static void
-sp_miptree_set_level_info(struct pipe_mipmap_tree *mt,
- unsigned level,
- unsigned nr_images,
- unsigned x, unsigned y, unsigned w, unsigned h, unsigned d)
+sp_miptree_set_level_info(struct softpipe_texture *spt,
+ unsigned level,
+ unsigned nr_images,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ unsigned d)
{
+ struct pipe_texture *pt = &spt->base;
+
assert(level < PIPE_MAX_TEXTURE_LEVELS);
- mt->level[level].width = w;
- mt->level[level].height = h;
- mt->level[level].depth = d;
- mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp;
- mt->level[level].nr_images = nr_images;
+ pt->width[level] = w;
+ pt->height[level] = h;
+ pt->depth[level] = d;
+
+ spt->nr_images[level] = nr_images;
+ spt->level_offset[level] = (x + y * spt->pitch) * pt->cpp;
/*
DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
- level, w, h, d, x, y, mt->level[level].level_offset);
+ level, w, h, d, x, y, spt->level_offset[level]);
*/
/* Not sure when this would happen, but anyway:
*/
- if (mt->level[level].image_offset) {
- FREE( mt->level[level].image_offset );
- mt->level[level].image_offset = NULL;
+ if (spt->image_offset[level]) {
+ FREE( spt->image_offset[level] );
+ spt->image_offset[level] = NULL;
}
assert(nr_images);
- assert(!mt->level[level].image_offset);
+ assert(!spt->image_offset[level]);
- mt->level[level].image_offset = (unsigned *) MALLOC( nr_images * sizeof(unsigned) );
- mt->level[level].image_offset[0] = 0;
+ spt->image_offset[level] = (unsigned *) MALLOC( nr_images * sizeof(unsigned) );
+ spt->image_offset[level][0] = 0;
}
static void
-sp_miptree_set_image_offset(struct pipe_mipmap_tree *mt,
- unsigned level, unsigned img, unsigned x, unsigned y)
+sp_miptree_set_image_offset(struct softpipe_texture *spt,
+ unsigned level, unsigned img, unsigned x, unsigned y)
{
if (img == 0 && level == 0)
assert(x == 0 && y == 0);
- assert(img < mt->level[level].nr_images);
+ assert(img < spt->nr_images[level]);
- mt->level[level].image_offset[img] = (x + y * mt->pitch);
+ spt->image_offset[level][img] = (x + y * spt->pitch);
/*
DBG("%s level %d img %d pos %d,%d image_offset %x\n",
- __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]);
+ __FUNCTION__, level, img, x, y, spt->image_offset[level][img]);
*/
}
static void
-sp_miptree_layout_2d( struct pipe_mipmap_tree *mt )
+sp_miptree_layout_2d( struct softpipe_texture *spt )
{
+ struct pipe_texture *pt = &spt->base;
int align_h = 2, align_w = 4;
unsigned level;
unsigned x = 0;
unsigned y = 0;
- unsigned width = mt->width0;
- unsigned height = mt->height0;
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
- mt->pitch = mt->width0;
+ spt->pitch = pt->width[0];
/* XXX FIX THIS:
* we use alignment=64 bytes in sp_region_alloc(). If we change
* that, change this too.
*/
- if (mt->pitch < 16)
- mt->pitch = 16;
+ if (spt->pitch < 16)
+ spt->pitch = 16;
/* May need to adjust pitch to accomodate the placement of
* the 2nd mipmap. This occurs when the alignment
* constraints of mipmap placement push the right edge of the
* 2nd mipmap out past the width of its parent.
*/
- if (mt->first_level != mt->last_level) {
- unsigned mip1_width = align(minify(mt->width0), align_w)
- + minify(minify(mt->width0));
+ if (pt->first_level != pt->last_level) {
+ unsigned mip1_width = align(minify(pt->width[0]), align_w)
+ + minify(minify(pt->width[0]));
- if (mip1_width > mt->width0)
- mt->pitch = mip1_width;
+ if (mip1_width > pt->width[0])
+ spt->pitch = mip1_width;
}
/* Pitch must be a whole number of dwords, even though we
* express it in texels.
*/
- mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp;
- mt->total_height = 0;
+ spt->pitch = align(spt->pitch * pt->cpp, 4) / pt->cpp;
+ spt->total_height = 0;
- for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
+ for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
unsigned img_height;
- sp_miptree_set_level_info(mt, level, 1, x, y, width, height, 1);
+ sp_miptree_set_level_info(spt, level, 1, x, y, width, height, 1);
- if (mt->compressed)
+ if (pt->compressed)
img_height = MAX2(1, height/4);
else
img_height = align(height, align_h);
@@ -156,11 +166,11 @@ sp_miptree_layout_2d( struct pipe_mipmap_tree *mt )
/* Because the images are packed better, the final offset
* might not be the maximal one:
*/
- mt->total_height = MAX2(mt->total_height, y + img_height);
+ spt->total_height = MAX2(spt->total_height, y + img_height);
/* Layout_below: step right after second mipmap.
*/
- if (level == mt->first_level + 1) {
+ if (level == pt->first_level + 1) {
x += align(width, align_w);
}
else {
@@ -193,16 +203,17 @@ static const int step_offsets[6][2] = {
-boolean
-softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
+static boolean
+softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct softpipe_texture * spt)
{
+ struct pipe_texture *pt = &spt->base;
unsigned level;
- switch (mt->target) {
+ switch (pt->target) {
case PIPE_TEXTURE_CUBE:{
- const unsigned dim = mt->width0;
+ const unsigned dim = pt->width[0];
unsigned face;
- unsigned lvlWidth = mt->width0, lvlHeight = mt->height0;
+ unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
assert(lvlWidth == lvlHeight); /* cubemap images are square */
@@ -211,16 +222,16 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
* or the final row of 4x4, 2x2 and 1x1 faces below this.
*/
if (dim > 32)
- mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
+ spt->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
else
- mt->pitch = 14 * 8;
+ spt->pitch = 14 * 8;
- mt->total_height = dim * 4 + 4;
+ spt->total_height = dim * 4 + 4;
/* Set all the levels to effectively occupy the whole rectangular region.
*/
- for (level = mt->first_level; level <= mt->last_level; level++) {
- sp_miptree_set_level_info(mt, level, 6,
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ sp_miptree_set_level_info(spt, level, 6,
0, 0,
lvlWidth, lvlHeight, 1);
lvlWidth /= 2;
@@ -234,16 +245,16 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
unsigned d = dim;
if (dim == 4 && face >= 4) {
- y = mt->total_height - 4;
+ y = spt->total_height - 4;
x = (face - 4) * 8;
}
- else if (dim < 4 && (face > 0 || mt->first_level > 0)) {
- y = mt->total_height - 4;
+ else if (dim < 4 && (face > 0 || pt->first_level > 0)) {
+ y = spt->total_height - 4;
x = face * 8;
}
- for (level = mt->first_level; level <= mt->last_level; level++) {
- sp_miptree_set_image_offset(mt, level, face, x, y);
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ sp_miptree_set_image_offset(spt, level, face, x, y);
d >>= 1;
@@ -262,13 +273,13 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
break;
case PIPE_TEX_FACE_POS_Z:
case PIPE_TEX_FACE_NEG_Z:
- y = mt->total_height - 4;
+ y = spt->total_height - 4;
x = (face - 4) * 8;
break;
}
case 2:
- y = mt->total_height - 4;
+ y = spt->total_height - 4;
x = 16 + face * 8;
break;
@@ -286,33 +297,33 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
break;
}
case PIPE_TEXTURE_3D:{
- unsigned width = mt->width0;
- unsigned height = mt->height0;
- unsigned depth = mt->depth0;
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
+ unsigned depth = pt->depth[0];
unsigned pack_x_pitch, pack_x_nr;
unsigned pack_y_pitch;
unsigned level;
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
- mt->total_height = 0;
+ spt->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+ spt->total_height = 0;
- pack_y_pitch = MAX2(mt->height0, 2);
- pack_x_pitch = mt->pitch;
+ pack_y_pitch = MAX2(pt->height[0], 2);
+ pack_x_pitch = spt->pitch;
pack_x_nr = 1;
- for (level = mt->first_level; level <= mt->last_level; level++) {
- unsigned nr_images = mt->target == PIPE_TEXTURE_3D ? depth : 6;
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
int x = 0;
int y = 0;
unsigned q, j;
- sp_miptree_set_level_info(mt, level, nr_images,
- 0, mt->total_height,
- width, height, depth);
+ sp_miptree_set_level_info(spt, level, nr_images,
+ 0, spt->total_height,
+ width, height, depth);
for (q = 0; q < nr_images;) {
for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
- sp_miptree_set_image_offset(mt, level, q, x, y);
+ sp_miptree_set_image_offset(spt, level, q, x, y);
x += pack_x_pitch;
}
@@ -321,12 +332,12 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
}
- mt->total_height += y;
+ spt->total_height += y;
if (pack_x_pitch > 4) {
pack_x_pitch >>= 1;
pack_x_nr <<= 1;
- assert(pack_x_pitch * pack_x_nr <= mt->pitch);
+ assert(pack_x_pitch * pack_x_nr <= spt->pitch);
}
if (pack_y_pitch > 2) {
@@ -343,7 +354,7 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
// case PIPE_TEXTURE_RECTANGLE:
- sp_miptree_layout_2d(mt);
+ sp_miptree_layout_2d(spt);
break;
default:
assert(0);
@@ -352,10 +363,69 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
/*
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
- mt->pitch,
- mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
+ spt->pitch,
+ spt->total_height, pt->cpp, spt->pitch * spt->total_height * pt->cpp);
*/
return TRUE;
}
+void
+softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
+{
+ struct softpipe_texture *spt = REALLOC(*pt, sizeof(struct pipe_texture),
+ sizeof(struct softpipe_texture));
+
+ if (spt) {
+ memset(&spt->base + 1, 0,
+ sizeof(struct softpipe_texture) - sizeof(struct pipe_texture));
+
+ if (softpipe_mipmap_tree_layout(pipe, spt)) {
+ spt->buffer = pipe->winsys->buffer_create(pipe->winsys,
+ PIPE_SURFACE_FLAG_TEXTURE);
+
+ if (spt->buffer) {
+ pipe->winsys->buffer_data(pipe->winsys, spt->buffer,
+ spt->pitch * spt->base.cpp *
+ spt->total_height, NULL,
+ PIPE_BUFFER_USAGE_PIXEL);
+ }
+ }
+
+ if (!spt->buffer) {
+ FREE(spt);
+ spt = NULL;
+ }
+ }
+
+ *pt = &spt->base;
+}
+
+void
+softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
+{
+ if (!*pt)
+ return;
+
+ /*
+ DBG("%s %p refcount will be %d\n",
+ __FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
+ */
+ if (--(*pt)->refcount <= 0) {
+ struct softpipe_texture *spt = softpipe_texture(*pt);
+ uint i;
+
+ /*
+ DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
+ */
+
+ pipe->winsys->buffer_reference(pipe->winsys, &spt->buffer, NULL);
+
+ for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
+ if (spt->image_offset[i])
+ free(spt->image_offset[i]);
+
+ free(spt);
+ }
+ *pt = NULL;
+}
diff --git a/src/mesa/pipe/softpipe/sp_texture.h b/src/mesa/pipe/softpipe/sp_texture.h
new file mode 100644
index 0000000000..732064d986
--- /dev/null
+++ b/src/mesa/pipe/softpipe/sp_texture.h
@@ -0,0 +1,57 @@
+#ifndef SP_TEXTURE_H
+#define SP_TEXTURE_H
+
+
+struct pipe_context;
+struct pipe_texture;
+
+
+struct softpipe_texture
+{
+ struct pipe_texture base;
+
+ /* Derived from the above:
+ */
+ unsigned pitch;
+ unsigned depth_pitch; /* per-image on i945? */
+ unsigned total_height;
+
+ unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
+
+ /* Explicitly store the offset of each image for each cube face or
+ * depth value. Pretty much have to accept that hardware formats
+ * are going to be so diverse that there is no unified way to
+ * compute the offsets of depth/cube images within a mipmap level,
+ * so have to store them as a lookup table:
+ */
+ unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */
+
+ /* Includes image offset tables:
+ */
+ unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
+
+ /* The data is held here:
+ */
+ struct pipe_buffer_handle *buffer;
+};
+
+
+/** cast wrapper */
+static INLINE struct softpipe_texture *
+softpipe_texture(struct pipe_texture *pt)
+{
+ return (struct softpipe_texture *) pt;
+}
+
+
+
+extern void
+softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt);
+
+extern void
+softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt);
+
+
+#endif /* SP_TEXTURE */
+
+
diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c
index ea0c8b8f91..fadd169f5d 100644
--- a/src/mesa/pipe/softpipe/sp_tile_cache.c
+++ b/src/mesa/pipe/softpipe/sp_tile_cache.c
@@ -38,9 +38,7 @@
#include "sp_surface.h"
#include "sp_tile_cache.h"
-#define CLEAR_OPTIMIZATION 0
-
-#define NUM_ENTRIES 20
+#define NUM_ENTRIES 30
/** XXX move these */
@@ -51,10 +49,15 @@
struct softpipe_tile_cache
{
struct pipe_surface *surface; /**< the surface we're caching */
- struct pipe_mipmap_tree *texture; /**< if caching a texture */
+ struct pipe_texture *texture; /**< if caching a texture */
struct softpipe_cached_tile entries[NUM_ENTRIES];
uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
- float clear_value[4];
+ float clear_color[4];
+ uint clear_val;
+ boolean depth_stencil; /** Is the surface a depth/stencil format? */
+
+ struct pipe_surface *tex_surf;
+ int tex_face, tex_level, tex_z;
};
@@ -69,7 +72,10 @@ struct softpipe_tile_cache
-static uint
+/**
+ * Is the tile at (x,y) in cleared state?
+ */
+static INLINE uint
is_clear_flag_set(const uint *bitvec, int x, int y)
{
int pos, bit;
@@ -82,7 +88,10 @@ is_clear_flag_set(const uint *bitvec, int x, int y)
}
-static void
+/**
+ * Mark the tile at (x,y) as not cleared.
+ */
+static INLINE void
clear_clear_flag(uint *bitvec, int x, int y)
{
int pos;
@@ -122,14 +131,37 @@ sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
}
+/**
+ * Specify the surface to cache.
+ */
void
sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
struct pipe_surface *ps)
{
+ assert(!tc->texture);
+
+ if (tc->surface && tc->surface->map) {
+ assert(tc->surface != ps);
+ pipe_surface_unmap(tc->surface);
+ }
+
pipe_surface_reference(&tc->surface, ps);
+
+ if (!ps->map)
+ pipe_surface_map(ps);
+
+ if (ps) {
+ tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM ||
+ ps->format == PIPE_FORMAT_Z16_UNORM ||
+ ps->format == PIPE_FORMAT_Z32_UNORM ||
+ ps->format == PIPE_FORMAT_U_S8);
+ }
}
+/**
+ * Return the surface being cached.
+ */
struct pipe_surface *
sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
{
@@ -137,44 +169,165 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
}
+/**
+ * Specify the texture to cache.
+ */
void
sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
- struct pipe_mipmap_tree *texture)
+ struct pipe_texture *texture)
{
uint i;
+ assert(!tc->surface);
+
tc->texture = texture;
+ if (tc->tex_surf && tc->tex_surf->map)
+ pipe_surface_unmap(tc->tex_surf);
+ pipe_surface_reference(&tc->tex_surf, NULL);
+
/* 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++) {
tc->entries[i].x = -1;
}
+
+ tc->tex_face = -1; /* any invalid value here */
+}
+
+
+/**
+ * Set pixels in a tile to the given clear color/value, float.
+ */
+static void
+clear_tile_rgba(struct softpipe_cached_tile *tile,
+ enum pipe_format format,
+ const float clear_value[4])
+{
+ if (clear_value[0] == 0.0 &&
+ clear_value[1] == 0.0 &&
+ clear_value[2] == 0.0 &&
+ clear_value[3] == 0.0) {
+ memset(tile->data.color, 0, sizeof(tile->data.color));
+ }
+ else {
+ uint i, j;
+ for (i = 0; i < TILE_SIZE; i++) {
+ for (j = 0; j < TILE_SIZE; j++) {
+ tile->data.color[i][j][0] = clear_value[0];
+ tile->data.color[i][j][1] = clear_value[1];
+ tile->data.color[i][j][2] = clear_value[2];
+ tile->data.color[i][j][3] = clear_value[3];
+ }
+ }
+ }
+}
+
+
+/**
+ * Set a tile to a solid value/color.
+ */
+static void
+clear_tile(struct softpipe_cached_tile *tile,
+ enum pipe_format format,
+ uint clear_value)
+{
+ uint i, j;
+
+ switch (format) {
+ case PIPE_FORMAT_U_S8:
+ /* 8 bpp */
+ memset(tile->data.any, 0, TILE_SIZE * TILE_SIZE);
+ break;
+ case PIPE_FORMAT_Z16_UNORM:
+ /* 16 bpp */
+ if (clear_value == 0) {
+ memset(tile->data.any, 0, 2 * TILE_SIZE * TILE_SIZE);
+ }
+ else {
+ for (i = 0; i < TILE_SIZE; i++) {
+ for (j = 0; j < TILE_SIZE; j++) {
+ tile->data.depth16[i][j] = clear_value;
+ }
+ }
+ }
+ break;
+ default:
+ /* 32 bpp */
+ if (clear_value == 0) {
+ memset(tile->data.any, 0, 4 * TILE_SIZE * TILE_SIZE);
+ }
+ else {
+ for (i = 0; i < TILE_SIZE; i++) {
+ for (j = 0; j < TILE_SIZE; j++) {
+ tile->data.color32[i][j] = clear_value;
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Actually clear the tiles which were flagged as being in a clear state.
+ */
+static void
+sp_tile_cache_flush_clear(struct pipe_context *pipe,
+ struct softpipe_tile_cache *tc)
+{
+ struct pipe_surface *ps = tc->surface;
+ const uint w = tc->surface->width;
+ const uint h = tc->surface->height;
+ uint x, y;
+ struct softpipe_cached_tile tile;
+ uint numCleared = 0;
+
+ /* clear one tile to the clear value */
+ clear_tile(&tile, ps->format, tc->clear_val);
+
+ /* push the tile to all positions marked as clear */
+ for (y = 0; y < h; y += TILE_SIZE) {
+ for (x = 0; x < w; x += TILE_SIZE) {
+ if (is_clear_flag_set(tc->clear_flags, x, y)) {
+ pipe->put_tile(pipe, ps,
+ x, y, TILE_SIZE, TILE_SIZE,
+ tile.data.color32, 0/*STRIDE*/);
+
+ /* do this? */
+ clear_clear_flag(tc->clear_flags, x, y);
+
+ numCleared++;
+ }
+ }
+ }
+#if 0
+ printf("num cleared: %u\n", numCleared);
+#endif
}
+/**
+ * Flush the tile cache: write all dirty tiles back to the surface.
+ * any tiles "flagged" as cleared will be "really" cleared.
+ */
void
sp_flush_tile_cache(struct softpipe_context *softpipe,
struct softpipe_tile_cache *tc)
{
struct pipe_context *pipe = &softpipe->pipe;
struct pipe_surface *ps = tc->surface;
- boolean is_depth_stencil;
int inuse = 0, pos;
- if (!ps || !ps->region || !ps->region->map)
+ if (!ps || !ps->buffer)
return;
- is_depth_stencil = (ps->format == PIPE_FORMAT_S8_Z24 ||
- ps->format == PIPE_FORMAT_Z24_S8 ||
- ps->format == PIPE_FORMAT_U_Z16 ||
- ps->format == PIPE_FORMAT_U_Z32 ||
- ps->format == PIPE_FORMAT_U_S8);
+ if (!ps->map)
+ pipe_surface_map(ps);
for (pos = 0; pos < NUM_ENTRIES; pos++) {
struct softpipe_cached_tile *tile = tc->entries + pos;
if (tile->x >= 0) {
- if (is_depth_stencil) {
+ if (tc->depth_stencil) {
pipe->put_tile(pipe, ps,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
@@ -184,30 +337,31 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
-
tile->x = tile->y = -1; /* mark as empty */
inuse++;
}
}
- /*
+#if TILE_CLEAR_OPTIMIZATION
+ sp_tile_cache_flush_clear(&softpipe->pipe, tc);
+#endif
+
+#if 0
printf("flushed tiles in use: %d\n", inuse);
- */
+#endif
}
+/**
+ * Get a tile from the cache.
+ * \param x, y position of tile, in pixels
+ */
struct softpipe_cached_tile *
sp_get_cached_tile(struct softpipe_context *softpipe,
struct softpipe_tile_cache *tc, int x, int y)
{
struct pipe_context *pipe = &softpipe->pipe;
struct pipe_surface *ps = tc->surface;
- boolean is_depth_stencil
- = (ps->format == PIPE_FORMAT_S8_Z24 ||
- ps->format == PIPE_FORMAT_Z24_S8 ||
- ps->format == PIPE_FORMAT_U_Z16 ||
- ps->format == PIPE_FORMAT_U_Z32 ||
- ps->format == PIPE_FORMAT_U_S8);
/* tile pos in framebuffer: */
const int tile_x = x & ~(TILE_SIZE - 1);
@@ -222,10 +376,10 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
if (tile->x != -1) {
/* put dirty tile back in framebuffer */
- if (is_depth_stencil) {
+ if (tc->depth_stencil) {
pipe->put_tile(pipe, ps,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
- tile->data.depth32, 0 /*STRIDE*/);
+ tile->data.depth32, 0/*STRIDE*/);
}
else {
pipe->put_tile_rgba(pipe, ps,
@@ -234,92 +388,32 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
}
}
+ tile->x = tile_x;
+ tile->y = tile_y;
+
if (is_clear_flag_set(tc->clear_flags, x, y)) {
/* don't get tile from framebuffer, just clear it */
- uint i, j;
- /* XXX these loops could be optimized */
- switch (ps->format) {
- case PIPE_FORMAT_U_Z16:
- {
- ushort clear_val = (ushort) (tc->clear_value[0] * 0xffff);
- for (i = 0; i < TILE_SIZE; i++) {
- for (j = 0; j < TILE_SIZE; j++) {
- tile->data.depth16[i][j] = clear_val;
- }
- }
- }
- break;
- case PIPE_FORMAT_U_Z32:
- {
- uint clear_val = (uint) (tc->clear_value[0] * 0xffffffff);
- for (i = 0; i < TILE_SIZE; i++) {
- for (j = 0; j < TILE_SIZE; j++) {
- tile->data.depth32[i][j] = clear_val;
- }
- }
- }
- break;
- case PIPE_FORMAT_S8_Z24:
- {
- uint clear_val = (uint) (tc->clear_value[0] * 0xffffff);
- clear_val |= ((uint) tc->clear_value[1]) << 24;
- for (i = 0; i < TILE_SIZE; i++) {
- for (j = 0; j < TILE_SIZE; j++) {
- tile->data.depth32[i][j] = clear_val;
- }
- }
- }
- break;
- case PIPE_FORMAT_Z24_S8:
- {
- uint clear_val = ((uint) (tc->clear_value[0] * 0xffffff)) << 8;
- clear_val |= ((uint) tc->clear_value[1]) & 0xff;
- for (i = 0; i < TILE_SIZE; i++) {
- for (j = 0; j < TILE_SIZE; j++) {
- tile->data.depth32[i][j] = clear_val;
- }
- }
- }
- break;
- case PIPE_FORMAT_U_S8:
- {
- ubyte clear_val = (uint) tc->clear_value[0];
- for (i = 0; i < TILE_SIZE; i++) {
- for (j = 0; j < TILE_SIZE; j++) {
- tile->data.stencil8[i][j] = clear_val;
- }
- }
- }
- break;
- default:
- /* color */
- for (i = 0; i < TILE_SIZE; i++) {
- for (j = 0; j < TILE_SIZE; j++) {
- tile->data.color[i][j][0] = tc->clear_value[0];
- tile->data.color[i][j][1] = tc->clear_value[1];
- tile->data.color[i][j][2] = tc->clear_value[2];
- tile->data.color[i][j][3] = tc->clear_value[3];
- }
- }
+ if (tc->depth_stencil) {
+ clear_tile(tile, ps->format, tc->clear_val);
+ }
+ else {
+ clear_tile_rgba(tile, ps->format, tc->clear_color);
}
clear_clear_flag(tc->clear_flags, x, y);
}
else {
- /* get new tile from framebuffer */
- if (is_depth_stencil) {
+ /* get new tile data from surface */
+ if (tc->depth_stencil) {
pipe->get_tile(pipe, ps,
- tile_x, tile_y, TILE_SIZE, TILE_SIZE,
+ tile->x, tile->y, TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
pipe->get_tile_rgba(pipe, ps,
- tile_x, tile_y, TILE_SIZE, TILE_SIZE,
+ tile->x, tile->y, TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
}
-
- tile->x = tile_x;
- tile->y = tile_y;
}
return tile;
@@ -363,16 +457,33 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
z != tile->z ||
face != tile->face ||
level != tile->level) {
- /* XXX this call is a bit heavier than we'd like: */
- struct pipe_surface *ps
- = pipe->get_tex_surface(pipe, tc->texture, face, level, z);
+ /* cache miss */
- pipe->get_tile_rgba(pipe, ps,
- tile_x, tile_y, TILE_SIZE, TILE_SIZE,
- (float *) tile->data.color);
+ /* check if we need to get a new surface */
+ if (!tc->tex_surf ||
+ tc->tex_face != face ||
+ tc->tex_level != level ||
+ tc->tex_z != z) {
+ /* get new surface (view into texture) */
+ struct pipe_surface *ps;
+
+ if (tc->tex_surf && tc->tex_surf->map)
+ pipe_surface_unmap(tc->tex_surf);
+
+ ps = pipe->get_tex_surface(pipe, tc->texture, face, level, z);
+ pipe_surface_reference(&tc->tex_surf, ps);
- pipe_surface_reference(&ps, NULL);
+ pipe_surface_map(ps);
+ tc->tex_face = face;
+ tc->tex_level = level;
+ tc->tex_z = z;
+ }
+
+ /* get tile from the surface (view into texture) */
+ pipe->get_tile_rgba(pipe, tc->tex_surf,
+ tile_x, tile_y, TILE_SIZE, TILE_SIZE,
+ (float *) tile->data.color);
tile->x = tile_x;
tile->y = tile_y;
tile->z = z;
@@ -390,16 +501,45 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
* Save the color and set a 'clearflag' for each tile of the screen.
*/
void
-sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float value[4])
+sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue)
{
- tc->clear_value[0] = value[0];
- tc->clear_value[1] = value[1];
- tc->clear_value[2] = value[2];
- tc->clear_value[3] = value[3];
+ uint r, g, b, a;
+
+ tc->clear_val = clearValue;
+
+ switch (tc->surface->format) {
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ r = (clearValue >> 24) & 0xff;
+ g = (clearValue >> 16) & 0xff;
+ b = (clearValue >> 8) & 0xff;
+ a = (clearValue ) & 0xff;
+ break;
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ r = (clearValue >> 16) & 0xff;
+ g = (clearValue >> 8) & 0xff;
+ b = (clearValue ) & 0xff;
+ a = (clearValue >> 24) & 0xff;
+ break;
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ r = (clearValue >> 8) & 0xff;
+ g = (clearValue >> 16) & 0xff;
+ b = (clearValue >> 24) & 0xff;
+ a = (clearValue ) & 0xff;
+ break;
+ default:
+ r = g = b = a = 0;
+ }
+
+ tc->clear_color[0] = r / 255.0;
+ tc->clear_color[1] = g / 255.0;
+ tc->clear_color[2] = b / 255.0;
+ tc->clear_color[3] = a / 255.0;
-#if CLEAR_OPTIMIZATION
+#if TILE_CLEAR_OPTIMIZATION
+ /* set flags to indicate all the tiles are cleared */
memset(tc->clear_flags, 255, sizeof(tc->clear_flags));
#else
+ /* disable the optimization */
memset(tc->clear_flags, 0, sizeof(tc->clear_flags));
#endif
}
diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.h b/src/mesa/pipe/softpipe/sp_tile_cache.h
index e66fec2e20..91fb2795a2 100644
--- a/src/mesa/pipe/softpipe/sp_tile_cache.h
+++ b/src/mesa/pipe/softpipe/sp_tile_cache.h
@@ -28,6 +28,8 @@
#ifndef SP_TILE_CACHE_H
#define SP_TILE_CACHE_H
+#define TILE_CLEAR_OPTIMIZATION 1
+
#include "pipe/p_compiler.h"
@@ -49,9 +51,11 @@ struct softpipe_cached_tile
int z, face, level; /**< Extra texture indexes */
union {
float color[TILE_SIZE][TILE_SIZE][4];
+ uint color32[TILE_SIZE][TILE_SIZE];
uint depth32[TILE_SIZE][TILE_SIZE];
ushort depth16[TILE_SIZE][TILE_SIZE];
ubyte stencil8[TILE_SIZE][TILE_SIZE];
+ ubyte any[1];
} data;
};
@@ -71,14 +75,14 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc);
extern void
sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
- struct pipe_mipmap_tree *texture);
+ struct pipe_texture *texture);
extern void
sp_flush_tile_cache(struct softpipe_context *softpipe,
struct softpipe_tile_cache *tc);
extern void
-sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float value[4]);
+sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue);
extern struct softpipe_cached_tile *
sp_get_cached_tile(struct softpipe_context *softpipe,