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/sp_context.c28
-rw-r--r--src/mesa/pipe/softpipe/sp_context.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_setup.c16
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_setup.h99
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_vbuf.c8
-rw-r--r--src/mesa/pipe/softpipe/sp_query.c6
-rw-r--r--src/mesa/pipe/softpipe/sp_state.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_state_fs.c45
-rw-r--r--src/mesa/pipe/softpipe/sp_state_surface.c42
-rw-r--r--src/mesa/pipe/softpipe/sp_surface.c45
-rw-r--r--src/mesa/pipe/softpipe/sp_texture.c330
-rw-r--r--src/mesa/pipe/softpipe/sp_texture.h19
-rw-r--r--src/mesa/pipe/softpipe/sp_tile_cache.c70
-rw-r--r--src/mesa/pipe/softpipe/sp_tile_cache.h6
14 files changed, 208 insertions, 510 deletions
diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c
index c7af63cc2d..68c18e2d05 100644
--- a/src/mesa/pipe/softpipe/sp_context.c
+++ b/src/mesa/pipe/softpipe/sp_context.c
@@ -75,22 +75,15 @@ softpipe_is_format_supported( struct pipe_context *pipe,
void
softpipe_map_surfaces(struct softpipe_context *sp)
{
- struct pipe_surface *ps;
unsigned i;
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
- ps = sp->framebuffer.cbufs[i];
- if (ps->buffer)
- pipe_surface_map(ps);
+ sp_tile_cache_map_surfaces(sp->cbuf_cache[i]);
}
- ps = sp->framebuffer.zbuf;
- if (ps && ps->buffer)
- pipe_surface_map(ps);
+ sp_tile_cache_map_surfaces(sp->zbuf_cache);
- ps = sp->framebuffer.sbuf;
- if (ps && ps->buffer)
- pipe_surface_map(ps);
+ sp_tile_cache_map_surfaces(sp->sbuf_cache);
}
@@ -100,7 +93,6 @@ softpipe_map_surfaces(struct softpipe_context *sp)
void
softpipe_unmap_surfaces(struct softpipe_context *sp)
{
- struct pipe_surface *ps;
uint i;
for (i = 0; i < sp->framebuffer.num_cbufs; i++)
@@ -109,18 +101,12 @@ softpipe_unmap_surfaces(struct softpipe_context *sp)
sp_flush_tile_cache(sp, sp->sbuf_cache);
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
- ps = sp->framebuffer.cbufs[i];
- if (ps->map)
- pipe_surface_unmap(ps);
+ sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]);
}
- ps = sp->framebuffer.zbuf;
- if (ps && ps->map)
- pipe_surface_unmap(ps);
+ sp_tile_cache_unmap_surfaces(sp->zbuf_cache);
- ps = sp->framebuffer.sbuf;
- if (ps && ps->map)
- pipe_surface_unmap(ps);
+ sp_tile_cache_unmap_surfaces(sp->sbuf_cache);
}
@@ -345,7 +331,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
if (GETENV( "SP_VBUF" ) != NULL) {
softpipe->vbuf = sp_draw_vbuf_stage(softpipe->draw,
&softpipe->pipe,
- sp_vbuf_setup_draw);
+ sp_vbuf_render);
draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf);
}
diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h
index 394baf0109..3537f86a61 100644
--- a/src/mesa/pipe/softpipe/sp_context.h
+++ b/src/mesa/pipe/softpipe/sp_context.h
@@ -76,7 +76,7 @@ struct softpipe_context {
/* Counter for occlusion queries. Note this supports overlapping
* queries.
*/
- uint64_t occlusion_count;
+ uint64 occlusion_count;
/*
* Mapped vertex buffers
diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c
index de45529bf9..722cadc5c0 100644
--- a/src/mesa/pipe/softpipe/sp_prim_setup.c
+++ b/src/mesa/pipe/softpipe/sp_prim_setup.c
@@ -1286,18 +1286,20 @@ static void calc_det( struct prim_header *header )
-/* Test harness - feed vertex buffer back into prim pipeline.
+/**
+ * Render buffer of points/lines/triangles.
+ * Called by vbuf code when the vertex or index buffer is filled.
*
* The big issue at this point is that reset_stipple doesn't make it
* through the interface. Probably need to split primitives at reset
* stipple, perhaps using the ~0 index marker.
*/
-void sp_vbuf_setup_draw( struct pipe_context *pipe,
- unsigned primitive,
- const ushort *elements,
- unsigned nr_elements,
- const void *vertex_buffer,
- unsigned nr_vertices )
+void sp_vbuf_render( struct pipe_context *pipe,
+ unsigned primitive,
+ const ushort *elements,
+ unsigned nr_elements,
+ const void *vertex_buffer,
+ unsigned nr_vertices )
{
struct softpipe_context *softpipe = softpipe_context( pipe );
struct setup_stage *setup = setup_stage( softpipe->setup );
diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.h b/src/mesa/pipe/softpipe/sp_prim_setup.h
index 598394f73e..c16dc634b0 100644
--- a/src/mesa/pipe/softpipe/sp_prim_setup.h
+++ b/src/mesa/pipe/softpipe/sp_prim_setup.h
@@ -1,33 +1,49 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
- *
+/**************************************************************************
+ *
+ * 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, sublicense,
- * 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 shall be included
- * in all copies or substantial portions of the Software.
- *
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL 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.
- */
+ * 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_PRIM_SETUP_H
#define SP_PRIM_SETUP_H
-/* Vertices are just an array of floats, with all the attributes
+/**
+ * vbuf is a special stage to gather the stream of triangles, lines, points
+ * together and reconstruct vertex buffers for hardware upload.
+ *
+ * First attempt, work in progress.
+ *
+ * TODO:
+ * - separate out vertex buffer building and primitive emit, ie >1 draw per vb.
+ * - tell vbuf stage how to build hw vertices directly
+ * - pass vbuf stage a buffer pointer for direct emit to agp/vram.
+ *
+ *
+ *
+ * Vertices are just an array of floats, with all the attributes
* packed. We currently assume a layout like:
*
* attr[0][0..3] - window position
@@ -37,23 +53,11 @@
* all the enabled attributes run contiguously.
*/
+
struct draw_stage;
struct softpipe_context;
-extern struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe );
-
-
-/* A special stage to gather the stream of triangles, lines, points
- * together and reconstruct vertex buffers for hardware upload.
- *
- * First attempt, work in progress.
- *
- * TODO:
- * - separate out vertex buffer building and primitive emit, ie >1 draw per vb.
- * - tell vbuf stage how to build hw vertices directly
- * - pass vbuf stage a buffer pointer for direct emit to agp/vram.
- */
typedef void (*vbuf_draw_func)( struct pipe_context *pipe,
unsigned prim,
const ushort *elements,
@@ -62,20 +66,23 @@ typedef void (*vbuf_draw_func)( struct pipe_context *pipe,
unsigned nr_vertices );
-extern struct draw_stage *sp_draw_vbuf_stage( struct draw_context *draw_context,
- struct pipe_context *pipe,
- vbuf_draw_func draw );
+extern struct draw_stage *
+sp_draw_render_stage( struct softpipe_context *softpipe );
+extern struct draw_stage *
+sp_draw_vbuf_stage( struct draw_context *draw_context,
+ struct pipe_context *pipe,
+ vbuf_draw_func draw );
-/* Test harness
- */
-void sp_vbuf_setup_draw( struct pipe_context *pipe,
- unsigned prim,
- const ushort *elements,
- unsigned nr_elements,
- const void *vertex_buffer,
- unsigned nr_vertices );
+
+extern void
+sp_vbuf_render( struct pipe_context *pipe,
+ unsigned prim,
+ const ushort *elements,
+ unsigned nr_elements,
+ const void *vertex_buffer,
+ unsigned nr_vertices );
diff --git a/src/mesa/pipe/softpipe/sp_prim_vbuf.c b/src/mesa/pipe/softpipe/sp_prim_vbuf.c
index 2cfdeb5809..055cb19f9a 100644
--- a/src/mesa/pipe/softpipe/sp_prim_vbuf.c
+++ b/src/mesa/pipe/softpipe/sp_prim_vbuf.c
@@ -120,6 +120,12 @@ static void emit_vertex( struct vbuf_stage *vbuf,
vertex->vertex_id = vbuf->nr_vertices++;
//vbuf->emit_vertex( vbuf->vertex_ptr, vertex );
+
+ /* Note: for softpipe, the vertex includes the vertex header info
+ * such as clip flags and clip coords. In the future when vbuf is
+ * always used, we could just copy the vertex attributes/data here.
+ * The sp_prim_setup.c code doesn't use any of the vertex header info.
+ */
memcpy(vbuf->vertex_ptr, vertex, vbuf->vertex_size);
vbuf->vertex_ptr += vbuf->vertex_size;
@@ -221,7 +227,9 @@ static void vbuf_flush_elements( struct draw_stage *stage )
struct vbuf_stage *vbuf = vbuf_stage( stage );
if (vbuf->nr_elements) {
+ /*
fprintf(stderr, "%s (%d elts)\n", __FUNCTION__, vbuf->nr_elements);
+ */
/* Draw now or add to list of primitives???
*/
diff --git a/src/mesa/pipe/softpipe/sp_query.c b/src/mesa/pipe/softpipe/sp_query.c
index bf753dad98..6a8a43aeda 100644
--- a/src/mesa/pipe/softpipe/sp_query.c
+++ b/src/mesa/pipe/softpipe/sp_query.c
@@ -37,8 +37,8 @@
#include "sp_query.h"
struct softpipe_query {
- uint64_t start;
- uint64_t end;
+ uint64 start;
+ uint64 end;
};
@@ -87,7 +87,7 @@ static boolean
softpipe_get_query_result(struct pipe_context *pipe,
struct pipe_query *q,
boolean wait,
- uint64_t *result )
+ uint64 *result )
{
struct softpipe_query *sq = softpipe_query(q);
*result = sq->end - sq->start;
diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h
index c1f5555a86..bac7b0876f 100644
--- a/src/mesa/pipe/softpipe/sp_state.h
+++ b/src/mesa/pipe/softpipe/sp_state.h
@@ -75,7 +75,7 @@ struct sp_fragment_shader_state {
/** Subclass of pipe_shader_state */
struct sp_vertex_shader_state {
struct pipe_shader_state shader;
- void *draw_data;
+ struct draw_vertex_shader *draw_data;
};
diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c
index f72a91485f..945c93411f 100644
--- a/src/mesa/pipe/softpipe/sp_state_fs.c
+++ b/src/mesa/pipe/softpipe/sp_state_fs.c
@@ -38,8 +38,9 @@
#include "pipe/tgsi/exec/tgsi_sse2.h"
-void * softpipe_create_fs_state(struct pipe_context *pipe,
- const struct pipe_shader_state *templ)
+void *
+softpipe_create_fs_state(struct pipe_context *pipe,
+ const struct pipe_shader_state *templ)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
struct sp_fragment_shader_state *state;
@@ -58,13 +59,6 @@ void * softpipe_create_fs_state(struct pipe_context *pipe,
tgsi_dump(state->shader.tokens, 0);
}
-#if defined(__i386__) || defined(__386__)
- if (softpipe->use_sse) {
- x86_init_func( &state->sse2_program );
- tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program );
- }
-#endif
-
#ifdef MESA_LLVM
state->llvm_prog = gallivm_from_tgsi(state->shader.tokens, GALLIVM_FS);
if (!gallivm_global_cpu_engine()) {
@@ -72,13 +66,19 @@ void * softpipe_create_fs_state(struct pipe_context *pipe,
}
else
gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog);
+#elif defined(__i386__) || defined(__386__)
+ if (softpipe->use_sse) {
+ x86_init_func( &state->sse2_program );
+ tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program );
+ }
#endif
return state;
}
-void softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
+void
+softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -88,10 +88,10 @@ void softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
}
-void softpipe_delete_fs_state(struct pipe_context *pipe,
- void *shader)
+void
+softpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
{
- struct sp_fragment_shader_state *state = shader;
+ struct sp_fragment_shader_state *state = fs;
#if defined(__i386__) || defined(__386__)
x86_release_func( &state->sse2_program );
@@ -101,8 +101,9 @@ void softpipe_delete_fs_state(struct pipe_context *pipe,
}
-void * softpipe_create_vs_state(struct pipe_context *pipe,
- const struct pipe_shader_state *templ)
+void *
+softpipe_create_vs_state(struct pipe_context *pipe,
+ const struct pipe_shader_state *templ)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
struct sp_vertex_shader_state *state;
@@ -125,7 +126,8 @@ void * softpipe_create_vs_state(struct pipe_context *pipe,
}
-void softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
+void
+softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -137,7 +139,8 @@ void softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
}
-void softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
+void
+softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -149,9 +152,11 @@ void softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
}
-void softpipe_set_constant_buffer(struct pipe_context *pipe,
- uint shader, uint index,
- const struct pipe_constant_buffer *buf)
+
+void
+softpipe_set_constant_buffer(struct pipe_context *pipe,
+ uint shader, uint index,
+ const struct pipe_constant_buffer *buf)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
struct pipe_winsys *ws = pipe->winsys;
diff --git a/src/mesa/pipe/softpipe/sp_state_surface.c b/src/mesa/pipe/softpipe/sp_state_surface.c
index ee72aaf4c5..4a9a28cc4d 100644
--- a/src/mesa/pipe/softpipe/sp_state_surface.c
+++ b/src/mesa/pipe/softpipe/sp_state_surface.c
@@ -38,7 +38,7 @@
/**
* XXX this might get moved someday
* Set the framebuffer surface info: color buffers, zbuffer, stencil buffer.
- * Here, we map the surfaces and update the tile cache to point to the new
+ * Here, we flush the old surfaces and update the tile cache to point to the new
* surfaces.
*/
void
@@ -46,7 +46,6 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
{
struct softpipe_context *sp = softpipe_context(pipe);
- struct pipe_surface *ps;
uint i;
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
@@ -54,19 +53,12 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) {
/* flush old */
sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
- /* unmap old */
- ps = sp->framebuffer.cbufs[i];
- if (ps && ps->map)
- pipe_surface_unmap(ps);
- /* map new */
- ps = fb->cbufs[i];
- if (ps)
- pipe_surface_map(ps);
+
/* assign new */
sp->framebuffer.cbufs[i] = fb->cbufs[i];
/* update cache */
- sp_tile_cache_set_surface(sp->cbuf_cache[i], ps);
+ sp_tile_cache_set_surface(sp->cbuf_cache[i], fb->cbufs[i]);
}
}
@@ -76,23 +68,12 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
if (sp->framebuffer.zbuf != fb->zbuf) {
/* flush old */
sp_flush_tile_cache(sp, sp->zbuf_cache);
- /* unmap old */
- ps = sp->framebuffer.zbuf;
- if (ps && ps->map)
- pipe_surface_unmap(ps);
- if (sp->framebuffer.sbuf == sp->framebuffer.zbuf) {
- /* combined z/stencil */
- sp->framebuffer.sbuf = NULL;
- }
- /* map new */
- ps = fb->zbuf;
- if (ps)
- pipe_surface_map(ps);
+
/* assign new */
sp->framebuffer.zbuf = fb->zbuf;
/* update cache */
- sp_tile_cache_set_surface(sp->zbuf_cache, ps);
+ sp_tile_cache_set_surface(sp->zbuf_cache, fb->zbuf);
}
/* XXX combined depth/stencil here */
@@ -101,14 +82,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
if (sp->framebuffer.sbuf != fb->sbuf) {
/* flush old */
sp_flush_tile_cache(sp, sp->sbuf_cache_sep);
- /* unmap old */
- ps = sp->framebuffer.sbuf;
- if (ps && ps->map)
- pipe_surface_unmap(ps);
- /* map new */
- ps = fb->sbuf;
- if (ps && fb->sbuf != fb->zbuf)
- pipe_surface_map(ps);
+
/* assign new */
sp->framebuffer.sbuf = fb->sbuf;
@@ -116,12 +90,12 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
if (fb->sbuf != fb->zbuf) {
/* separate stencil buf */
sp->sbuf_cache = sp->sbuf_cache_sep;
- sp_tile_cache_set_surface(sp->sbuf_cache, ps);
+ sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf);
}
else {
/* combined depth/stencil */
sp->sbuf_cache = sp->zbuf_cache;
- sp_tile_cache_set_surface(sp->sbuf_cache, ps);
+ sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf);
}
}
diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c
index 5259fbfd20..6c080d5b5c 100644
--- a/src/mesa/pipe/softpipe/sp_surface.c
+++ b/src/mesa/pipe/softpipe/sp_surface.c
@@ -46,20 +46,6 @@ softpipe_get_tex_surface(struct pipe_context *pipe,
{
struct softpipe_texture *spt = softpipe_texture(pt);
struct pipe_surface *ps;
- unsigned offset; /* in bytes */
-
- offset = spt->level_offset[level];
-
- if (pt->target == PIPE_TEXTURE_CUBE) {
- offset += spt->image_offset[level][face] * pt->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);
if (ps) {
@@ -69,8 +55,17 @@ softpipe_get_tex_surface(struct pipe_context *pipe,
ps->cpp = pt->cpp;
ps->width = pt->width[level];
ps->height = pt->height[level];
- ps->pitch = spt->pitch;
- ps->offset = offset;
+ ps->pitch = ps->width;
+ ps->offset = spt->level_offset[level];
+
+ if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
+ ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
+ (pt->compressed ? ps->height/4 : ps->height) *
+ ps->width * ps->cpp;
+ } else {
+ assert(face == 0);
+ assert(zslice == 0);
+ }
}
return ps;
}
@@ -163,10 +158,10 @@ sp_surface_copy(struct pipe_context *pipe,
}
-static ubyte *
-get_pointer(struct pipe_surface *dst, unsigned x, unsigned y)
+static void *
+get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y)
{
- return dst->map + (y * dst->pitch + x) * dst->cpp;
+ return (char *)dst_map + (y * dst->pitch + x) * dst->cpp;
}
@@ -184,16 +179,16 @@ sp_surface_fill(struct pipe_context *pipe,
unsigned width, unsigned height, unsigned value)
{
unsigned i, j;
+ void *dst_map = pipe_surface_map(dst);
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);
+ ubyte *row = get_pointer(dst, dst_map, dstx, dsty);
for (i = 0; i < height; i++) {
memset(row, value, width);
row += dst->pitch;
@@ -202,7 +197,7 @@ sp_surface_fill(struct pipe_context *pipe,
break;
case 2:
{
- ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
+ ushort *row = get_pointer(dst, dst_map, dstx, dsty);
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++)
row[j] = (ushort) value;
@@ -212,7 +207,7 @@ sp_surface_fill(struct pipe_context *pipe,
break;
case 4:
{
- unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty);
+ unsigned *row = get_pointer(dst, dst_map, dstx, dsty);
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++)
row[j] = value;
@@ -223,7 +218,7 @@ sp_surface_fill(struct pipe_context *pipe,
case 8:
{
/* expand the 4-byte clear value to an 8-byte value */
- ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
+ ushort *row = (ushort *) get_pointer(dst, dst_map, 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);
@@ -257,8 +252,6 @@ sp_init_surface_functions(struct softpipe_context *sp)
{
sp->pipe.get_tile = pipe_get_tile_raw;
sp->pipe.put_tile = pipe_put_tile_raw;
- sp->pipe.get_tile_rgba = pipe_get_tile_rgba;
- sp->pipe.put_tile_rgba = pipe_put_tile_rgba;
sp->pipe.surface_data = sp_surface_data;
sp->pipe.surface_copy = sp_surface_copy;
diff --git a/src/mesa/pipe/softpipe/sp_texture.c b/src/mesa/pipe/softpipe/sp_texture.c
index 44512e4281..e5e6bfe01b 100644
--- a/src/mesa/pipe/softpipe/sp_texture.c
+++ b/src/mesa/pipe/softpipe/sp_texture.c
@@ -41,10 +41,7 @@
#include "sp_texture.h"
-/* At the moment, just make softpipe use the same layout for its
- * textures as the i945. Softpipe needs some sort of texture layout,
- * this one was handy. May be worthwhile to simplify this code a
- * little.
+/* Simple, maximally packed layout.
*/
static unsigned minify( unsigned d )
@@ -53,319 +50,35 @@ static unsigned minify( unsigned d )
}
-
-static void
-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);
-
- 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, spt->level_offset[level]);
- */
-
- /* Not sure when this would happen, but anyway:
- */
- if (spt->image_offset[level]) {
- FREE( spt->image_offset[level] );
- spt->image_offset[level] = NULL;
- }
-
- assert(nr_images);
- assert(!spt->image_offset[level]);
-
- spt->image_offset[level] = (unsigned *) MALLOC( nr_images * sizeof(unsigned) );
- spt->image_offset[level][0] = 0;
-}
-
-
-static void
-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 < spt->nr_images[level]);
-
- 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, spt->image_offset[level][img]);
- */
-}
-
-
static void
-sp_miptree_layout_2d( struct softpipe_texture *spt )
+softpipe_texture_layout(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 = pt->width[0];
unsigned height = pt->height[0];
+ unsigned depth = pt->depth[0];
- 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 (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 (pt->first_level != pt->last_level) {
- unsigned mip1_width = align(minify(pt->width[0]), align_w)
- + minify(minify(pt->width[0]));
-
- 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.
- */
- spt->pitch = align(spt->pitch * pt->cpp, 4) / pt->cpp;
- spt->total_height = 0;
+ spt->buffer_size = 0;
for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
- unsigned img_height;
-
- sp_miptree_set_level_info(spt, level, 1, x, y, width, height, 1);
-
- if (pt->compressed)
- img_height = MAX2(1, height/4);
- else
- img_height = align(height, align_h);
+ pt->width[level] = width;
+ pt->height[level] = height;
+ pt->depth[level] = depth;
+ spt->level_offset[level] = spt->buffer_size;
- /* Because the images are packed better, the final offset
- * might not be the maximal one:
- */
- spt->total_height = MAX2(spt->total_height, y + img_height);
-
- /* Layout_below: step right after second mipmap.
- */
- if (level == pt->first_level + 1) {
- x += align(width, align_w);
- }
- else {
- y += img_height;
- }
+ spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) *
+ ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
+ width * pt->cpp;
width = minify(width);
height = minify(height);
+ depth = minify(depth);
}
}
-static const int initial_offsets[6][2] = {
- {0, 0},
- {0, 2},
- {1, 0},
- {1, 2},
- {1, 1},
- {1, 3}
-};
-
-static const int step_offsets[6][2] = {
- {0, 2},
- {0, 2},
- {-1, 2},
- {-1, 2},
- {-1, 1},
- {-1, 1}
-};
-
-
-
-static boolean
-softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct softpipe_texture * spt)
-{
- struct pipe_texture *pt = &spt->base;
- unsigned level;
-
- switch (pt->target) {
- case PIPE_TEXTURE_CUBE:{
- const unsigned dim = pt->width[0];
- unsigned face;
- unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
-
- assert(lvlWidth == lvlHeight); /* cubemap images are square */
-
- /* Depending on the size of the largest images, pitch can be
- * determined either by the old-style packing of cubemap faces,
- * or the final row of 4x4, 2x2 and 1x1 faces below this.
- */
- if (dim > 32)
- spt->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
- else
- spt->pitch = 14 * 8;
-
- spt->total_height = dim * 4 + 4;
-
- /* Set all the levels to effectively occupy the whole rectangular region.
- */
- 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;
- lvlHeight /= 2;
- }
-
-
- for (face = 0; face < 6; face++) {
- unsigned x = initial_offsets[face][0] * dim;
- unsigned y = initial_offsets[face][1] * dim;
- unsigned d = dim;
-
- if (dim == 4 && face >= 4) {
- y = spt->total_height - 4;
- x = (face - 4) * 8;
- }
- else if (dim < 4 && (face > 0 || pt->first_level > 0)) {
- y = spt->total_height - 4;
- x = face * 8;
- }
-
- for (level = pt->first_level; level <= pt->last_level; level++) {
- sp_miptree_set_image_offset(spt, level, face, x, y);
-
- d >>= 1;
-
- switch (d) {
- case 4:
- switch (face) {
- case PIPE_TEX_FACE_POS_X:
- case PIPE_TEX_FACE_NEG_X:
- x += step_offsets[face][0] * d;
- y += step_offsets[face][1] * d;
- break;
- case PIPE_TEX_FACE_POS_Y:
- case PIPE_TEX_FACE_NEG_Y:
- y += 12;
- x -= 8;
- break;
- case PIPE_TEX_FACE_POS_Z:
- case PIPE_TEX_FACE_NEG_Z:
- y = spt->total_height - 4;
- x = (face - 4) * 8;
- break;
- }
-
- case 2:
- y = spt->total_height - 4;
- x = 16 + face * 8;
- break;
-
- case 1:
- x += 48;
- break;
-
- default:
- x += step_offsets[face][0] * d;
- y += step_offsets[face][1] * d;
- break;
- }
- }
- }
- break;
- }
- case PIPE_TEXTURE_3D:{
- 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;
-
- spt->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
- spt->total_height = 0;
-
- pack_y_pitch = MAX2(pt->height[0], 2);
- pack_x_pitch = spt->pitch;
- pack_x_nr = 1;
-
- 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(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(spt, level, q, x, y);
- x += pack_x_pitch;
- }
-
- x = 0;
- y += pack_y_pitch;
- }
-
-
- spt->total_height += y;
-
- if (pack_x_pitch > 4) {
- pack_x_pitch >>= 1;
- pack_x_nr <<= 1;
- assert(pack_x_pitch * pack_x_nr <= spt->pitch);
- }
-
- if (pack_y_pitch > 2) {
- pack_y_pitch >>= 1;
- }
-
- width = minify(width);
- height = minify(height);
- depth = minify(depth);
- }
- break;
- }
-
- case PIPE_TEXTURE_1D:
- case PIPE_TEXTURE_2D:
-// case PIPE_TEXTURE_RECTANGLE:
- sp_miptree_layout_2d(spt);
- break;
- default:
- assert(0);
- break;
- }
-
- /*
- DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
- 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)
{
@@ -376,15 +89,13 @@ softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
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, 32, 0, 0);
+ softpipe_texture_layout(spt);
- if (spt->buffer) {
- pipe->winsys->buffer_data(pipe->winsys, spt->buffer,
- spt->pitch * spt->base.cpp *
- spt->total_height, NULL,
- PIPE_BUFFER_USAGE_PIXEL);
- }
+ spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32, 0, 0);
+
+ if (spt->buffer) {
+ pipe->winsys->buffer_data(pipe->winsys, spt->buffer, spt->buffer_size,
+ NULL, PIPE_BUFFER_USAGE_PIXEL);
}
if (!spt->buffer) {
@@ -408,7 +119,6 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
*/
if (--(*pt)->refcount <= 0) {
struct softpipe_texture *spt = softpipe_texture(*pt);
- uint i;
/*
DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
@@ -416,10 +126,6 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
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
index 732064d986..e1a5db2791 100644
--- a/src/mesa/pipe/softpipe/sp_texture.h
+++ b/src/mesa/pipe/softpipe/sp_texture.h
@@ -10,29 +10,12 @@ 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;
+ unsigned long buffer_size;
};
diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c
index 1dbcc5aadd..6515ce668c 100644
--- a/src/mesa/pipe/softpipe/sp_tile_cache.c
+++ b/src/mesa/pipe/softpipe/sp_tile_cache.c
@@ -34,6 +34,7 @@
#include "pipe/p_util.h"
#include "pipe/p_inlines.h"
+#include "pipe/util/p_tile.h"
#include "sp_context.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
@@ -49,6 +50,7 @@
struct softpipe_tile_cache
{
struct pipe_surface *surface; /**< the surface we're caching */
+ void *surface_map;
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];
@@ -57,6 +59,7 @@ struct softpipe_tile_cache
boolean depth_stencil; /** Is the surface a depth/stencil format? */
struct pipe_surface *tex_surf;
+ void *tex_surf_map;
int tex_face, tex_level, tex_z;
struct softpipe_cached_tile tile; /**< scratch tile for clears */
@@ -150,7 +153,7 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
{
assert(!tc->texture);
- if (tc->surface && tc->surface->map) {
+ if (tc->surface_map) {
/*assert(tc->surface != ps);*/
pipe_surface_unmap(tc->surface);
}
@@ -158,8 +161,8 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
pipe_surface_reference(&tc->surface, ps);
if (ps) {
- if (!ps->map)
- pipe_surface_map(ps);
+ if (tc->surface_map)
+ tc->surface_map = pipe_surface_map(ps);
tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM ||
ps->format == PIPE_FORMAT_Z16_UNORM ||
@@ -179,6 +182,32 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
}
+void
+sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc)
+{
+ if (tc->surface && !tc->surface_map)
+ tc->surface_map = pipe_surface_map(tc->surface);
+
+ if (tc->tex_surf && !tc->tex_surf_map)
+ tc->tex_surf_map = pipe_surface_map(tc->tex_surf);
+}
+
+
+void
+sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc)
+{
+ if (tc->surface_map) {
+ pipe_surface_unmap(tc->surface);
+ tc->surface_map = NULL;
+ }
+
+ if (tc->tex_surf_map) {
+ pipe_surface_unmap(tc->tex_surf);
+ tc->tex_surf_map = NULL;
+ }
+}
+
+
/**
* Specify the texture to cache.
*/
@@ -192,8 +221,10 @@ sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
tc->texture = texture;
- if (tc->tex_surf && tc->tex_surf->map)
+ if (tc->tex_surf_map) {
pipe_surface_unmap(tc->tex_surf);
+ tc->tex_surf_map = NULL;
+ }
pipe_surface_reference(&tc->tex_surf, NULL);
/* mark as entries as invalid/empty */
@@ -330,9 +361,6 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,
if (!ps || !ps->buffer)
return;
- 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) {
@@ -342,9 +370,9 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe->put_tile_rgba(pipe, ps,
- tile->x, tile->y, TILE_SIZE, TILE_SIZE,
- (float *) tile->data.color);
+ pipe_put_tile_rgba(pipe, ps,
+ tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+ (float *) tile->data.color);
}
tile->x = tile->y = -1; /* mark as empty */
inuse++;
@@ -391,9 +419,9 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe->put_tile_rgba(pipe, ps,
- tile->x, tile->y, TILE_SIZE, TILE_SIZE,
- (float *) tile->data.color);
+ pipe_put_tile_rgba(pipe, ps,
+ tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+ (float *) tile->data.color);
}
}
@@ -418,9 +446,9 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe->get_tile_rgba(pipe, ps,
- tile->x, tile->y, TILE_SIZE, TILE_SIZE,
- (float *) tile->data.color);
+ pipe_get_tile_rgba(pipe, ps,
+ tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+ (float *) tile->data.color);
}
}
}
@@ -475,11 +503,11 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
tc->tex_z != z) {
/* get new surface (view into texture) */
- if (tc->tex_surf && tc->tex_surf->map)
+ if (tc->tex_surf_map)
pipe_surface_unmap(tc->tex_surf);
tc->tex_surf = pipe->get_tex_surface(pipe, tc->texture, face, level, z);
- pipe_surface_map(tc->tex_surf);
+ tc->tex_surf_map = pipe_surface_map(tc->tex_surf);
tc->tex_face = face;
tc->tex_level = level;
@@ -487,9 +515,9 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
}
/* 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);
+ 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;
diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.h b/src/mesa/pipe/softpipe/sp_tile_cache.h
index 91fb2795a2..7fd1081286 100644
--- a/src/mesa/pipe/softpipe/sp_tile_cache.h
+++ b/src/mesa/pipe/softpipe/sp_tile_cache.h
@@ -74,6 +74,12 @@ extern struct pipe_surface *
sp_tile_cache_get_surface(struct softpipe_tile_cache *tc);
extern void
+sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc);
+
+extern void
+sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc);
+
+extern void
sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
struct pipe_texture *texture);