summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c3
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c12
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c15
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_vbuf.c3
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c3
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c3
-rw-r--r--src/gallium/auxiliary/pipebuffer/Makefile1
-rw-r--r--src/gallium/auxiliary/pipebuffer/SConscript1
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c100
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr.h4
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_validate.c153
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_validate.h91
-rw-r--r--src/gallium/auxiliary/util/p_debug.c254
-rw-r--r--src/gallium/auxiliary/util/p_debug_mem.c9
-rw-r--r--src/gallium/auxiliary/util/p_tile.c50
-rw-r--r--src/gallium/auxiliary/util/u_blit.c9
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c81
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c21
-rw-r--r--src/gallium/auxiliary/util/u_hash_table.c77
-rw-r--r--src/gallium/auxiliary/util/u_hash_table.h4
-rw-r--r--src/gallium/auxiliary/util/u_pack_color.h26
-rw-r--r--src/gallium/auxiliary/util/u_string.h120
-rw-r--r--src/gallium/drivers/failover/fo_context.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.c31
-rw-r--r--src/gallium/drivers/i915simple/i915_surface.c23
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c105
-rw-r--r--src/gallium/drivers/i965simple/brw_surface.c51
-rw-r--r--src/gallium/drivers/i965simple/brw_tex_layout.c10
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c35
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c22
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.h58
-rw-r--r--src/gallium/drivers/softpipe/sp_surface.c23
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c185
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h3
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c36
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.h2
-rw-r--r--src/gallium/include/pipe/p_context.h6
-rw-r--r--src/gallium/include/pipe/p_debug.h11
-rw-r--r--src/gallium/include/pipe/p_defines.h6
-rw-r--r--src/gallium/include/pipe/p_inlines.h50
-rw-r--r--src/gallium/include/pipe/p_screen.h29
-rw-r--r--src/gallium/include/pipe/p_state.h16
-rw-r--r--src/gallium/include/pipe/p_util.h3
-rw-r--r--src/gallium/include/pipe/p_winsys.h5
-rw-r--r--src/gallium/winsys/dri/intel/intel_winsys_pipe.c3
-rw-r--r--src/gallium/winsys/xlib/xm_winsys.c5
-rw-r--r--src/gallium/winsys/xlib/xm_winsys_aub.c3
48 files changed, 1345 insertions, 424 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index a1a3a9efaf3..dc5987df448 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -769,8 +769,7 @@ void cso_restore_vertex_shader(struct cso_context *ctx)
enum pipe_error cso_set_framebuffer(struct cso_context *ctx,
const struct pipe_framebuffer_state *fb)
{
- /* XXX this memcmp() fails to detect buffer size changes */
- if (1/*memcmp(&ctx->fb, fb, sizeof(*fb))*/) {
+ if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) {
ctx->fb = *fb;
ctx->pipe->set_framebuffer_state(ctx->pipe, fb);
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index f501b2aed41..6dc20f2c90a 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -415,8 +415,11 @@ aaline_create_texture(struct aaline_stage *aaline)
assert(aaline->texture->width[level] == aaline->texture->height[level]);
- surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0);
- data = pipe_surface_map(surface);
+ /* This texture is new, no need to flush.
+ */
+ surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ data = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE);
if (data == NULL)
return FALSE;
@@ -440,9 +443,8 @@ aaline_create_texture(struct aaline_stage *aaline)
}
/* unmap */
- pipe_surface_unmap(surface);
- pipe_surface_reference(&surface, NULL);
- pipe->texture_update(pipe, aaline->texture, 0, (1 << level));
+ screen->surface_unmap(screen, surface);
+ screen->tex_surface_release(screen, &surface);
}
return TRUE;
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index 73ee4198580..4bca92ff11d 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -376,8 +376,14 @@ pstip_update_texture(struct pstip_stage *pstip)
uint i, j;
ubyte *data;
- surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0);
- data = pipe_surface_map(surface);
+ /* XXX: want to avoid flushing just because we use stipple:
+ */
+ pipe->flush( pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL );
+
+ surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ data = screen->surface_map(screen, surface,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/*
* Load alpha texture.
@@ -399,9 +405,8 @@ pstip_update_texture(struct pstip_stage *pstip)
}
/* unmap */
- pipe_surface_unmap(surface);
- pipe_surface_reference(&surface, NULL);
- pipe->texture_update(pipe, pstip->texture, 0, 0x1);
+ screen->surface_unmap(screen, surface);
+ screen->tex_surface_release(screen, &surface);
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
index 86a7d1c7303..67b9a9503d2 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
@@ -427,9 +427,6 @@ static void vbuf_destroy( struct draw_stage *stage )
if(vbuf->indices)
align_free( vbuf->indices );
- if(vbuf->translate)
- vbuf->translate->release( vbuf->translate );
-
if (vbuf->render)
vbuf->render->destroy( vbuf->render );
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index 100117a9aef..b96335b7895 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -184,7 +184,8 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw )
void draw_pt_fetch_destroy( struct pt_fetch *fetch )
{
- translate_cache_destroy(fetch->cache);
+ if (fetch->cache)
+ translate_cache_destroy(fetch->cache);
FREE(fetch);
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index b7b970a297f..4ea7d4359ff 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -268,7 +268,8 @@ static void fetch_emit_destroy( struct draw_pt_middle_end *middle )
{
struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
- translate_cache_destroy(feme->cache);
+ if (feme->cache)
+ translate_cache_destroy(feme->cache);
FREE(middle);
}
diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile
index d654dbcc919..ff09011b660 100644
--- a/src/gallium/auxiliary/pipebuffer/Makefile
+++ b/src/gallium/auxiliary/pipebuffer/Makefile
@@ -11,6 +11,7 @@ C_SOURCES = \
pb_bufmgr_mm.c \
pb_bufmgr_pool.c \
pb_bufmgr_slab.c \
+ pb_validate.c \
pb_winsys.c
include ../../Makefile.template
diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript
index 604a217982e..9db0c0eae3b 100644
--- a/src/gallium/auxiliary/pipebuffer/SConscript
+++ b/src/gallium/auxiliary/pipebuffer/SConscript
@@ -10,6 +10,7 @@ pipebuffer = env.ConvenienceLibrary(
'pb_bufmgr_mm.c',
'pb_bufmgr_pool.c',
'pb_bufmgr_slab.c',
+ 'pb_validate.c',
'pb_winsys.c',
])
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
index 2fa08429715..7f236887a90 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
@@ -168,6 +168,28 @@ _fenced_buffer_remove(struct fenced_buffer *fenced_buf)
}
+static INLINE enum pipe_error
+_fenced_buffer_finish(struct fenced_buffer *fenced_buf)
+{
+ struct fenced_buffer_list *fenced_list = fenced_buf->list;
+ struct pipe_winsys *winsys = fenced_list->winsys;
+
+ debug_warning("waiting for GPU");
+
+ assert(fenced_buf->fence);
+ if(fenced_buf->fence) {
+ if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) {
+ return PIPE_ERROR;
+ }
+ /* Remove from the fenced list */
+ _fenced_buffer_remove(fenced_buf); /* TODO: remove consequents */
+ }
+
+ fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE;
+ return PIPE_OK;
+}
+
+
/**
* Free as many fenced buffers from the list head as possible.
*/
@@ -207,40 +229,6 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
}
-/**
- * Serialize writes, but allow concurrent reads.
- */
-static INLINE enum pipe_error
-fenced_buffer_serialize(struct fenced_buffer *fenced_buf, unsigned flags)
-{
- struct fenced_buffer_list *fenced_list = fenced_buf->list;
- struct pipe_winsys *winsys = fenced_list->winsys;
-
- /* Allow concurrent reads */
- if(((fenced_buf->flags | flags) & PIPE_BUFFER_USAGE_WRITE) == 0)
- return PIPE_OK;
-
- /* Wait for the CPU to finish */
- if(fenced_buf->mapcount) {
- /* FIXME: Use thread conditions variables to signal when mapcount
- * reaches zero */
- debug_warning("attemp to write concurrently to buffer");
- /* XXX: we must not fail here in order to support texture mipmap generation
- return PIPE_ERROR_RETRY;
- */
- }
-
- /* Wait for the GPU to finish */
- if(fenced_buf->fence) {
- if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0)
- return PIPE_ERROR_RETRY;
- _fenced_buffer_remove(fenced_buf);
- }
-
- return PIPE_OK;
-}
-
-
static void
fenced_buffer_destroy(struct pb_buffer *buf)
{
@@ -280,15 +268,28 @@ fenced_buffer_map(struct pb_buffer *buf,
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
void *map;
- assert((flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE) == 0);
+
+ assert(!(flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE));
+ flags &= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
- if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK)
- return NULL;
+ /* Check for GPU read/write access */
+ if(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) {
+ /* Wait for the GPU to finish writing */
+ _fenced_buffer_finish(fenced_buf);
+ }
+
+ /* Check for CPU write access (read is OK) */
+ if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) {
+ /* this is legal -- just for debugging */
+ debug_warning("concurrent CPU writes");
+ }
map = pb_map(fenced_buf->buffer, flags);
- if(map)
+ if(map) {
++fenced_buf->mapcount;
- fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+ fenced_buf->flags |= flags;
+ }
+
return map;
}
@@ -298,10 +299,12 @@ fenced_buffer_unmap(struct pb_buffer *buf)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
assert(fenced_buf->mapcount);
- pb_unmap(fenced_buf->buffer);
- --fenced_buf->mapcount;
- if(!fenced_buf->mapcount)
- fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+ if(fenced_buf->mapcount) {
+ pb_unmap(fenced_buf->buffer);
+ --fenced_buf->mapcount;
+ if(!fenced_buf->mapcount)
+ fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+ }
}
@@ -334,8 +337,10 @@ fenced_buffer_create(struct fenced_buffer_list *fenced_list,
return NULL;
buf = CALLOC_STRUCT(fenced_buffer);
- if(!buf)
+ if(!buf) {
+ pb_reference(&buffer, NULL);
return NULL;
+ }
buf->base.base.refcount = 1;
buf->base.base.alignment = buffer->base.alignment;
@@ -374,7 +379,7 @@ buffer_fence(struct pb_buffer *buf,
fenced_list = fenced_buf->list;
winsys = fenced_list->winsys;
- if(fence == fenced_buf->fence) {
+ if(!fence || fence == fenced_buf->fence) {
/* Handle the same fence case specially, not only because it is a fast
* path, but mostly to avoid serializing two writes with the same fence,
* as that would bring the hardware down to synchronous operation without
@@ -384,11 +389,6 @@ buffer_fence(struct pb_buffer *buf,
return;
}
- if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK) {
- /* FIXME: propagate error */
- (void)0;
- }
-
_glthread_LOCK_MUTEX(fenced_list->mutex);
if (fenced_buf->fence)
_fenced_buffer_remove(fenced_buf);
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
index 8de286e3f94..f6cc7a525b7 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
@@ -50,7 +50,8 @@
#define PB_BUFMGR_H_
-#include <stddef.h>
+#include "pipe/p_compiler.h"
+#include "pipe/p_error.h"
#ifdef __cplusplus
@@ -68,7 +69,6 @@ struct pipe_winsys;
*/
struct pb_manager
{
- /* XXX: we will likely need more allocation flags */
struct pb_buffer *
(*create_buffer)( struct pb_manager *mgr,
size_t size,
diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c
new file mode 100644
index 00000000000..362fd896f31
--- /dev/null
+++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c
@@ -0,0 +1,153 @@
+/**************************************************************************
+ *
+ * Copyright 2008 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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Buffer validation.
+ *
+ * @author Jose Fonseca <[email protected]>
+ */
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_error.h"
+#include "pipe/p_util.h"
+#include "pipe/p_debug.h"
+
+#include "pb_buffer.h"
+#include "pb_buffer_fenced.h"
+#include "pb_validate.h"
+
+
+#define PB_VALIDATE_INITIAL_SIZE 1 /* 512 */
+
+
+struct pb_validate
+{
+ struct pb_buffer **buffers;
+ unsigned used;
+ unsigned size;
+};
+
+
+enum pipe_error
+pb_validate_add_buffer(struct pb_validate *vl,
+ struct pb_buffer *buf)
+{
+ assert(buf);
+ if(!buf)
+ return PIPE_ERROR;
+
+ /* We only need to store one reference for each buffer, so avoid storing
+ * consecutive references for the same buffer. It might not be the more
+ * common pasttern, but it is easy to implement.
+ */
+ if(vl->used && vl->buffers[vl->used - 1] == buf) {
+ return PIPE_OK;
+ }
+
+ /* Grow the table */
+ if(vl->used == vl->size) {
+ unsigned new_size;
+ struct pb_buffer **new_buffers;
+
+ new_size = vl->size * 2;
+ if(!new_size)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ new_buffers = (struct pb_buffer **)REALLOC(vl->buffers,
+ vl->size*sizeof(struct pb_buffer *),
+ new_size*sizeof(struct pb_buffer *));
+ if(!new_buffers)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ memset(new_buffers + vl->size, 0, (new_size - vl->size)*sizeof(struct pb_buffer *));
+
+ vl->size = new_size;
+ vl->buffers = new_buffers;
+ }
+
+ assert(!vl->buffers[vl->used]);
+ pb_reference(&vl->buffers[vl->used], buf);
+ ++vl->used;
+
+ return PIPE_OK;
+}
+
+
+enum pipe_error
+pb_validate_validate(struct pb_validate *vl)
+{
+ /* FIXME: go through each buffer, ensure its not mapped, its address is
+ * available -- requires a new pb_buffer interface */
+ return PIPE_OK;
+}
+
+
+void
+pb_validate_fence(struct pb_validate *vl,
+ struct pipe_fence_handle *fence)
+{
+ unsigned i;
+ for(i = 0; i < vl->used; ++i) {
+ buffer_fence(vl->buffers[i], fence);
+ pb_reference(&vl->buffers[i], NULL);
+ }
+ vl->used = 0;
+}
+
+
+void
+pb_validate_destroy(struct pb_validate *vl)
+{
+ unsigned i;
+ for(i = 0; i < vl->used; ++i)
+ pb_reference(&vl->buffers[i], NULL);
+ FREE(vl->buffers);
+ FREE(vl);
+}
+
+
+struct pb_validate *
+pb_validate_create()
+{
+ struct pb_validate *vl;
+
+ vl = CALLOC_STRUCT(pb_validate);
+ if(!vl)
+ return NULL;
+
+ vl->size = PB_VALIDATE_INITIAL_SIZE;
+ vl->buffers = (struct pb_buffer **)CALLOC(vl->size, sizeof(struct pb_buffer *));
+ if(!vl->buffers) {
+ FREE(vl);
+ return NULL;
+ }
+
+ return vl;
+}
+
diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.h b/src/gallium/auxiliary/pipebuffer/pb_validate.h
new file mode 100644
index 00000000000..3db1d5330b9
--- /dev/null
+++ b/src/gallium/auxiliary/pipebuffer/pb_validate.h
@@ -0,0 +1,91 @@
+/**************************************************************************
+ *
+ * Copyright 2008 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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Buffer validation.
+ *
+ * @author Jose Fonseca <[email protected]>
+ */
+
+#ifndef PB_VALIDATE_H_
+#define PB_VALIDATE_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct pb_buffer;
+struct pipe_fence_handle;
+
+
+/**
+ * Buffer validation list.
+ *
+ * It holds a list of buffers to be validated and fenced when flushing.
+ */
+struct pb_validate;
+
+
+enum pipe_error
+pb_validate_add_buffer(struct pb_validate *vl,
+ struct pb_buffer *buf);
+
+/**
+ * Validate all buffers for hardware access.
+ *
+ * Should be called right before issuing commands to the hardware.
+ */
+enum pipe_error
+pb_validate_validate(struct pb_validate *vl);
+
+/**
+ * Fence all buffers and clear the list.
+ *
+ * Should be called right before issuing commands to the hardware.
+ */
+void
+pb_validate_fence(struct pb_validate *vl,
+ struct pipe_fence_handle *fence);
+
+struct pb_validate *
+pb_validate_create(void);
+
+void
+pb_validate_destroy(struct pb_validate *vl);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*PB_VALIDATE_H_*/
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index 4ec17466624..ce7fb589562 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -67,7 +67,7 @@ void _debug_vprintf(const char *format, va_list ap)
static char buf[512 + 1] = {'\0'};
size_t len = strlen(buf);
int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap);
- if(ret > (int)(sizeof(buf) - len - 1) || strchr(buf + len, '\n')) {
+ if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) {
_EngDebugPrint("%s", buf);
buf[0] = '\0';
}
@@ -154,6 +154,7 @@ debug_get_option(const char *name, const char *dfault)
{
const char *result;
#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
+#ifdef DEBUG
ULONG_PTR iFile = 0;
const void *pMap = NULL;
const char *sol, *eol, *sep;
@@ -184,6 +185,9 @@ debug_get_option(const char *name, const char *dfault)
EngUnmapFile(iFile);
}
#else
+ result = dfault;
+#endif
+#else
result = getenv(name);
if(!result)
@@ -203,15 +207,15 @@ debug_get_bool_option(const char *name, boolean dfault)
if(str == NULL)
result = dfault;
- else if(!strcmp(str, "n"))
+ else if(!util_strcmp(str, "n"))
result = FALSE;
- else if(!strcmp(str, "no"))
+ else if(!util_strcmp(str, "no"))
result = FALSE;
- else if(!strcmp(str, "0"))
+ else if(!util_strcmp(str, "0"))
result = FALSE;
- else if(!strcmp(str, "f"))
+ else if(!util_strcmp(str, "f"))
result = FALSE;
- else if(!strcmp(str, "false"))
+ else if(!util_strcmp(str, "false"))
result = FALSE;
else
result = TRUE;
@@ -244,7 +248,7 @@ debug_get_flags_option(const char *name,
else {
result = 0;
while( flags->name ) {
- if (!strcmp(str, "all") || strstr(str, flags->name ))
+ if (!util_strcmp(str, "all") || util_strstr(str, flags->name ))
result |= flags->value;
++flags;
}
@@ -299,10 +303,10 @@ debug_dump_flags(const struct debug_named_value *names,
while(names->name) {
if((names->value & value) == names->value) {
if (!first)
- strncat(output, "|", sizeof(output));
+ util_strncat(output, "|", sizeof(output));
else
first = 0;
- strncat(output, names->name, sizeof(output));
+ util_strncat(output, names->name, sizeof(output));
value &= ~names->value;
}
++names;
@@ -310,12 +314,12 @@ debug_dump_flags(const struct debug_named_value *names,
if (value) {
if (!first)
- strncat(output, "|", sizeof(output));
+ util_strncat(output, "|", sizeof(output));
else
first = 0;
util_snprintf(rest, sizeof(rest), "0x%08lx", value);
- strncat(output, rest, sizeof(output));
+ util_strncat(output, rest, sizeof(output));
}
if(first)
@@ -325,101 +329,159 @@ debug_dump_flags(const struct debug_named_value *names,
}
+static const struct debug_named_value pipe_format_names[] = {
+#ifdef DEBUG
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_NONE),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_A1R5G5B5_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_A4R4G4B4_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R5G6B5_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_I8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR_REV),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_Z16_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_FLOAT),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_S8Z24_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24S8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_X8Z24_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24X8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_S8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R64_FLOAT),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64_FLOAT),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64_FLOAT),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64A64_FLOAT),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_FLOAT),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_FLOAT),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_FLOAT),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_FLOAT),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_UNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_USCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SNORM),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SSCALED),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_SRGB),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_L8_SRGB),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SRGB),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SRGB),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SRGB),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGB),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA),
+ DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_RGBA),
+#endif
+ DEBUG_NAMED_VALUE_END
+};
-
-
+#ifdef DEBUG
+void debug_print_format(const char *msg, unsigned fmt )
+{
+ debug_printf("%s: %s\n", msg, debug_dump_enum(pipe_format_names, fmt));
+}
+#endif
char *pf_sprint_name( char *str, enum pipe_format format )
{
- strcpy( str, "PIPE_FORMAT_" );
- switch (pf_layout( format )) {
- case PIPE_FORMAT_LAYOUT_RGBAZS:
- {
- pipe_format_rgbazs_t rgbazs = (pipe_format_rgbazs_t) format;
- uint i;
- uint scale = 1 << (pf_exp8( rgbazs ) * 3);
-
- for (i = 0; i < 4; i++) {
- uint size = pf_size_xyzw( rgbazs, i );
-
- if (size == 0) {
- break;
- }
- switch (pf_swizzle_xyzw( rgbazs, i )) {
- case PIPE_FORMAT_COMP_R:
- strcat( str, "R" );
- break;
- case PIPE_FORMAT_COMP_G:
- strcat( str, "G" );
- break;
- case PIPE_FORMAT_COMP_B:
- strcat( str, "B" );
- break;
- case PIPE_FORMAT_COMP_A:
- strcat( str, "A" );
- break;
- case PIPE_FORMAT_COMP_0:
- strcat( str, "0" );
- break;
- case PIPE_FORMAT_COMP_1:
- strcat( str, "1" );
- break;
- case PIPE_FORMAT_COMP_Z:
- strcat( str, "Z" );
- break;
- case PIPE_FORMAT_COMP_S:
- strcat( str, "S" );
- break;
- }
- util_snprintf( &str[strlen( str )], 32, "%u", size * scale );
- }
- if (i != 0) {
- strcat( str, "_" );
- }
- switch (pf_type( rgbazs )) {
- case PIPE_FORMAT_TYPE_UNKNOWN:
- strcat( str, "NONE" );
- break;
- case PIPE_FORMAT_TYPE_FLOAT:
- strcat( str, "FLOAT" );
- break;
- case PIPE_FORMAT_TYPE_UNORM:
- strcat( str, "UNORM" );
- break;
- case PIPE_FORMAT_TYPE_SNORM:
- strcat( str, "SNORM" );
- break;
- case PIPE_FORMAT_TYPE_USCALED:
- strcat( str, "USCALED" );
- break;
- case PIPE_FORMAT_TYPE_SSCALED:
- strcat( str, "SSCALED" );
- break;
- }
- }
- break;
- case PIPE_FORMAT_LAYOUT_YCBCR:
- {
- pipe_format_ycbcr_t ycbcr = (pipe_format_ycbcr_t) format;
-
- strcat( str, "YCBCR" );
- if (pf_rev( ycbcr )) {
- strcat( str, "_REV" );
- }
- }
- break;
- }
+ strcpy( str, debug_dump_enum(pipe_format_names, format) );
return str;
}
#ifdef DEBUG
-void debug_print_format(const char *msg, unsigned fmt )
+void debug_dump_image(const char *prefix,
+ unsigned format, unsigned cpp,
+ unsigned width, unsigned height,
+ unsigned pitch,
+ const void *data)
{
- char fmtstr[80];
-
- pf_sprint_name(fmtstr, (enum pipe_format)fmt);
+#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
+ static unsigned no = 0;
+ char filename[256];
+ WCHAR wfilename[sizeof(filename)];
+ ULONG_PTR iFile = 0;
+ struct {
+ unsigned format;
+ unsigned cpp;
+ unsigned width;
+ unsigned height;
+ } header;
+ unsigned char *pMap = NULL;
+ unsigned i;
- debug_printf("%s: %s\n", msg, fmtstr);
+ util_snprintf(filename, sizeof(filename), "\\??\\c:\\%03u%s.raw", ++no, prefix);
+ for(i = 0; i < sizeof(filename); ++i)
+ wfilename[i] = (WCHAR)filename[i];
+
+ pMap = (unsigned char *)EngMapFile(wfilename, sizeof(header) + cpp*width*height, &iFile);
+ if(!pMap)
+ return;
+
+ header.format = format;
+ header.cpp = cpp;
+ header.width = width;
+ header.height = height;
+ memcpy(pMap, &header, sizeof(header));
+ pMap += sizeof(header);
+
+ for(i = 0; i < height; ++i) {
+ memcpy(pMap, (unsigned char *)data + cpp*pitch*i, cpp*width);
+ pMap += cpp*width;
+ }
+
+ EngUnmapFile(iFile);
+#endif
}
#endif
diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c
index 3b5e4fbaeea..78497c5f6af 100644
--- a/src/gallium/auxiliary/util/p_debug_mem.c
+++ b/src/gallium/auxiliary/util/p_debug_mem.c
@@ -211,6 +211,7 @@ debug_memory_begin(void)
void
debug_memory_end(unsigned long start_no)
{
+ size_t total_size = 0;
struct list_head *entry;
entry = list.prev;
@@ -220,9 +221,15 @@ debug_memory_end(unsigned long start_no)
hdr = LIST_ENTRY(struct debug_memory_header, entry, head);
ptr = data_from_header(hdr);
if(start_no <= hdr->no && hdr->no < last_no ||
- last_no < start_no && (hdr->no < last_no || start_no <= hdr->no))
+ last_no < start_no && (hdr->no < last_no || start_no <= hdr->no)) {
debug_printf("%s:%u:%s: %u bytes at %p not freed\n",
hdr->file, hdr->line, hdr->function,
hdr->size, ptr);
+ total_size += hdr->size;
+ }
+ }
+ if(total_size) {
+ debug_printf("Total of %u KB of system memory apparently leaked\n",
+ (total_size + 1023)/1024);
}
}
diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c
index 63e1cc6013a..5728757d2fb 100644
--- a/src/gallium/auxiliary/util/p_tile.c
+++ b/src/gallium/auxiliary/util/p_tile.c
@@ -50,6 +50,7 @@ pipe_get_tile_raw(struct pipe_context *pipe,
uint x, uint y, uint w, uint h,
void *p, int dst_stride)
{
+ struct pipe_screen *screen = pipe->screen;
const uint cpp = ps->cpp;
const ubyte *pSrc;
const uint src_stride = ps->pitch * cpp;
@@ -63,7 +64,11 @@ pipe_get_tile_raw(struct pipe_context *pipe,
if (pipe_clip_tile(x, y, &w, &h, ps))
return;
- pSrc = (const ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp;
+ pSrc = (const ubyte *) screen->surface_map(screen, ps,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ assert(pSrc); /* XXX: proper error handling! */
+
+ pSrc += (y * ps->pitch + x) * cpp;
pDest = (ubyte *) p;
for (i = 0; i < h; i++) {
@@ -72,7 +77,7 @@ pipe_get_tile_raw(struct pipe_context *pipe,
pSrc += src_stride;
}
- pipe_surface_unmap(ps);
+ screen->surface_unmap(screen, ps);
}
@@ -86,6 +91,7 @@ pipe_put_tile_raw(struct pipe_context *pipe,
uint x, uint y, uint w, uint h,
const void *p, int src_stride)
{
+ struct pipe_screen *screen = pipe->screen;
const uint cpp = ps->cpp;
const ubyte *pSrc;
const uint dst_stride = ps->pitch * cpp;
@@ -100,7 +106,11 @@ pipe_put_tile_raw(struct pipe_context *pipe,
return;
pSrc = (const ubyte *) p;
- pDest = (ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp;
+
+ pDest = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
+ assert(pDest); /* XXX: proper error handling */
+
+ pDest += (y * ps->pitch + x) * cpp;
for (i = 0; i < h; i++) {
memcpy(pDest, pSrc, w * cpp);
@@ -108,7 +118,7 @@ pipe_put_tile_raw(struct pipe_context *pipe,
pSrc += src_stride;
}
- pipe_surface_unmap(ps);
+ screen->surface_unmap(screen, ps);
}
@@ -834,18 +844,26 @@ pipe_get_tile_z(struct pipe_context *pipe,
uint x, uint y, uint w, uint h,
uint *z)
{
+ struct pipe_screen *screen = pipe->screen;
const uint dstStride = w;
+ void *map;
uint *pDest = z;
uint i, j;
if (pipe_clip_tile(x, y, &w, &h, ps))
return;
+ map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
+ if (!map) {
+ assert(0);
+ return;
+ }
+
switch (ps->format) {
case PIPE_FORMAT_Z32_UNORM:
{
const uint *pSrc
- = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
+ = (const uint *)map + (y * ps->pitch + x);
for (i = 0; i < h; i++) {
memcpy(pDest, pSrc, 4 * w);
pDest += dstStride;
@@ -857,7 +875,7 @@ pipe_get_tile_z(struct pipe_context *pipe,
case PIPE_FORMAT_X8Z24_UNORM:
{
const uint *pSrc
- = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
+ = (const uint *)map + (y * ps->pitch + x);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 24-bit Z to 32-bit Z */
@@ -871,7 +889,7 @@ pipe_get_tile_z(struct pipe_context *pipe,
case PIPE_FORMAT_Z16_UNORM:
{
const ushort *pSrc
- = (const ushort *) pipe_surface_map(ps) + (y * ps->pitch + x);
+ = (const ushort *)map + (y * ps->pitch + x);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 16-bit Z to 32-bit Z */
@@ -886,7 +904,7 @@ pipe_get_tile_z(struct pipe_context *pipe,
assert(0);
}
- pipe_surface_unmap(ps);
+ screen->surface_unmap(screen, ps);
}
@@ -896,17 +914,25 @@ pipe_put_tile_z(struct pipe_context *pipe,
uint x, uint y, uint w, uint h,
const uint *zSrc)
{
+ struct pipe_screen *screen = pipe->screen;
const uint srcStride = w;
const uint *pSrc = zSrc;
+ void *map;
uint i, j;
if (pipe_clip_tile(x, y, &w, &h, ps))
return;
+ map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
+ if (!map) {
+ assert(0);
+ return;
+ }
+
switch (ps->format) {
case PIPE_FORMAT_Z32_UNORM:
{
- uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
+ uint *pDest = (uint *) map + (y * ps->pitch + x);
for (i = 0; i < h; i++) {
memcpy(pDest, pSrc, 4 * w);
pDest += ps->pitch;
@@ -917,7 +943,7 @@ pipe_put_tile_z(struct pipe_context *pipe,
case PIPE_FORMAT_S8Z24_UNORM:
case PIPE_FORMAT_X8Z24_UNORM:
{
- uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
+ uint *pDest = (uint *) map + (y * ps->pitch + x);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 32-bit Z to 24-bit Z (0 stencil) */
@@ -930,7 +956,7 @@ pipe_put_tile_z(struct pipe_context *pipe,
break;
case PIPE_FORMAT_Z16_UNORM:
{
- ushort *pDest = (ushort *) pipe_surface_map(ps) + (y * ps->pitch + x);
+ ushort *pDest = (ushort *) map + (y * ps->pitch + x);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 32-bit Z to 16-bit Z */
@@ -945,7 +971,7 @@ pipe_put_tile_z(struct pipe_context *pipe,
assert(0);
}
- pipe_surface_unmap(ps);
+ screen->surface_unmap(screen, ps);
}
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 568d62ced19..999a3e50995 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -287,7 +287,8 @@ util_blit_pixels(struct blit_state *ctx,
if (!tex)
return;
- texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0);
+ texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
/* load temp texture */
pipe->surface_copy(pipe, FALSE,
@@ -295,7 +296,9 @@ util_blit_pixels(struct blit_state *ctx,
src, srcLeft, srcTop, /* src */
srcW, srcH); /* size */
- pipe->texture_update(pipe, tex, 0, 1 << 0);
+ /* free the surface, update the texture if necessary.
+ */
+ screen->tex_surface_release(screen, &texSurf);
/* save state (restored below) */
cso_save_blend(ctx->cso);
@@ -356,8 +359,6 @@ util_blit_pixels(struct blit_state *ctx,
cso_restore_vertex_shader(ctx->cso);
cso_restore_viewport(ctx->cso);
- /* free the texture */
- pipe_surface_reference(&texSurf, NULL);
screen->texture_release(screen, &tex);
}
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index e659edb0881..bf143815d8b 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -82,52 +82,51 @@ util_draw_texquad(struct pipe_context *pipe,
{
struct pipe_buffer *vbuf;
uint numAttribs = 2, vertexBytes, i, j;
- float *v;
vertexBytes = 4 * (4 * numAttribs * sizeof(float));
/* XXX create one-time */
vbuf = pipe->winsys->buffer_create(pipe->winsys, 32,
PIPE_BUFFER_USAGE_VERTEX, vertexBytes);
- assert(vbuf);
-
- v = (float *) pipe->winsys->buffer_map(pipe->winsys, vbuf,
- PIPE_BUFFER_USAGE_CPU_WRITE);
-
- /*
- * Load vertex buffer
- */
- for (i = j = 0; i < 4; i++) {
- v[j + 2] = z; /* z */
- v[j + 3] = 1.0; /* w */
- v[j + 6] = 0.0; /* r */
- v[j + 7] = 1.0; /* q */
- j += 8;
+ if (vbuf) {
+ float *v = (float *) pipe->winsys->buffer_map(pipe->winsys, vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ if (v) {
+ /*
+ * Load vertex buffer
+ */
+ for (i = j = 0; i < 4; i++) {
+ v[j + 2] = z; /* z */
+ v[j + 3] = 1.0; /* w */
+ v[j + 6] = 0.0; /* r */
+ v[j + 7] = 1.0; /* q */
+ j += 8;
+ }
+
+ v[0] = x0;
+ v[1] = y0;
+ v[4] = 0.0; /*s*/
+ v[5] = 0.0; /*t*/
+
+ v[8] = x1;
+ v[9] = y0;
+ v[12] = 1.0;
+ v[13] = 0.0;
+
+ v[16] = x1;
+ v[17] = y1;
+ v[20] = 1.0;
+ v[21] = 1.0;
+
+ v[24] = x0;
+ v[25] = y1;
+ v[28] = 0.0;
+ v[29] = 1.0;
+
+ pipe->winsys->buffer_unmap(pipe->winsys, vbuf);
+ util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
+ }
+
+ pipe_buffer_reference(pipe->winsys, &vbuf, NULL);
}
-
- v[0] = x0;
- v[1] = y0;
- v[4] = 0.0; /*s*/
- v[5] = 0.0; /*t*/
-
- v[8] = x1;
- v[9] = y0;
- v[12] = 1.0;
- v[13] = 0.0;
-
- v[16] = x1;
- v[17] = y1;
- v[20] = 1.0;
- v[21] = 1.0;
-
- v[24] = x0;
- v[25] = y1;
- v[28] = 0.0;
- v[29] = 1.0;
-
- pipe->winsys->buffer_unmap(pipe->winsys, vbuf);
-
- util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
-
- pipe_buffer_reference(pipe->winsys, &vbuf, NULL);
}
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index c53c5122681..7d71aefda9d 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -589,8 +589,11 @@ make_1d_mipmap(struct gen_mipmap_state *ctx,
struct pipe_surface *srcSurf, *dstSurf;
void *srcMap, *dstMap;
- srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice);
- dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
+ srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
+ dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer,
PIPE_BUFFER_USAGE_CPU_READ)
@@ -629,8 +632,10 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
struct pipe_surface *srcSurf, *dstSurf;
ubyte *srcMap, *dstMap;
- srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice);
- dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
+ srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer,
PIPE_BUFFER_USAGE_CPU_READ)
@@ -891,10 +896,14 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
const uint srcLevel = dstLevel - 1;
+ struct pipe_surface *surf =
+ screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
/*
* Setup framebuffer / dest surface
*/
- fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
+ fb.cbufs[0] = surf;
fb.width = pt->width[dstLevel];
fb.height = pt->height[dstLevel];
cso_set_framebuffer(ctx->cso, &fb);
@@ -925,7 +934,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
/* need to signal that the texture has changed _after_ rendering to it */
- pipe->texture_update(pipe, pt, face, (1 << dstLevel));
+ pipe_surface_reference( &surf, NULL );
}
/* restore state we changed */
diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c
index f3f16a8d94f..dd5eca7fca3 100644
--- a/src/gallium/auxiliary/util/u_hash_table.c
+++ b/src/gallium/auxiliary/util/u_hash_table.c
@@ -67,6 +67,13 @@ struct hash_table_item
};
+static INLINE struct hash_table_item *
+hash_table_item(struct cso_hash_iter iter)
+{
+ return (struct hash_table_item *)cso_hash_iter_data(iter);
+}
+
+
struct hash_table *
hash_table_create(unsigned (*hash)(void *key),
int (*compare)(void *key1, void *key2))
@@ -90,7 +97,27 @@ hash_table_create(unsigned (*hash)(void *key),
}
-static struct hash_table_item *
+static INLINE struct cso_hash_iter
+hash_table_find_iter(struct hash_table *ht,
+ void *key,
+ unsigned key_hash)
+{
+ struct cso_hash_iter iter;
+ struct hash_table_item *item;
+
+ iter = cso_hash_find(ht->cso, key_hash);
+ while (!cso_hash_iter_is_null(iter)) {
+ item = (struct hash_table_item *)cso_hash_iter_data(iter);
+ if (!ht->compare(item->key, key))
+ break;
+ iter = cso_hash_iter_next(iter);
+ }
+
+ return iter;
+}
+
+
+static INLINE struct hash_table_item *
hash_table_find_item(struct hash_table *ht,
void *key,
unsigned key_hash)
@@ -117,6 +144,7 @@ hash_table_set(struct hash_table *ht,
{
unsigned key_hash;
struct hash_table_item *item;
+ struct cso_hash_iter iter;
assert(ht);
@@ -136,9 +164,8 @@ hash_table_set(struct hash_table *ht,
item->key = key;
item->value = value;
- cso_hash_insert(ht->cso, key_hash, item);
- /* FIXME: there is no OOM propagation in cso_hash */
- if(0) {
+ iter = cso_hash_insert(ht->cso, key_hash, item);
+ if(cso_hash_iter_is_null(iter)) {
FREE(item);
return PIPE_ERROR_OUT_OF_MEMORY;
}
@@ -171,19 +198,39 @@ hash_table_remove(struct hash_table *ht,
void *key)
{
unsigned key_hash;
+ struct cso_hash_iter iter;
struct hash_table_item *item;
assert(ht);
key_hash = ht->hash(key);
- item = hash_table_find_item(ht, key, key_hash);
- if(!item)
+ iter = hash_table_find_iter(ht, key, key_hash);
+ if(cso_hash_iter_is_null(iter))
return;
- /* FIXME: cso_hash_take takes the first element of the collision list
- * indiscriminately, so we can not take the item down. */
- item->value = NULL;
+ item = hash_table_item(iter);
+ assert(item);
+ FREE(item);
+
+ cso_hash_erase(ht->cso, iter);
+}
+
+
+void
+hash_table_clear(struct hash_table *ht)
+{
+ struct cso_hash_iter iter;
+ struct hash_table_item *item;
+
+ assert(ht);
+
+ iter = cso_hash_first_node(ht->cso);
+ while (!cso_hash_iter_is_null(iter)) {
+ item = (struct hash_table_item *)cso_hash_take(ht->cso, cso_hash_iter_key(iter));
+ FREE(item);
+ iter = cso_hash_first_node(ht->cso);
+ }
}
@@ -196,6 +243,8 @@ hash_table_foreach(struct hash_table *ht,
struct hash_table_item *item;
enum pipe_error result;
+ assert(ht);
+
iter = cso_hash_first_node(ht->cso);
while (!cso_hash_iter_is_null(iter)) {
item = (struct hash_table_item *)cso_hash_iter_data(iter);
@@ -212,7 +261,17 @@ hash_table_foreach(struct hash_table *ht,
void
hash_table_destroy(struct hash_table *ht)
{
+ struct cso_hash_iter iter;
+ struct hash_table_item *item;
+
assert(ht);
+
+ iter = cso_hash_first_node(ht->cso);
+ while (!cso_hash_iter_is_null(iter)) {
+ item = (struct hash_table_item *)cso_hash_iter_data(iter);
+ FREE(item);
+ iter = cso_hash_iter_next(iter);
+ }
cso_hash_delete(ht->cso);
diff --git a/src/gallium/auxiliary/util/u_hash_table.h b/src/gallium/auxiliary/util/u_hash_table.h
index 1583bd7548c..feee881582e 100644
--- a/src/gallium/auxiliary/util/u_hash_table.h
+++ b/src/gallium/auxiliary/util/u_hash_table.h
@@ -75,6 +75,10 @@ hash_table_remove(struct hash_table *ht,
void *key);
+void
+hash_table_clear(struct hash_table *ht);
+
+
enum pipe_error
hash_table_foreach(struct hash_table *ht,
enum pipe_error (*callback)(void *key, void *value, void *data),
diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h
index 0b917c005f1..655e2c82592 100644
--- a/src/gallium/auxiliary/util/u_pack_color.h
+++ b/src/gallium/auxiliary/util/u_pack_color.h
@@ -101,6 +101,19 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
*d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
}
return;
+ case PIPE_FORMAT_A8_UNORM:
+ {
+ ubyte *d = (ubyte *) dest;
+ *d = a;
+ }
+ return;
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ {
+ ubyte *d = (ubyte *) dest;
+ *d = r;
+ }
+ return;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
{
float *d = (float *) dest;
@@ -198,6 +211,19 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest)
*d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
}
return;
+ case PIPE_FORMAT_A8_UNORM:
+ {
+ ubyte *d = (ubyte *) dest;
+ *d = a;
+ }
+ return;
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ {
+ ubyte *d = (ubyte *) dest;
+ *d = r;
+ }
+ return;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
{
float *d = (float *) dest;
diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h
index b99d4e8021c..73c88d87b4c 100644
--- a/src/gallium/auxiliary/util/u_string.h
+++ b/src/gallium/auxiliary/util/u_string.h
@@ -41,6 +41,8 @@
#include <stddef.h>
#include <stdarg.h>
+#include "pipe/p_compiler.h"
+
#ifdef __cplusplus
extern "C" {
@@ -48,11 +50,129 @@ extern "C" {
#ifdef WIN32
+
int util_vsnprintf(char *, size_t, const char *, va_list);
int util_snprintf(char *str, size_t size, const char *format, ...);
+
+static INLINE void
+util_vsprintf(char *str, const char *format, va_list ap)
+{
+ util_vsnprintf(str, (size_t)-1, format, ap);
+}
+
+static INLINE void
+util_sprintf(char *str, const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ util_vsnprintf(str, (size_t)-1, format, ap);
+ va_end(ap);
+}
+
+static INLINE char *
+util_strchr(const char *s, char c)
+{
+ while(*s) {
+ if(*s == c)
+ return (char *)s;
+ ++s;
+ }
+ return NULL;
+}
+
+static INLINE char*
+util_strncat(char *dst, const char *src, size_t n)
+{
+ char *p = dst + strlen(dst);
+ const char *q = src;
+ size_t i;
+
+ for (i = 0; i < n && *q != '\0'; ++i)
+ *p++ = *q++;
+ *p = '\0';
+
+ return dst;
+}
+
+static INLINE int
+util_strcmp(const char *s1, const char *s2)
+{
+ unsigned char u1, u2;
+
+ while (1) {
+ u1 = (unsigned char) *s1++;
+ u2 = (unsigned char) *s2++;
+ if (u1 != u2)
+ return u1 - u2;
+ if (u1 == '\0')
+ return 0;
+ }
+ return 0;
+}
+
+static INLINE int
+util_strncmp(const char *s1, const char *s2, size_t n)
+{
+ unsigned char u1, u2;
+
+ while (n-- > 0) {
+ u1 = (unsigned char) *s1++;
+ u2 = (unsigned char) *s2++;
+ if (u1 != u2)
+ return u1 - u2;
+ if (u1 == '\0')
+ return 0;
+ }
+ return 0;
+}
+
+static INLINE char *
+util_strstr(const char *haystack, const char *needle)
+{
+ const char *p = haystack;
+ int len = strlen(needle);
+
+ for (; (p = util_strchr(p, *needle)) != 0; p++) {
+ if (util_strncmp(p, needle, len) == 0) {
+ return (char *)p;
+ }
+ }
+ return NULL;
+}
+
+static INLINE void *
+util_memmove(void *dest, const void *src, size_t n)
+{
+ char *p = (char *)dest;
+ const char *q = (const char *)src;
+ if (dest < src) {
+ while (n--)
+ *p++ = *q++;
+ }
+ else
+ {
+ p += n;
+ q += n;
+ while (n--)
+ *--p = *--q;
+ }
+ return dest;
+}
+
+
#else
+
#define util_vsnprintf vsnprintf
#define util_snprintf snprintf
+#define util_vsprintf vsprintf
+#define util_sprintf sprintf
+#define util_strchr strchr
+#define util_strcmp strcmp
+#define util_strncmp strncmp
+#define util_strncat strncat
+#define util_strstr strstr
+#define util_memmove memmove
+
#endif
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index cb95ba516f9..014a3e31d50 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -147,8 +147,8 @@ struct pipe_context *failover_create( struct pipe_context *hw,
failover->pipe.texture_create = hw->texture_create;
failover->pipe.texture_release = hw->texture_release;
failover->pipe.get_tex_surface = hw->get_tex_surface;
-#endif
failover->pipe.texture_update = hw->texture_update;
+#endif
failover->pipe.flush = hw->flush;
diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c
index 646cfd921d1..ba8f183bdf0 100644
--- a/src/gallium/drivers/i915simple/i915_screen.c
+++ b/src/gallium/drivers/i915simple/i915_screen.c
@@ -201,6 +201,35 @@ i915_destroy_screen( struct pipe_screen *screen )
}
+static void *
+i915_surface_map( struct pipe_screen *screen,
+ struct pipe_surface *surface,
+ unsigned flags )
+{
+ char *map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags );
+ if (map == NULL)
+ return NULL;
+
+ if (surface->texture &&
+ (flags & PIPE_BUFFER_USAGE_CPU_WRITE))
+ {
+ /* Do something to notify contexts of a texture change.
+ */
+ /* i915_screen(screen)->timestamp++; */
+ }
+
+ return map + surface->offset;
+}
+
+static void
+i915_surface_unmap(struct pipe_screen *screen,
+ struct pipe_surface *surface)
+{
+ screen->winsys->buffer_unmap( screen->winsys, surface->buffer );
+}
+
+
+
/**
* Create a new i915_screen object
*/
@@ -244,6 +273,8 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
i915screen->screen.get_param = i915_get_param;
i915screen->screen.get_paramf = i915_get_paramf;
i915screen->screen.is_format_supported = i915_is_format_supported;
+ i915screen->screen.surface_map = i915_surface_map;
+ i915screen->screen.surface_unmap = i915_surface_unmap;
i915_init_screen_texture_functions(&i915screen->screen);
diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c
index f4fbedbe9bc..98367ac0739 100644
--- a/src/gallium/drivers/i915simple/i915_surface.c
+++ b/src/gallium/drivers/i915simple/i915_surface.c
@@ -51,17 +51,25 @@ i915_surface_copy(struct pipe_context *pipe,
assert( dst->cpp == src->cpp );
if (0) {
- pipe_copy_rect(pipe_surface_map(dst),
+ void *dst_map = pipe->screen->surface_map( pipe->screen,
+ dst,
+ PIPE_BUFFER_USAGE_CPU_WRITE );
+
+ const void *src_map = pipe->screen->surface_map( pipe->screen,
+ src,
+ PIPE_BUFFER_USAGE_CPU_READ );
+
+ pipe_copy_rect(dst_map,
dst->cpp,
dst->pitch,
dstx, dsty,
width, height,
- pipe_surface_map(src),
+ src_map,
do_flip ? -(int) src->pitch : src->pitch,
srcx, do_flip ? 1 - srcy - height : srcy);
- pipe_surface_unmap(src);
- pipe_surface_unmap(dst);
+ pipe->screen->surface_unmap(pipe->screen, src);
+ pipe->screen->surface_unmap(pipe->screen, dst);
}
else {
i915_copy_blit( i915_context(pipe),
@@ -92,7 +100,10 @@ i915_surface_fill(struct pipe_context *pipe,
{
if (0) {
unsigned i, j;
- void *dst_map = pipe_surface_map(dst);
+ void *dst_map = pipe->screen->surface_map( pipe->screen,
+ dst,
+ PIPE_BUFFER_USAGE_CPU_WRITE );
+
switch (dst->cpp) {
case 1: {
@@ -126,7 +137,7 @@ i915_surface_fill(struct pipe_context *pipe,
break;
}
- pipe_surface_unmap( dst );
+ pipe->screen->surface_unmap(pipe->screen, dst);
}
else {
i915_fill_blit( i915_context(pipe),
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index c39e747705b..3e23e540f9d 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -105,6 +105,51 @@ i915_miptree_set_image_offset(struct i915_texture *tex,
}
+/* Hack it up to use the old winsys->surface_alloc_storage()
+ * method for now:
+ */
+static boolean
+i915_displaytarget_layout(struct pipe_screen *screen,
+ struct i915_texture *tex)
+{
+ struct pipe_winsys *ws = screen->winsys;
+ struct pipe_surface surf;
+ unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+
+ memset(&surf, 0, sizeof(surf));
+
+ ws->surface_alloc_storage( ws,
+ &surf,
+ tex->base.width[0],
+ tex->base.height[0],
+ tex->base.format,
+ flags,
+ tex->base.tex_usage);
+
+ /* Now extract the goodies:
+ */
+ i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
+ i915_miptree_set_level_info( tex, 0, 0, 0, 0,
+ tex->base.width[0],
+ tex->base.height[0],
+ 1 );
+
+ tex->buffer = surf.buffer;
+ tex->pitch = surf.pitch;
+ tex->total_height = 0;
+
+
+ return tex->buffer != NULL;
+}
+
+
+
+
+
static void
i945_miptree_layout_2d( struct i915_texture *tex )
{
@@ -483,30 +528,45 @@ static struct pipe_texture *
i915_texture_create_screen(struct pipe_screen *screen,
const struct pipe_texture *templat)
{
+ struct i915_screen *i915screen = i915_screen(screen);
+ struct pipe_winsys *ws = screen->winsys;
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
- if (tex) {
- struct i915_screen *i915screen = i915_screen(screen);
- struct pipe_winsys *ws = screen->winsys;
-
- tex->base = *templat;
- tex->base.refcount = 1;
- tex->base.screen = screen;
+ if (!tex)
+ return NULL;
- if (i915screen->is_i945 ? i945_miptree_layout(tex) :
- i915_miptree_layout(tex))
- tex->buffer = ws->buffer_create(ws, 64,
- PIPE_BUFFER_USAGE_PIXEL,
- tex->pitch * tex->base.cpp *
- tex->total_height);
+ tex->base = *templat;
+ tex->base.refcount = 1;
+ tex->base.screen = screen;
- if (!tex->buffer) {
- FREE(tex);
- return NULL;
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+ if (!i915_displaytarget_layout(screen, tex))
+ goto fail;
+ }
+ else {
+ if (i915screen->is_i945) {
+ if (!i945_miptree_layout(tex))
+ goto fail;
+ }
+ else {
+ if (!i915_miptree_layout(tex))
+ goto fail;
}
+
+ tex->buffer = ws->buffer_create(ws, 64,
+ PIPE_BUFFER_USAGE_PIXEL,
+ tex->pitch * tex->base.cpp *
+ tex->total_height);
+
+ if (!tex->buffer)
+ goto fail;
}
return &tex->base;
+
+ fail:
+ FREE(tex);
+ return NULL;
}
@@ -541,13 +601,6 @@ i915_texture_release_screen(struct pipe_screen *screen,
}
-static void
-i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
- uint face, uint levelsMask)
-{
- /* no-op? */
-}
-
/*
* XXX note: same as code in sp_surface.c
@@ -555,7 +608,8 @@ i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
static struct pipe_surface *
i915_get_tex_surface_screen(struct pipe_screen *screen,
struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
+ unsigned face, unsigned level, unsigned zslice,
+ unsigned flags)
{
struct i915_texture *tex = (struct i915_texture *)pt;
struct pipe_winsys *ws = screen->winsys;
@@ -586,6 +640,7 @@ i915_get_tex_surface_screen(struct pipe_screen *screen,
ps->height = pt->height[level];
ps->pitch = tex->pitch;
ps->offset = offset;
+ ps->usage = flags;
}
return ps;
}
@@ -594,7 +649,7 @@ i915_get_tex_surface_screen(struct pipe_screen *screen,
void
i915_init_texture_functions(struct i915_context *i915)
{
- i915->pipe.texture_update = i915_texture_update;
+// i915->pipe.texture_update = i915_texture_update;
}
diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c
index c99a91dcf76..3e3736b2806 100644
--- a/src/gallium/drivers/i965simple/brw_surface.c
+++ b/src/gallium/drivers/i965simple/brw_surface.c
@@ -35,27 +35,6 @@
#include "util/p_tile.h"
-/* 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
-brw_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)
-{
- pipe_copy_rect(pipe_surface_map(dst) + dst->offset,
- 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.
@@ -72,17 +51,25 @@ brw_surface_copy(struct pipe_context *pipe,
assert(dst->cpp == src->cpp);
if (0) {
- pipe_copy_rect(pipe_surface_map(dst) + dst->offset,
+ void *dst_map = pipe->screen->surface_map( pipe->screen,
+ dst,
+ PIPE_BUFFER_USAGE_CPU_WRITE );
+
+ const void *src_map = pipe->screen->surface_map( pipe->screen,
+ src,
+ PIPE_BUFFER_USAGE_CPU_READ );
+
+ pipe_copy_rect(dst_map,
dst->cpp,
dst->pitch,
- dstx, dsty,
- width, height,
- pipe_surface_map(src) + src->offset,
- do_flip ? -src->pitch : src->pitch,
+ dstx, dsty,
+ width, height,
+ src_map,
+ do_flip ? -(int) src->pitch : src->pitch,
srcx, do_flip ? 1 - srcy - height : srcy);
- pipe_surface_unmap(src);
- pipe_surface_unmap(dst);
+ pipe->screen->surface_unmap(pipe->screen, src);
+ pipe->screen->surface_unmap(pipe->screen, dst);
}
else {
brw_copy_blit(brw_context(pipe),
@@ -113,7 +100,10 @@ brw_surface_fill(struct pipe_context *pipe,
{
if (0) {
unsigned i, j;
- void *dst_map = pipe_surface_map(dst);
+ void *dst_map = pipe->screen->surface_map( pipe->screen,
+ dst,
+ PIPE_BUFFER_USAGE_CPU_WRITE );
+
switch (dst->cpp) {
case 1: {
@@ -147,7 +137,7 @@ brw_surface_fill(struct pipe_context *pipe,
break;
}
- pipe_surface_unmap( dst );
+ pipe->screen->surface_unmap(pipe->screen, dst);
}
else {
brw_fill_blit(brw_context(pipe),
@@ -164,7 +154,6 @@ brw_surface_fill(struct pipe_context *pipe,
void
brw_init_surface_functions(struct brw_context *brw)
{
- (void) brw_surface_data; /* silence warning */
brw->pipe.surface_copy = brw_surface_copy;
brw->pipe.surface_fill = brw_surface_fill;
}
diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c
index b580f98204c..78ae0b1223e 100644
--- a/src/gallium/drivers/i965simple/brw_tex_layout.c
+++ b/src/gallium/drivers/i965simple/brw_tex_layout.c
@@ -357,14 +357,6 @@ brw_texture_release_screen(struct pipe_screen *screen,
}
-static void
-brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
- uint face, uint levelsMask)
-{
- /* no-op? */
-}
-
-
static struct pipe_surface *
brw_get_tex_surface_screen(struct pipe_screen *screen,
struct pipe_texture *pt,
@@ -407,7 +399,7 @@ brw_get_tex_surface_screen(struct pipe_screen *screen,
void
brw_init_texture_functions(struct brw_context *brw)
{
- brw->pipe.texture_update = brw_texture_update;
+// brw->pipe.texture_update = brw_texture_update;
}
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index fe9cd8375e3..2af0db37143 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -192,11 +192,11 @@ softpipe_create( struct pipe_screen *screen,
* Must be before quad stage setup!
*/
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
- softpipe->cbuf_cache[i] = sp_create_tile_cache();
- softpipe->zsbuf_cache = sp_create_tile_cache();
+ softpipe->cbuf_cache[i] = sp_create_tile_cache( screen );
+ softpipe->zsbuf_cache = sp_create_tile_cache( screen );
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
- softpipe->tex_cache[i] = sp_create_tile_cache();
+ softpipe->tex_cache[i] = sp_create_tile_cache( screen );
/* setup quad rendering stages */
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index 0625b69099b..e03994b63b7 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -50,25 +50,28 @@ softpipe_flush( struct pipe_context *pipe,
draw_flush(softpipe->draw);
- /* - flush the quad pipeline
- * - flush the texture cache
- * - flush the render cache
- */
+ if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
+ for (i = 0; i < softpipe->num_textures; i++) {
+ sp_flush_tile_cache(softpipe, softpipe->tex_cache[i]);
+ }
+ }
- for (i = 0; i < softpipe->framebuffer.num_cbufs; i++)
- if (softpipe->cbuf_cache[i])
- sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]);
+ if (flags & PIPE_FLUSH_RENDER_CACHE) {
+ for (i = 0; i < softpipe->framebuffer.num_cbufs; i++)
+ if (softpipe->cbuf_cache[i])
+ sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]);
- if (softpipe->zsbuf_cache)
- sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache);
+ if (softpipe->zsbuf_cache)
+ sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache);
- /* Need this call for hardware buffers before swapbuffers.
- *
- * there should probably be another/different flush-type function
- * that's called before swapbuffers because we don't always want
- * to unmap surfaces when flushing.
- */
- softpipe_unmap_surfaces(softpipe);
+ /* Need this call for hardware buffers before swapbuffers.
+ *
+ * there should probably be another/different flush-type function
+ * that's called before swapbuffers because we don't always want
+ * to unmap surfaces when flushing.
+ */
+ softpipe_unmap_surfaces(softpipe);
+ }
if (fence)
*fence = NULL;
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 7dacb1c4613..e9926bf41f9 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -33,6 +33,7 @@
#include "sp_texture.h"
#include "sp_winsys.h"
+#include "sp_screen.h"
static const char *
@@ -137,6 +138,7 @@ softpipe_destroy_screen( struct pipe_screen *screen )
}
+
/**
* Create a new pipe_screen object
* Note: we're not presently subclassing pipe_screen (no softpipe_screen).
@@ -144,22 +146,22 @@ softpipe_destroy_screen( struct pipe_screen *screen )
struct pipe_screen *
softpipe_create_screen(struct pipe_winsys *winsys)
{
- struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen);
+ struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen);
if (!screen)
return NULL;
- screen->winsys = winsys;
+ screen->base.winsys = winsys;
- screen->destroy = softpipe_destroy_screen;
+ screen->base.destroy = softpipe_destroy_screen;
- screen->get_name = softpipe_get_name;
- screen->get_vendor = softpipe_get_vendor;
- screen->get_param = softpipe_get_param;
- screen->get_paramf = softpipe_get_paramf;
- screen->is_format_supported = softpipe_is_format_supported;
+ screen->base.get_name = softpipe_get_name;
+ screen->base.get_vendor = softpipe_get_vendor;
+ screen->base.get_param = softpipe_get_param;
+ screen->base.get_paramf = softpipe_get_paramf;
+ screen->base.is_format_supported = softpipe_is_format_supported;
- softpipe_init_screen_texture_funcs(screen);
+ softpipe_init_screen_texture_funcs(&screen->base);
- return screen;
+ return &screen->base;
}
diff --git a/src/gallium/drivers/softpipe/sp_screen.h b/src/gallium/drivers/softpipe/sp_screen.h
new file mode 100644
index 00000000000..3d4bfd3e840
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_screen.h
@@ -0,0 +1,58 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <[email protected]>
+ */
+
+#ifndef SP_SCREEN_H
+#define SP_SCREEN_H
+
+#include "pipe/p_screen.h"
+#include "pipe/p_defines.h"
+
+
+
+struct softpipe_screen {
+ struct pipe_screen base;
+
+ /* Increments whenever textures are modified. Contexts can track
+ * this.
+ */
+ unsigned timestamp;
+};
+
+
+
+
+static INLINE struct softpipe_screen *
+softpipe_screen( struct pipe_screen *pipe )
+{
+ return (struct softpipe_screen *)pipe;
+}
+
+
+#endif /* SP_SCREEN_H */
diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c
index 653449c4f18..29a1e92416e 100644
--- a/src/gallium/drivers/softpipe/sp_surface.c
+++ b/src/gallium/drivers/softpipe/sp_surface.c
@@ -46,19 +46,28 @@ sp_surface_copy(struct pipe_context *pipe,
struct pipe_surface *src,
unsigned srcx, unsigned srcy, unsigned width, unsigned height)
{
+ void *dst_map = pipe->screen->surface_map( pipe->screen,
+ dst,
+ PIPE_BUFFER_USAGE_CPU_WRITE );
+
+ const void *src_map = pipe->screen->surface_map( pipe->screen,
+ src,
+ PIPE_BUFFER_USAGE_CPU_READ );
+
assert( dst->cpp == src->cpp );
+ assert(src_map && dst_map);
- pipe_copy_rect(pipe_surface_map(dst),
+ pipe_copy_rect(dst_map,
dst->cpp,
dst->pitch,
dstx, dsty,
width, height,
- pipe_surface_map(src),
+ src_map,
do_flip ? -(int) src->pitch : src->pitch,
srcx, do_flip ? 1 - srcy - height : srcy);
- pipe_surface_unmap(src);
- pipe_surface_unmap(dst);
+ pipe->screen->surface_unmap(pipe->screen, src);
+ pipe->screen->surface_unmap(pipe->screen, dst);
}
@@ -83,7 +92,9 @@ sp_surface_fill(struct pipe_context *pipe,
unsigned width, unsigned height, unsigned value)
{
unsigned i, j;
- void *dst_map = pipe_surface_map(dst);
+ void *dst_map = pipe->screen->surface_map( pipe->screen,
+ dst,
+ PIPE_BUFFER_USAGE_CPU_WRITE );
assert(dst->pitch > 0);
assert(width <= dst->pitch);
@@ -147,7 +158,7 @@ sp_surface_fill(struct pipe_context *pipe,
break;
}
- pipe_surface_unmap( dst );
+ pipe->screen->surface_unmap(pipe->screen, dst);
}
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 256586ec886..1d7a1fffe4d 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -40,6 +40,7 @@
#include "sp_state.h"
#include "sp_texture.h"
#include "sp_tile_cache.h"
+#include "sp_screen.h"
/* Simple, maximally packed layout.
@@ -51,40 +52,88 @@ static unsigned minify( unsigned d )
}
-static void
-softpipe_texture_layout(struct softpipe_texture * spt)
+/* Conventional allocation path for non-display textures:
+ */
+static boolean
+softpipe_texture_layout(struct pipe_screen *screen,
+ struct softpipe_texture * spt)
{
+ struct pipe_winsys *ws = screen->winsys;
struct pipe_texture *pt = &spt->base;
unsigned level;
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned depth = pt->depth[0];
- spt->buffer_size = 0;
+ unsigned buffer_size = 0;
for (level = 0; level <= pt->last_level; level++) {
pt->width[level] = width;
pt->height[level] = height;
pt->depth[level] = depth;
+ spt->pitch[level] = width;
- spt->level_offset[level] = spt->buffer_size;
+ spt->level_offset[level] = buffer_size;
- spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) *
- ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
- width * pt->cpp;
+ 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);
}
+
+ spt->buffer = ws->buffer_create(ws, 32,
+ PIPE_BUFFER_USAGE_PIXEL,
+ buffer_size);
+
+ return spt->buffer != NULL;
+}
+
+
+
+/* Hack it up to use the old winsys->surface_alloc_storage()
+ * method for now:
+ */
+static boolean
+softpipe_displaytarget_layout(struct pipe_screen *screen,
+ struct softpipe_texture * spt)
+{
+ struct pipe_winsys *ws = screen->winsys;
+ struct pipe_surface surf;
+ unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+
+ memset(&surf, 0, sizeof(surf));
+
+ ws->surface_alloc_storage( ws,
+ &surf,
+ spt->base.width[0],
+ spt->base.height[0],
+ spt->base.format,
+ flags,
+ spt->base.tex_usage);
+
+ /* Now extract the goodies:
+ */
+ spt->buffer = surf.buffer;
+ spt->pitch[0] = surf.pitch;
+
+ return spt->buffer != NULL;
}
+
+
+
static struct pipe_texture *
softpipe_texture_create(struct pipe_screen *screen,
const struct pipe_texture *templat)
{
- struct pipe_winsys *ws = screen->winsys;
struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
if (!spt)
return NULL;
@@ -93,19 +142,21 @@ softpipe_texture_create(struct pipe_screen *screen,
spt->base.refcount = 1;
spt->base.screen = screen;
- softpipe_texture_layout(spt);
-
- spt->buffer = ws->buffer_create(ws, 32,
- PIPE_BUFFER_USAGE_PIXEL,
- spt->buffer_size);
- if (!spt->buffer) {
- FREE(spt);
- return NULL;
+ if (spt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+ if (!softpipe_displaytarget_layout(screen, spt))
+ goto fail;
}
-
+ else {
+ if (!softpipe_texture_layout(screen, spt))
+ goto fail;
+ }
+
assert(spt->base.refcount == 1);
-
return &spt->base;
+
+ fail:
+ FREE(spt);
+ return NULL;
}
@@ -116,19 +167,10 @@ softpipe_texture_release(struct pipe_screen *screen,
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);
- /*
- DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
- */
-
pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);
-
FREE(spt);
}
*pt = NULL;
@@ -138,7 +180,8 @@ softpipe_texture_release(struct pipe_screen *screen,
static struct pipe_surface *
softpipe_get_tex_surface(struct pipe_screen *screen,
struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
+ unsigned face, unsigned level, unsigned zslice,
+ unsigned usage)
{
struct pipe_winsys *ws = screen->winsys;
struct softpipe_texture *spt = softpipe_texture(pt);
@@ -157,6 +200,24 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
ps->height = pt->height[level];
ps->pitch = ps->width;
ps->offset = spt->level_offset[level];
+ ps->usage = usage;
+
+ /* Because we are softpipe, anything that the state tracker
+ * thought was going to be done with the GPU will actually get
+ * done with the CPU. Let's adjust the flags to take that into
+ * account.
+ */
+ if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE)
+ ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE;
+
+ if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ)
+ ps->usage |= PIPE_BUFFER_USAGE_CPU_READ;
+
+
+ pipe_texture_reference(&ps->texture, pt);
+ ps->face = face;
+ ps->level = level;
+ ps->zslice = zslice;
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
@@ -172,25 +233,64 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
}
-static void
-softpipe_texture_update(struct pipe_context *pipe,
- struct pipe_texture *texture,
- uint face, uint levelsMask)
+static void
+softpipe_tex_surface_release(struct pipe_screen *screen,
+ struct pipe_surface **s)
{
- struct softpipe_context *softpipe = softpipe_context(pipe);
- uint unit;
- for (unit = 0; unit < softpipe->num_textures; unit++) {
- if (softpipe->texture[unit] == texture) {
- sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]);
- }
+ /* Effectively do the texture_update work here - if texture images
+ * needed post-processing to put them into hardware layout, this is
+ * where it would happen. For softpipe, nothing to do.
+ */
+ assert ((*s)->texture);
+ pipe_texture_reference(&(*s)->texture, NULL);
+
+ screen->winsys->surface_release(screen->winsys, s);
+}
+
+
+static void *
+softpipe_surface_map( struct pipe_screen *screen,
+ struct pipe_surface *surface,
+ unsigned flags )
+{
+ ubyte *map;
+
+ if (flags & ~surface->usage) {
+ assert(0);
+ return NULL;
+ }
+
+ map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags );
+ if (map == NULL)
+ return NULL;
+
+ /* May want to different things here depending on read/write nature
+ * of the map:
+ */
+ if (surface->texture &&
+ (flags & PIPE_BUFFER_USAGE_CPU_WRITE))
+ {
+ /* Do something to notify sharing contexts of a texture change.
+ * In softpipe, that would mean flushing the texture cache.
+ */
+ softpipe_screen(screen)->timestamp++;
}
+
+ return map + surface->offset;
+}
+
+
+static void
+softpipe_surface_unmap(struct pipe_screen *screen,
+ struct pipe_surface *surface)
+{
+ screen->winsys->buffer_unmap( screen->winsys, surface->buffer );
}
void
-softpipe_init_texture_funcs( struct softpipe_context *softpipe )
+softpipe_init_texture_funcs(struct softpipe_context *sp)
{
- softpipe->pipe.texture_update = softpipe_texture_update;
}
@@ -199,5 +299,10 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = softpipe_texture_create;
screen->texture_release = softpipe_texture_release;
+
screen->get_tex_surface = softpipe_get_tex_surface;
+ screen->tex_surface_release = softpipe_tex_surface_release;
+
+ screen->surface_map = softpipe_surface_map;
+ screen->surface_unmap = softpipe_surface_unmap;
}
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index a7322144e6f..779a9d8fc97 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -42,11 +42,11 @@ struct softpipe_texture
struct pipe_texture base;
unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS];
/* The data is held here:
*/
struct pipe_buffer *buffer;
- unsigned long buffer_size;
};
@@ -61,7 +61,6 @@ softpipe_texture(struct pipe_texture *pt)
extern void
softpipe_init_texture_funcs( struct softpipe_context *softpipe );
-
extern void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen);
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index 1117c0ad4c7..28c29da87c9 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -49,6 +49,7 @@
struct softpipe_tile_cache
{
+ struct pipe_screen *screen;
struct pipe_surface *surface; /**< the surface we're caching */
void *surface_map;
struct pipe_texture *texture; /**< if caching a texture */
@@ -109,13 +110,14 @@ clear_clear_flag(uint *bitvec, int x, int y)
struct softpipe_tile_cache *
-sp_create_tile_cache(void)
+sp_create_tile_cache( struct pipe_screen *screen )
{
struct softpipe_tile_cache *tc;
uint pos;
tc = CALLOC_STRUCT( softpipe_tile_cache );
if (tc) {
+ tc->screen = screen;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
tc->entries[pos].x =
tc->entries[pos].y = -1;
@@ -154,16 +156,17 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
assert(!tc->texture);
if (tc->surface_map) {
- /*assert(tc->surface != ps);*/
- pipe_surface_unmap(tc->surface);
+ tc->screen->surface_unmap(tc->screen, tc->surface);
tc->surface_map = NULL;
}
pipe_surface_reference(&tc->surface, ps);
- if (ps) {
- if (tc->surface_map)
- tc->surface_map = pipe_surface_map(ps);
+ if (tc->surface) {
+ if (tc->surface_map) /* XXX: this is always NULL!? */
+ tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface,
+ PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE);
tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM ||
ps->format == PIPE_FORMAT_Z16_UNORM ||
@@ -187,10 +190,13 @@ 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);
+ tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface,
+ PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_CPU_READ);
if (tc->tex_surf && !tc->tex_surf_map)
- tc->tex_surf_map = pipe_surface_map(tc->tex_surf);
+ tc->tex_surf_map = tc->screen->surface_map(tc->screen, tc->tex_surf,
+ PIPE_BUFFER_USAGE_CPU_READ);
}
@@ -198,12 +204,12 @@ void
sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc)
{
if (tc->surface_map) {
- pipe_surface_unmap(tc->surface);
+ tc->screen->surface_unmap(tc->screen, tc->surface);
tc->surface_map = NULL;
}
if (tc->tex_surf_map) {
- pipe_surface_unmap(tc->tex_surf);
+ tc->screen->surface_unmap(tc->screen, tc->tex_surf);
tc->tex_surf_map = NULL;
}
}
@@ -224,7 +230,7 @@ sp_tile_cache_set_texture(struct pipe_context *pipe,
pipe_texture_reference(&tc->texture, texture);
if (tc->tex_surf_map) {
- pipe_surface_unmap(tc->tex_surf);
+ tc->screen->surface_unmap(tc->screen, tc->tex_surf);
tc->tex_surf_map = NULL;
}
pipe_surface_reference(&tc->tex_surf, NULL);
@@ -514,10 +520,12 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
/* get new surface (view into texture) */
if (tc->tex_surf_map)
- pipe_surface_unmap(tc->tex_surf);
+ tc->screen->surface_unmap(tc->screen, tc->tex_surf);
- tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z);
- tc->tex_surf_map = pipe_surface_map(tc->tex_surf);
+ tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ tc->tex_surf_map = screen->surface_map(screen, tc->tex_surf,
+ PIPE_BUFFER_USAGE_CPU_READ);
tc->tex_face = face;
tc->tex_level = level;
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h
index 2631e29a3a6..bc96c941f61 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.h
@@ -61,7 +61,7 @@ struct softpipe_cached_tile
extern struct softpipe_tile_cache *
-sp_create_tile_cache(void);
+sp_create_tile_cache( struct pipe_screen *screen );
extern void
sp_destroy_tile_cache(struct softpipe_tile_cache *tc);
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index f3a9c2cd8b2..0f68f592f77 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -198,12 +198,6 @@ struct pipe_context {
/*@}*/
- /** Called when texture data is changed */
- void (*texture_update)(struct pipe_context *pipe,
- struct pipe_texture *texture,
- uint face, uint dirtyLevelsMask);
-
-
/** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */
void (*flush)( struct pipe_context *pipe,
unsigned flags,
diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h
index 7a7312ea122..1263d0da619 100644
--- a/src/gallium/include/pipe/p_debug.h
+++ b/src/gallium/include/pipe/p_debug.h
@@ -313,6 +313,17 @@ void
debug_memory_end(unsigned long beginning);
+#ifdef DEBUG
+void debug_dump_image(const char *prefix,
+ unsigned format, unsigned cpp,
+ unsigned width, unsigned height,
+ unsigned pitch,
+ const void *data);
+#else
+#define debug_dump_image(prefix, format, cpp, width, height, pitch, data) ((void)0)
+#endif
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 46a355daa21..83330ef22fe 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -174,6 +174,12 @@ enum pipe_texture_target {
/**
+ * Surface layout
+ */
+#define PIPE_SURFACE_LAYOUT_LINEAR 0
+
+
+/**
* Surface status
*/
#define PIPE_SURFACE_STATUS_UNDEFINED 0
diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h
index 8eb604e73f1..1e4b98edb48 100644
--- a/src/gallium/include/pipe/p_inlines.h
+++ b/src/gallium/include/pipe/p_inlines.h
@@ -39,21 +39,40 @@ extern "C" {
#endif
+/* XXX: these are a kludge. will fix when all surfaces are views into
+ * textures, and free-floating winsys surfaces go away.
+ */
static INLINE void *
-pipe_surface_map(struct pipe_surface *surface)
+pipe_surface_map( struct pipe_surface *surf, unsigned flags )
{
- return (char *)surface->winsys->buffer_map( surface->winsys, surface->buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_CPU_READ )
- + surface->offset;
+ if (surf->texture) {
+ struct pipe_screen *screen = surf->texture->screen;
+ return surf->texture->screen->surface_map( screen, surf, flags );
+ }
+ else {
+ struct pipe_winsys *winsys = surf->winsys;
+ char *map = (char *)winsys->buffer_map( winsys, surf->buffer, flags );
+ if (map == NULL)
+ return NULL;
+ return (void *)(map + surf->offset);
+ }
}
static INLINE void
-pipe_surface_unmap(struct pipe_surface *surface)
+pipe_surface_unmap( struct pipe_surface *surf )
{
- surface->winsys->buffer_unmap( surface->winsys, surface->buffer );
+ if (surf->texture) {
+ struct pipe_screen *screen = surf->texture->screen;
+ surf->texture->screen->surface_unmap( screen, surf );
+ }
+ else {
+ struct pipe_winsys *winsys = surf->winsys;
+ winsys->buffer_unmap( winsys, surf->buffer );
+ }
}
+
+
/**
* Set 'ptr' to point to 'surf' and update reference counting.
* The old thing pointed to, if any, will be unreferenced first.
@@ -66,9 +85,20 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
if (surf)
surf->refcount++;
- if (*ptr /* && --(*ptr)->refcount == 0 */) {
- struct pipe_winsys *winsys = (*ptr)->winsys;
- winsys->surface_release(winsys, ptr);
+ if (*ptr) {
+
+ /* There are currently two sorts of surfaces... This needs to be
+ * fixed so that all surfaces are views into a texture.
+ */
+ if ((*ptr)->texture) {
+ struct pipe_screen *screen = (*ptr)->texture->screen;
+ screen->tex_surface_release( screen, ptr );
+ }
+ else {
+ struct pipe_winsys *winsys = (*ptr)->winsys;
+ winsys->surface_release(winsys, ptr);
+ }
+
assert(!*ptr);
}
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 26ac99d287d..cc8430dae16 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -89,6 +89,18 @@ struct pipe_screen {
struct pipe_texture * (*texture_create)(struct pipe_screen *,
const struct pipe_texture *templat);
+ /**
+ * Create a new texture object, using the given template info, but on top of
+ * existing memory.
+ *
+ * It is assumed that the buffer data is layed out according to the expected
+ * by the hardware. NULL will be returned if any inconsistency is found.
+ */
+ struct pipe_texture * (*texture_blanket)(struct pipe_screen *,
+ const struct pipe_texture *templat,
+ const unsigned *pitch,
+ struct pipe_buffer *buffer);
+
void (*texture_release)(struct pipe_screen *,
struct pipe_texture **pt);
@@ -96,7 +108,22 @@ struct pipe_screen {
struct pipe_surface *(*get_tex_surface)(struct pipe_screen *,
struct pipe_texture *texture,
unsigned face, unsigned level,
- unsigned zslice);
+ unsigned zslice,
+ unsigned usage );
+
+ /* Surfaces allocated by the above must be released here:
+ */
+ void (*tex_surface_release)( struct pipe_screen *,
+ struct pipe_surface ** );
+
+
+ void *(*surface_map)( struct pipe_screen *,
+ struct pipe_surface *surface,
+ unsigned flags );
+
+ void (*surface_unmap)( struct pipe_screen *,
+ struct pipe_surface *surface );
+
};
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 912d84e7b99..e7ee8c97ed7 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -271,12 +271,26 @@ struct pipe_surface
unsigned width;
unsigned height;
unsigned pitch; /**< in pixels */
+ unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */
unsigned offset; /**< offset from start of buffer, in bytes */
unsigned refcount;
+ unsigned usage; /**< PIPE_BUFFER_USAGE_* */
+
struct pipe_winsys *winsys; /**< winsys which owns/created the surface */
+
+ struct pipe_texture *texture; /**< optional texture into which this is a view */
+ unsigned face;
+ unsigned level;
+ unsigned zslice;
};
+#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1
+#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */
+#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */
+#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8
+#define PIPE_TEXTURE_USAGE_SAMPLER 0x10
+
/**
* Texture object.
*/
@@ -292,6 +306,8 @@ struct pipe_texture
unsigned cpp:8;
unsigned last_level:8; /**< Index of last mipmap level present/defined */
unsigned compressed:1;
+
+ unsigned tex_usage; /* PIPE_TEXTURE_USAGE_* */
/* These are also refcounted:
*/
diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h
index 0e7e2466662..0d8ed167b2a 100644
--- a/src/gallium/include/pipe/p_util.h
+++ b/src/gallium/include/pipe/p_util.h
@@ -204,7 +204,10 @@ mem_dup(const void *src, uint size)
#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) )
+#ifndef Elements
#define Elements(x) (sizeof(x)/sizeof((x)[0]))
+#endif
+
#define Offset(TYPE, MEMBER) ((unsigned)&(((TYPE *)NULL)->MEMBER))
/**
diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h
index 3005ec2d941..7ebc2851928 100644
--- a/src/gallium/include/pipe/p_winsys.h
+++ b/src/gallium/include/pipe/p_winsys.h
@@ -86,11 +86,12 @@ struct pipe_winsys
struct pipe_surface *surf,
unsigned width, unsigned height,
enum pipe_format format,
- unsigned flags);
+ unsigned flags,
+ unsigned tex_usage);
void (*surface_release)(struct pipe_winsys *ws, struct pipe_surface **s);
-
+
/**
* Buffer management. Buffer attributes are mostly fixed over its lifetime.
*
diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c
index 77dec9488df..d15143acfd4 100644
--- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c
+++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c
@@ -206,7 +206,8 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys,
struct pipe_surface *surf,
unsigned width, unsigned height,
enum pipe_format format,
- unsigned flags)
+ unsigned flags,
+ unsigned tex_usage)
{
const unsigned alignment = 64;
int ret;
diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c
index 14c3892559b..b14758f3336 100644
--- a/src/gallium/winsys/xlib/xm_winsys.c
+++ b/src/gallium/winsys/xlib/xm_winsys.c
@@ -489,7 +489,8 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys,
struct pipe_surface *surf,
unsigned width, unsigned height,
enum pipe_format format,
- unsigned flags)
+ unsigned flags,
+ unsigned tex_usage)
{
const unsigned alignment = 64;
@@ -498,6 +499,7 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys,
surf->format = format;
surf->cpp = pf_get_size(format);
surf->pitch = round_up(width, alignment / surf->cpp);
+ surf->usage = flags;
#ifdef GALLIUM_CELL /* XXX a bit of a hack */
height = round_up(height, TILE_SIZE);
@@ -551,6 +553,7 @@ static void
xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
{
struct pipe_surface *surf = *s;
+ assert(!surf->texture);
surf->refcount--;
if (surf->refcount == 0) {
if (surf->buffer)
diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c
index f42f7fcc5f1..77376099f0d 100644
--- a/src/gallium/winsys/xlib/xm_winsys_aub.c
+++ b/src/gallium/winsys/xlib/xm_winsys_aub.c
@@ -276,7 +276,8 @@ aub_i915_surface_alloc_storage(struct pipe_winsys *winsys,
struct pipe_surface *surf,
unsigned width, unsigned height,
enum pipe_format format,
- unsigned flags)
+ unsigned flags,
+ unsigned tex_usage)
{
const unsigned alignment = 64;