summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/README.portability2
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c13
-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.h13
-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_bufmgr_slab.c23
-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/SConscript1
-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_debug_prof.c175
-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_state.c2
-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.h22
-rw-r--r--src/gallium/include/pipe/p_defines.h6
-rw-r--r--src/gallium/include/pipe/p_format.h3
-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.h1
-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
-rw-r--r--src/mesa/state_tracker/st_atom.c3
-rw-r--r--src/mesa/state_tracker/st_atom.h1
-rw-r--r--src/mesa/state_tracker/st_atom_framebuffer.c65
-rw-r--r--src/mesa/state_tracker/st_atom_pixeltransfer.c12
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c28
-rw-r--r--src/mesa/state_tracker/st_atom_texture.c80
-rw-r--r--src/mesa/state_tracker/st_cb_accum.c85
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c36
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c107
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c189
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.h6
-rw-r--r--src/mesa/state_tracker/st_cb_feedback.c7
-rw-r--r--src/mesa/state_tracker/st_cb_program.c1
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c41
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c108
-rw-r--r--src/mesa/state_tracker/st_context.h3
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c6
-rw-r--r--src/mesa/state_tracker/st_texture.c61
-rw-r--r--src/mesa/state_tracker/st_texture.h14
74 files changed, 2139 insertions, 721 deletions
diff --git a/src/gallium/README.portability b/src/gallium/README.portability
index 18a97f449b4..d5d5987a7ff 100644
--- a/src/gallium/README.portability
+++ b/src/gallium/README.portability
@@ -6,7 +6,7 @@
The state tracker and winsys driver support a rather limited number of
platforms. However, the pipe drivers are meant to run in a wide number of
platforms. Hence the pipe drivers, the auxiliary modules, and all public
-headers in general, should stricly follow these guidelines to ensure
+headers in general, should strictly follow these guidelines to ensure
= Compiler Support =
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index a1a3a9efaf3..af4af8ac1d4 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -292,7 +292,7 @@ enum pipe_error cso_set_blend(struct cso_context *ctx,
if (!cso)
return PIPE_ERROR_OUT_OF_MEMORY;
- cso->state = *templ;
+ memcpy(&cso->state, templ, sizeof(*templ));
cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state);
cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state;
cso->context = ctx->pipe;
@@ -350,7 +350,7 @@ enum pipe_error cso_single_sampler(struct cso_context *ctx,
if (!cso)
return PIPE_ERROR_OUT_OF_MEMORY;
- cso->state = *templ;
+ memcpy(&cso->state, templ, sizeof(*templ));
cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state);
cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state;
cso->context = ctx->pipe;
@@ -508,7 +508,7 @@ enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx,
if (!cso)
return PIPE_ERROR_OUT_OF_MEMORY;
- cso->state = *templ;
+ memcpy(&cso->state, templ, sizeof(*templ));
cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &cso->state);
cso->delete_state = (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state;
cso->context = ctx->pipe;
@@ -564,7 +564,7 @@ enum pipe_error cso_set_rasterizer(struct cso_context *ctx,
if (!cso)
return PIPE_ERROR_OUT_OF_MEMORY;
- cso->state = *templ;
+ memcpy(&cso->state, templ, sizeof(*templ));
cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state);
cso->delete_state = (cso_state_callback)ctx->pipe->delete_rasterizer_state;
cso->context = ctx->pipe;
@@ -726,7 +726,7 @@ enum pipe_error cso_set_vertex_shader(struct cso_context *ctx,
if (!cso)
return PIPE_ERROR_OUT_OF_MEMORY;
- cso->state = *templ;
+ memcpy(cso->state, templ, sizeof(*templ));
cso->data = ctx->pipe->create_vs_state(ctx->pipe, &cso->state);
cso->delete_state = (cso_state_callback)ctx->pipe->delete_vs_state;
cso->context = ctx->pipe;
@@ -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 346a96e37fd..b1ed8aa24ea 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 2dfd1800d55..4c92416eb19 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.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
index 49705cb8627..857ea53c786 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
@@ -146,6 +146,8 @@ pb_map(struct pb_buffer *buf,
unsigned flags)
{
assert(buf);
+ if(!buf)
+ return NULL;
return buf->vtbl->map(buf, flags);
}
@@ -154,6 +156,8 @@ static INLINE void
pb_unmap(struct pb_buffer *buf)
{
assert(buf);
+ if(!buf)
+ return;
buf->vtbl->unmap(buf);
}
@@ -163,6 +167,12 @@ pb_get_base_buffer( struct pb_buffer *buf,
struct pb_buffer **base_buf,
unsigned *offset )
{
+ assert(buf);
+ if(!buf) {
+ base_buf = NULL;
+ offset = 0;
+ return;
+ }
buf->vtbl->get_base_buffer(buf, base_buf, offset);
}
@@ -171,7 +181,8 @@ static INLINE void
pb_destroy(struct pb_buffer *buf)
{
assert(buf);
- assert(buf->vtbl);
+ if(!buf)
+ return;
buf->vtbl->destroy(buf);
}
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_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c
index b931455056e..45ba158a4d9 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c
@@ -47,9 +47,6 @@
#include "pb_bufmgr.h"
-#define DRI_SLABPOOL_ALLOC_RETRIES 100
-
-
struct pb_slab;
struct pb_slab_buffer
@@ -313,7 +310,6 @@ pb_slab_manager_create_buffer(struct pb_manager *_mgr,
static struct pb_slab_buffer *buf;
struct pb_slab *slab;
struct list_head *list;
- int count = DRI_SLABPOOL_ALLOC_RETRIES;
/* check size */
assert(size == mgr->bufSize);
@@ -331,23 +327,14 @@ pb_slab_manager_create_buffer(struct pb_manager *_mgr,
/* XXX: check for compatible buffer usage too? */
_glthread_LOCK_MUTEX(mgr->mutex);
- while (mgr->slabs.next == &mgr->slabs && count > 0) {
- if (mgr->slabs.next != &mgr->slabs)
- break;
-
- _glthread_UNLOCK_MUTEX(mgr->mutex);
- if (count != DRI_SLABPOOL_ALLOC_RETRIES)
- util_time_sleep(1);
- _glthread_LOCK_MUTEX(mgr->mutex);
+ if (mgr->slabs.next == &mgr->slabs) {
(void) pb_slab_create(mgr);
- count--;
+ if (mgr->slabs.next == &mgr->slabs) {
+ _glthread_UNLOCK_MUTEX(mgr->mutex);
+ return NULL;
+ }
}
-
list = mgr->slabs.next;
- if (list == &mgr->slabs) {
- _glthread_UNLOCK_MUTEX(mgr->mutex);
- return NULL;
- }
slab = LIST_ENTRY(struct pb_slab, list, head);
if (--slab->numFree == 0)
LIST_DELINIT(list);
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/SConscript b/src/gallium/auxiliary/util/SConscript
index d55d2c70818..0309de1ac22 100644
--- a/src/gallium/auxiliary/util/SConscript
+++ b/src/gallium/auxiliary/util/SConscript
@@ -5,6 +5,7 @@ util = env.ConvenienceLibrary(
source = [
'p_debug.c',
'p_debug_mem.c',
+ 'p_debug_prof.c',
'p_tile.c',
'p_util.c',
'u_blit.c',
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_debug_prof.c b/src/gallium/auxiliary/util/p_debug_prof.c
new file mode 100644
index 00000000000..958f99c327c
--- /dev/null
+++ b/src/gallium/auxiliary/util/p_debug_prof.c
@@ -0,0 +1,175 @@
+/**************************************************************************
+ *
+ * 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
+ * Poor-man profiling.
+ *
+ * @author José Fonseca <[email protected]>
+ *
+ * @sa http://blogs.msdn.com/joshpoley/archive/2008/03/12/poor-man-s-profiler.aspx
+ * @sa http://www.johnpanzer.com/aci_cuj/index.html
+ */
+
+#include "pipe/p_config.h"
+
+#if defined(PROFILE) && defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
+
+#include <windows.h>
+#include <winddi.h>
+
+#include "pipe/p_debug.h"
+#include "util/u_string.h"
+
+
+#define PROFILE_FILE_SIZE 4*1024*1024
+#define FILE_NAME_SIZE 256
+
+static WCHAR wFileName[FILE_NAME_SIZE];
+static ULONG_PTR iFile = 0;
+static void *pMap = NULL;
+static void *pMapEnd = NULL;
+
+
+/**
+ * Called at the start of every method or function.
+ *
+ * @sa http://msdn.microsoft.com/en-us/library/c63a9b7h.aspx
+ */
+void __declspec(naked) __cdecl
+_penter(void) {
+ _asm {
+ push ebx
+ mov ebx, [pMap]
+ test ebx, ebx
+ jz done
+ cmp ebx, [pMapEnd]
+ je done
+ push eax
+ push edx
+ mov eax, [esp+12]
+ and eax, 0xfffffffe
+ mov [ebx], eax
+ add ebx, 4
+ rdtsc
+ mov [ebx], eax
+ add ebx, 4
+ mov [pMap], ebx
+ pop edx
+ pop eax
+done:
+ pop ebx
+ ret
+ }
+}
+
+
+/**
+ * Called at the end of Calls the end of every method or function.
+ *
+ * @sa http://msdn.microsoft.com/en-us/library/xc11y76y.aspx
+ */
+void __declspec(naked) __cdecl
+_pexit(void) {
+ _asm {
+ push ebx
+ mov ebx, [pMap]
+ test ebx, ebx
+ jz done
+ cmp ebx, [pMapEnd]
+ je done
+ push eax
+ push edx
+ mov eax, [esp+12]
+ or eax, 0x00000001
+ mov [ebx], eax
+ add ebx, 4
+ rdtsc
+ mov [ebx], eax
+ add ebx, 4
+ mov [pMap], ebx
+ pop edx
+ pop eax
+done:
+ pop ebx
+ ret
+ }
+}
+
+
+void __declspec(naked)
+__debug_profile_reference1(void) {
+ _asm {
+ call _penter
+ call _pexit
+ ret
+ }
+}
+
+
+void __declspec(naked)
+__debug_profile_reference2(void) {
+ _asm {
+ call _penter
+ call __debug_profile_reference1
+ call _pexit
+ ret
+ }
+}
+
+
+void
+debug_profile_start(void)
+{
+ static unsigned no = 0;
+ char filename[FILE_NAME_SIZE];
+ unsigned i;
+
+ util_snprintf(filename, sizeof(filename), "\\??\\c:\\%03u.prof", ++no);
+ for(i = 0; i < FILE_NAME_SIZE; ++i)
+ wFileName[i] = (WCHAR)filename[i];
+
+ pMap = EngMapFile(wFileName, PROFILE_FILE_SIZE, &iFile);
+ if(pMap) {
+ pMapEnd = (unsigned char*)pMap + PROFILE_FILE_SIZE;
+ /* reference functions for calibration purposes */
+ __debug_profile_reference2();
+ }
+}
+
+void
+debug_profile_stop(void)
+{
+ if(iFile) {
+ EngUnmapFile(iFile);
+ /* TODO: truncate file */
+ }
+ iFile = 0;
+ pMapEnd = pMap = NULL;
+}
+
+#endif /* PROFILE */
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_state.c b/src/gallium/drivers/i915simple/i915_state.c
index 964bd7c871c..e6c4671700e 100644
--- a/src/gallium/drivers/i915simple/i915_state.c
+++ b/src/gallium/drivers/i915simple/i915_state.c
@@ -466,7 +466,7 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader)
FREE(ifs->program);
ifs->program_len = 0;
- FREE(ifs->state.tokens);
+ FREE((struct tgsi_token *)ifs->state.tokens);
FREE(ifs);
}
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..0af635be573 100644
--- a/src/gallium/include/pipe/p_debug.h
+++ b/src/gallium/include/pipe/p_debug.h
@@ -313,6 +313,28 @@ void
debug_memory_end(unsigned long beginning);
+#if defined(PROFILE) && defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
+
+void
+debug_profile_start(void);
+
+void
+debug_profile_stop(void);
+
+#endif
+
+
+#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_format.h b/src/gallium/include/pipe/p_format.h
index a4bd23c302a..9ba00f8d7b6 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -307,6 +307,9 @@ enum pipe_format {
PIPE_FORMAT_R8G8B8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SNORM ),
PIPE_FORMAT_R8G8B8A8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ),
PIPE_FORMAT_R8G8B8X8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ),
+ PIPE_FORMAT_B6G5R5_SNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_BGR1, 6, 5, 5, 0, PIPE_FORMAT_TYPE_SNORM ),
+ PIPE_FORMAT_A8B8G8R8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGRA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ),
+ PIPE_FORMAT_X8B8G8R8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ),
PIPE_FORMAT_R8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ),
PIPE_FORMAT_R8G8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SSCALED ),
PIPE_FORMAT_R8G8B8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SSCALED ),
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 a66ab765f72..597354ca96c 100644
--- a/src/gallium/include/pipe/p_util.h
+++ b/src/gallium/include/pipe/p_util.h
@@ -204,7 +204,6 @@ mem_dup(const void *src, uint size)
#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) )
-/* JB stop warnings */
#ifndef Elements
#define Elements(x) (sizeof(x)/sizeof((x)[0]))
#endif
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 6a42c790337..10e1a84cc12 100644
--- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c
+++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c
@@ -220,7 +220,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;
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index 18063adc79c..ecfd1179189 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -45,10 +45,10 @@
*/
static const struct st_tracked_state *atoms[] =
{
- &st_update_framebuffer,
&st_update_depth_stencil_alpha,
&st_update_clip,
+ &st_finalize_textures,
&st_update_shader,
&st_update_rasterizer,
@@ -58,6 +58,7 @@ static const struct st_tracked_state *atoms[] =
&st_update_blend,
&st_update_sampler,
&st_update_texture,
+ &st_update_framebuffer,
&st_update_vs_constants,
&st_update_fs_constants,
&st_update_pixel_transfer
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
index c6c6eba8121..c7cffd85c8a 100644
--- a/src/mesa/state_tracker/st_atom.h
+++ b/src/mesa/state_tracker/st_atom.h
@@ -55,6 +55,7 @@ extern const struct st_tracked_state st_update_scissor;
extern const struct st_tracked_state st_update_blend;
extern const struct st_tracked_state st_update_sampler;
extern const struct st_tracked_state st_update_texture;
+extern const struct st_tracked_state st_finalize_textures;
extern const struct st_tracked_state st_update_fs_constants;
extern const struct st_tracked_state st_update_vs_constants;
extern const struct st_tracked_state st_update_pixel_transfer;
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index 0a6974d8a7f..d46c3ee16c5 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -34,13 +34,60 @@
#include "st_context.h"
#include "st_atom.h"
#include "st_cb_fbo.h"
+#include "st_texture.h"
#include "pipe/p_context.h"
+#include "pipe/p_inlines.h"
#include "cso_cache/cso_context.h"
+
+/**
+ * When doing GL render to texture, we have to be sure that finalize_texture()
+ * didn't yank out the pipe_texture that we earlier created a surface for.
+ * Check for that here and create a new surface if needed.
+ */
+static void
+update_renderbuffer_surface(struct st_context *st,
+ struct st_renderbuffer *strb)
+{
+ struct pipe_screen *screen = st->pipe->screen;
+ struct pipe_texture *texture = strb->rtt->pt;
+ int rtt_width = strb->Base.Width;
+ int rtt_height = strb->Base.Height;
+
+ if (!strb->surface ||
+ strb->surface->texture != texture ||
+ strb->surface->width != rtt_width ||
+ strb->surface->height != rtt_height) {
+ int level;
+ /* find matching mipmap level size */
+ for (level = 0; level <= texture->last_level; level++) {
+ if (texture->width[level] == rtt_width &&
+ texture->height[level] == rtt_height) {
+
+ pipe_surface_reference(&strb->surface, NULL);
+
+ strb->surface = screen->get_tex_surface(screen,
+ texture,
+ strb->rtt_face,
+ level,
+ strb->rtt_slice,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+#if 0
+ printf("-- alloc new surface %d x %d into tex %p\n",
+ strb->surface->width, strb->surface->height,
+ texture);
+#endif
+ break;
+ }
+ }
+ }
+}
+
+
/**
* Update framebuffer state (color, depth, stencil, etc. buffers)
- * XXX someday: separate draw/read buffers.
*/
static void
update_framebuffer_state( struct st_context *st )
@@ -55,6 +102,8 @@ update_framebuffer_state( struct st_context *st )
framebuffer->width = fb->Width;
framebuffer->height = fb->Height;
+ /*printf("------ fb size %d x %d\n", fb->Width, fb->Height);*/
+
/* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state
* to determine which surfaces to draw to
*/
@@ -62,6 +111,13 @@ update_framebuffer_state( struct st_context *st )
for (j = 0; j < MAX_DRAW_BUFFERS; j++) {
for (i = 0; i < fb->_NumColorDrawBuffers[j]; i++) {
strb = st_renderbuffer(fb->_ColorDrawBuffers[j][i]);
+
+ /*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/
+ if (strb->rtt) {
+ /* rendering to a GL texture, may have to update surface */
+ update_renderbuffer_surface(st, strb);
+ }
+
assert(strb->surface);
framebuffer->cbufs[framebuffer->num_cbufs] = strb->surface;
framebuffer->num_cbufs++;
@@ -71,6 +127,11 @@ update_framebuffer_state( struct st_context *st )
strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
if (strb) {
strb = st_renderbuffer(strb->Base.Wrapped);
+ if (strb->rtt) {
+ /* rendering to a GL texture, may have to update surface */
+ update_renderbuffer_surface(st, strb);
+ }
+
assert(strb->surface);
framebuffer->zsbuf = strb->surface;
}
@@ -99,7 +160,7 @@ const struct st_tracked_state st_update_framebuffer = {
"st_update_framebuffer", /* name */
{ /* dirty */
_NEW_BUFFERS, /* mesa */
- 0, /* st */
+ ST_NEW_FRAMEBUFFER, /* st */
},
update_framebuffer_state /* update */
};
diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index 999c1484490..e500ac8684d 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -126,7 +126,8 @@ create_color_map_texture(GLcontext *ctx)
/* create texture for color map/table */
pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0,
- texSize, texSize, 1, 0);
+ texSize, texSize, 1, 0,
+ PIPE_TEXTURE_USAGE_SAMPLER);
return pt;
}
@@ -148,8 +149,10 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt)
uint *dest;
uint i, j;
- surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
- dest = (uint *) pipe_surface_map(surface);
+ surface = screen->get_tex_surface(screen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ dest = (uint *) screen->surface_map(screen, surface,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* Pack four 1D maps into a 2D texture:
* R map is placed horizontally, indexed by S, in channel 0
@@ -168,9 +171,8 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt)
}
}
- pipe_surface_unmap(surface);
+ screen->surface_unmap(screen, surface);
pipe_surface_reference(&surface, NULL);
- pipe->texture_update(pipe, pt, 0, 0x1);
}
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 7745591afba..a62ea8161c5 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -44,6 +44,8 @@
#include "pipe/p_context.h"
#include "pipe/p_shader_tokens.h"
+#include "util/u_simple_shaders.h"
+
#include "cso_cache/cso_context.h"
#include "st_context.h"
@@ -252,6 +254,22 @@ st_free_translated_vertex_programs(struct st_context *st,
}
+static void *
+get_passthrough_fs(struct st_context *st)
+{
+ struct pipe_shader_state shader;
+
+ if (!st->passthrough_fs) {
+ st->passthrough_fs =
+ util_make_fragment_passthrough_shader(st->pipe, &shader);
+#if 0 /* We actually need to keep the tokens around at this time */
+ free((void *) shader.tokens);
+#endif
+ }
+
+ return st->passthrough_fs;
+}
+
static void
update_linkage( struct st_context *st )
@@ -277,7 +295,15 @@ update_linkage( struct st_context *st )
st_reference_fragprog(st, &st->fp, stfp);
cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader);
- cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
+
+ if (st->missing_textures) {
+ /* use a pass-through frag shader that uses no textures */
+ void *fs = get_passthrough_fs(st);
+ cso_set_fragment_shader_handle(st->cso_context, fs);
+ }
+ else {
+ cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
+ }
st->vertex_result_to_slot = xvp->output_to_slot;
}
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
index 767654f3d0f..1ec671ed48f 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -39,34 +39,13 @@
#include "pipe/p_context.h"
#include "pipe/p_inlines.h"
#include "cso_cache/cso_context.h"
-#include "util/u_simple_shaders.h"
-static void *
-get_passthrough_fs(struct st_context *st)
-{
- struct pipe_shader_state shader;
-
- if (!st->passthrough_fs) {
- st->passthrough_fs =
- util_make_fragment_passthrough_shader(st->pipe, &shader);
- free((void *) shader.tokens);
- }
-
- return st->passthrough_fs;
-}
-
-
-/**
- * XXX This needs some work yet....
- * Need to "upload" texture images at appropriate times.
- */
static void
update_textures(struct st_context *st)
{
struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
GLuint su;
- GLboolean missing_textures = GL_FALSE;
st->state.num_textures = 0;
@@ -85,13 +64,11 @@ update_textures(struct st_context *st)
retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
if (!retval) {
/* out of mem */
- missing_textures = GL_TRUE;
+ /* missing texture */
continue;
}
st->state.num_textures = su + 1;
-
- stObj->teximage_realloc = TRUE;
}
pt = st_get_stobj_texture(stObj);
@@ -103,12 +80,6 @@ update_textures(struct st_context *st)
cso_set_sampler_textures(st->cso_context,
st->state.num_textures,
st->state.sampler_texture);
-
- if (missing_textures) {
- /* use a pass-through frag shader that uses no textures */
- void *fs = get_passthrough_fs(st);
- cso_set_fragment_shader_handle(st->cso_context, fs);
- }
}
@@ -120,3 +91,52 @@ const struct st_tracked_state st_update_texture = {
},
update_textures /* update */
};
+
+
+
+
+static void
+finalize_textures(struct st_context *st)
+{
+ struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
+ const GLboolean prev_missing_textures = st->missing_textures;
+ GLuint su;
+
+ st->missing_textures = GL_FALSE;
+
+ for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) {
+ if (fprog->Base.SamplersUsed & (1 << su)) {
+ const GLuint texUnit = fprog->Base.SamplerUnits[su];
+ struct gl_texture_object *texObj
+ = st->ctx->Texture.Unit[texUnit]._Current;
+ struct st_texture_object *stObj = st_texture_object(texObj);
+
+ if (texObj) {
+ GLboolean flush, retval;
+
+ retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
+ if (!retval) {
+ /* out of mem */
+ st->missing_textures = GL_TRUE;
+ continue;
+ }
+
+ stObj->teximage_realloc = TRUE;
+ }
+ }
+ }
+
+ if (prev_missing_textures != st->missing_textures)
+ st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+}
+
+
+
+const struct st_tracked_state st_finalize_textures = {
+ "st_finalize_textures", /* name */
+ { /* dirty */
+ _NEW_TEXTURE, /* mesa */
+ 0, /* st */
+ },
+ finalize_textures /* update */
+};
diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index 1636bed91a5..8098d75e18f 100644
--- a/src/mesa/state_tracker/st_cb_accum.c
+++ b/src/mesa/state_tracker/st_cb_accum.c
@@ -105,14 +105,18 @@ void
st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
{
struct st_renderbuffer *acc_strb = st_renderbuffer(rb);
- struct pipe_surface *acc_ps = acc_strb->surface;
+ struct pipe_surface *acc_ps;
+ struct pipe_screen *screen = ctx->st->pipe->screen;
const GLint xpos = ctx->DrawBuffer->_Xmin;
const GLint ypos = ctx->DrawBuffer->_Ymin;
const GLint width = ctx->DrawBuffer->_Xmax - xpos;
const GLint height = ctx->DrawBuffer->_Ymax - ypos;
GLvoid *map;
- map = pipe_surface_map(acc_ps);
+ acc_ps = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ map = screen->surface_map(screen, acc_ps,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* note acc_strb->format might not equal acc_ps->format */
switch (acc_strb->format) {
@@ -140,7 +144,8 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
_mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()");
}
- pipe_surface_unmap(acc_ps);
+ screen->surface_unmap(screen, acc_ps);
+ pipe_surface_reference(&acc_ps, NULL);
}
@@ -150,10 +155,12 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
GLint xpos, GLint ypos, GLint width, GLint height,
struct st_renderbuffer *acc_strb)
{
+ struct pipe_screen *screen = ctx->st->pipe->screen;
struct pipe_surface *acc_ps = acc_strb->surface;
GLvoid *map;
- map = pipe_surface_map(acc_ps);
+ map = screen->surface_map(screen, acc_ps,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* note acc_strb->format might not equal acc_ps->format */
switch (acc_strb->format) {
@@ -174,77 +181,107 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
_mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
}
- pipe_surface_unmap(acc_ps);
+ screen->surface_unmap(screen, acc_ps);
}
static void
accum_accum(struct pipe_context *pipe, GLfloat value,
GLint xpos, GLint ypos, GLint width, GLint height,
- struct pipe_surface *acc_ps,
- struct pipe_surface *color_ps)
+ struct st_renderbuffer *acc_strb,
+ struct st_renderbuffer *color_strb)
{
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_surface *acc_surf, *color_surf;
GLfloat *colorBuf, *accBuf;
GLint i;
+ acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+ (PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_CPU_READ));
+
+ color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
colorBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
- pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, colorBuf);
- acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
+ pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, colorBuf);
+ acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf);
for (i = 0; i < 4 * width * height; i++) {
accBuf[i] = accBuf[i] + colorBuf[i] * value;
}
- acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
+ acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf);
free(colorBuf);
free(accBuf);
+ pipe_surface_reference(&acc_surf, NULL);
+ pipe_surface_reference(&color_surf, NULL);
}
static void
accum_load(struct pipe_context *pipe, GLfloat value,
GLint xpos, GLint ypos, GLint width, GLint height,
- struct pipe_surface *acc_ps,
- struct pipe_surface *color_ps)
+ struct st_renderbuffer *acc_strb,
+ struct st_renderbuffer *color_strb)
{
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_surface *acc_surf, *color_surf;
GLfloat *buf;
GLint i;
+ acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
- pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, buf);
+ pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, buf);
for (i = 0; i < 4 * width * height; i++) {
buf[i] = buf[i] * value;
}
- acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, buf);
+ acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, buf);
free(buf);
+ pipe_surface_reference(&acc_surf, NULL);
+ pipe_surface_reference(&color_surf, NULL);
}
static void
accum_return(GLcontext *ctx, GLfloat value,
GLint xpos, GLint ypos, GLint width, GLint height,
- struct pipe_surface *acc_ps,
- struct pipe_surface *color_ps)
+ struct st_renderbuffer *acc_strb,
+ struct st_renderbuffer *color_strb)
{
struct pipe_context *pipe = ctx->st->pipe;
+ struct pipe_screen *screen = pipe->screen;
const GLubyte *colormask = ctx->Color.ColorMask;
+ struct pipe_surface *acc_surf, *color_surf;
GLfloat *abuf, *cbuf = NULL;
GLint i, ch;
abuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
- acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, abuf);
+ acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
+ color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
+ (PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE));
+
+ acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, abuf);
if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) {
cbuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
- pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, cbuf);
+ pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, cbuf);
}
for (i = 0; i < width * height; i++) {
@@ -259,11 +296,13 @@ accum_return(GLcontext *ctx, GLfloat value,
}
}
- pipe_put_tile_rgba(pipe, color_ps, xpos, ypos, width, height, abuf);
+ pipe_put_tile_rgba(pipe, color_surf, xpos, ypos, width, height, abuf);
free(abuf);
if (cbuf)
free(cbuf);
+ pipe_surface_reference(&acc_surf, NULL);
+ pipe_surface_reference(&color_surf, NULL);
}
@@ -276,8 +315,6 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
= st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
struct st_renderbuffer *color_strb
= st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
- struct pipe_surface *acc_ps = acc_strb->surface;
- struct pipe_surface *color_ps = color_strb->surface;
const GLint xpos = ctx->DrawBuffer->_Xmin;
const GLint ypos = ctx->DrawBuffer->_Ymin;
@@ -300,14 +337,14 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
break;
case GL_ACCUM:
if (value != 0.0F) {
- accum_accum(pipe, value, xpos, ypos, width, height, acc_ps, color_ps);
+ accum_accum(pipe, value, xpos, ypos, width, height, acc_strb, color_strb);
}
break;
case GL_LOAD:
- accum_load(pipe, value, xpos, ypos, width, height, acc_ps, color_ps);
+ accum_load(pipe, value, xpos, ypos, width, height, acc_strb, color_strb);
break;
case GL_RETURN:
- accum_return(ctx, value, xpos, ypos, width, height, acc_ps, color_ps);
+ accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb);
break;
default:
assert(0);
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index e95ff5e2e0d..3a102df67f1 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -325,16 +325,18 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
* Create texture to hold bitmap pattern.
*/
pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, ctx->st->bitmap.tex_format,
- 0, width, height, 1, 0);
+ 0, width, height, 1, 0,
+ PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt) {
_mesa_unmap_bitmap_pbo(ctx, unpack);
return NULL;
}
- surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
+ surface = screen->get_tex_surface(screen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* map texture surface */
- dest = pipe_surface_map(surface);
+ dest = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE);
/* Put image into texture surface */
memset(dest, 0xff, height * surface->pitch);
@@ -344,9 +346,8 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
_mesa_unmap_bitmap_pbo(ctx, unpack);
/* Release surface */
- pipe_surface_unmap(surface);
+ screen->surface_unmap(screen, surface);
pipe_surface_reference(&surface, NULL);
- pipe->texture_update(pipe, pt, 0, 0x1);
return pt;
}
@@ -543,13 +544,16 @@ reset_cache(struct st_context *st)
cache->texture = st_texture_create(st, PIPE_TEXTURE_2D,
st->bitmap.tex_format, 0,
BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
- 1, 0);
+ 1, 0,
+ PIPE_TEXTURE_USAGE_SAMPLER);
/* Map the texture surface.
* Subsequent glBitmap calls will write into the texture image.
*/
- cache->surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0);
- cache->buffer = pipe_surface_map(cache->surf);
+ cache->surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ cache->buffer = screen->surface_map(screen, cache->surf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* init image to all 0xff */
memset(cache->buffer, 0xff, BITMAP_CACHE_WIDTH * BITMAP_CACHE_HEIGHT);
@@ -566,6 +570,7 @@ st_flush_bitmap_cache(struct st_context *st)
if (st->ctx->DrawBuffer) {
struct bitmap_cache *cache = st->bitmap.cache;
struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
assert(cache->xmin <= cache->xmax);
/*
@@ -578,11 +583,8 @@ st_flush_bitmap_cache(struct st_context *st)
/* The texture surface has been mapped until now.
* So unmap and release the texture surface before drawing.
*/
- pipe_surface_unmap(cache->surf);
- pipe_surface_reference(&cache->surf, NULL);
-
- /* XXX is this needed? */
- pipe->texture_update(pipe, cache->texture, 0, 0x1);
+ screen->surface_unmap(screen, cache->surf);
+ screen->tex_surface_release(screen, &cache->surf);
draw_bitmap_quad(st->ctx,
cache->xpos,
@@ -666,6 +668,9 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
struct st_context *st = ctx->st;
struct pipe_texture *pt;
+ if (width == 0 || height == 0)
+ return;
+
st_validate_state(st);
if (!st->bitmap.vs) {
@@ -746,6 +751,11 @@ void
st_destroy_bitmap(struct st_context *st)
{
struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ struct bitmap_cache *cache = st->bitmap.cache;
+
+ screen->surface_unmap(screen, cache->surf);
+ screen->tex_surface_release(screen, &cache->surf);
if (st->bitmap.vs) {
cso_delete_vertex_shader(st->cso_context, st->bitmap.vs);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index fbbe8d2d64e..a486581989c 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -349,7 +349,8 @@ make_texture(struct st_context *st,
return NULL;
pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height,
- 1, 0);
+ 1, 0,
+ PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt) {
_mesa_unmap_drawpix_pbo(ctx, unpack);
return NULL;
@@ -365,10 +366,12 @@ make_texture(struct st_context *st,
/* we'll do pixel transfer in a fragment shader */
ctx->_ImageTransferState = 0x0;
- surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
+ surface = screen->get_tex_surface(screen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* map texture surface */
- dest = pipe_surface_map(surface);
+ dest = screen->surface_map(screen, surface,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* Put image into texture surface.
* Note that the image is actually going to be upside down in
@@ -387,9 +390,8 @@ make_texture(struct st_context *st,
unpack);
/* unmap */
- pipe_surface_unmap(surface);
+ screen->surface_unmap(screen, surface);
pipe_surface_reference(&surface, NULL);
- pipe->texture_update(pipe, pt, 0, 0x1);
assert(success);
@@ -485,7 +487,7 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
ubyte *map;
/* allocate/load buffer object with vertex data */
- buf = pipe_buffer_create(pipe,32, PIPE_BUFFER_USAGE_VERTEX,
+ buf = pipe_buffer_create(pipe, 32, PIPE_BUFFER_USAGE_VERTEX,
sizeof(verts));
map = pipe_buffer_map(pipe, buf, PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(map, verts, sizeof(verts));
@@ -495,8 +497,7 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
PIPE_PRIM_QUADS,
4, /* verts */
3); /* attribs/vert */
-
- pipe_buffer_destroy(pipe, buf);
+ pipe_buffer_reference(pipe->winsys, &buf, NULL);
}
}
@@ -603,8 +604,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
x1 = x + width * ctx->Pixel.ZoomX;
y0 = y;
y1 = y + height * ctx->Pixel.ZoomY;
+ //if(!color)
draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex);
-
+ //else
+ //printf("skip draw quad\n");
/* restore state */
cso_restore_rasterizer(cso);
cso_restore_viewport(cso);
@@ -734,15 +737,23 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
{
struct st_context *st = ctx->st;
struct pipe_context *pipe = st->pipe;
- struct pipe_surface *ps = st->state.framebuffer.zsbuf;
+ struct pipe_screen *screen = pipe->screen;
+ struct st_renderbuffer *strb;
+ struct pipe_surface *ps;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
GLint skipPixels;
ubyte *stmap;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+ strb = st_renderbuffer(ctx->DrawBuffer->
+ Attachment[BUFFER_STENCIL].Renderbuffer);
+ ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
/* map the stencil buffer */
- stmap = pipe_surface_map(ps);
+ stmap = screen->surface_map(screen, ps,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* if width > MAX_WIDTH, have to process image in chunks */
skipPixels = 0;
@@ -799,7 +810,8 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
}
/* unmap the stencil buffer */
- pipe_surface_unmap(ps);
+ screen->surface_unmap(screen, ps);
+ pipe_surface_reference(&ps, NULL);
}
@@ -872,7 +884,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint dstx, GLint dsty)
{
struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
- struct pipe_surface *psDraw = rbDraw->surface;
+ struct pipe_screen *screen = ctx->st->pipe->screen;
+ struct pipe_surface *psDraw;
ubyte *drawMap;
ubyte *buffer;
int i;
@@ -887,8 +900,11 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE,
&ctx->DefaultPacking, buffer);
+ psDraw = screen->get_tex_surface(screen, rbDraw->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
/* map the stencil buffer */
- drawMap = pipe_surface_map(psDraw);
+ drawMap = screen->surface_map(screen, psDraw, PIPE_BUFFER_USAGE_CPU_WRITE);
/* draw */
/* XXX PixelZoom not handled yet */
@@ -928,7 +944,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
free(buffer);
/* unmap the stencil buffer */
- pipe_surface_unmap(psDraw);
+ screen->surface_unmap(screen, psDraw);
+ pipe_surface_reference(&psDraw, NULL);
}
@@ -943,7 +960,6 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
struct st_renderbuffer *rbRead;
struct st_vertex_program *stvp;
struct st_fragment_program *stfp;
- struct pipe_surface *psRead;
struct pipe_surface *psTex;
struct pipe_texture *pt;
GLfloat *color;
@@ -974,8 +990,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
}
- psRead = rbRead->surface;
- srcFormat = psRead->format;
+ srcFormat = rbRead->texture->format;
if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE)) {
texFormat = srcFormat;
@@ -987,54 +1002,72 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
assert(texFormat != PIPE_FORMAT_NONE); /* XXX no depth texture formats??? */
}
else {
- /* todo */
- assert(0);
+ /* default color format */
+ texFormat = st_choose_format(pipe, GL_RGBA, PIPE_TEXTURE);
+ assert(texFormat != PIPE_FORMAT_NONE);
}
}
pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0,
- width, height, 1, 0);
+ width, height, 1, 0,
+ PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt)
return;
- psTex = screen->get_tex_surface(screen, pt, 0, 0, 0);
-
if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
srcy = ctx->DrawBuffer->Height - srcy - height;
}
if (srcFormat == texFormat) {
/* copy source framebuffer surface into mipmap/texture */
+ struct pipe_surface *psRead = screen->get_tex_surface(screen,
+ rbRead->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ);
+ psTex = screen->get_tex_surface(screen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE );
pipe->surface_copy(pipe,
FALSE,
psTex, /* dest */
0, 0, /* destx/y */
psRead,
srcx, srcy, width, height);
+ pipe_surface_reference(&psRead, NULL);
}
- else if (type == GL_COLOR) {
- /* alternate path using get/put_tile() */
- GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+ else {
+ /* CPU-based fallback/conversion */
+ struct pipe_surface *psRead = screen->get_tex_surface(screen,
+ rbRead->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
- pipe_get_tile_rgba(pipe, psRead, srcx, srcy, width, height, buf);
- pipe_put_tile_rgba(pipe, psTex, 0, 0, width, height, buf);
+ psTex = screen->get_tex_surface(screen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE );
- free(buf);
- }
- else {
- /* GL_DEPTH */
- GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
- pipe_get_tile_z(pipe, psRead, srcx, srcy, width, height, buf);
- pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf);
- free(buf);
+ if (type == GL_COLOR) {
+ /* alternate path using get/put_tile() */
+ GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+
+ pipe_get_tile_rgba(pipe, psRead, srcx, srcy, width, height, buf);
+ pipe_put_tile_rgba(pipe, psTex, 0, 0, width, height, buf);
+
+ free(buf);
+ }
+ else {
+ /* GL_DEPTH */
+ GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
+ pipe_get_tile_z(pipe, psRead, srcx, srcy, width, height, buf);
+ pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf);
+ free(buf);
+ }
+ pipe_surface_reference(&psRead, NULL);
}
+ pipe_surface_reference(&psTex, NULL);
+
/* draw textured quad */
draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
pt, stvp, stfp, color, GL_TRUE);
- pipe_surface_reference(&psTex, NULL);
pipe_texture_reference(&pt, NULL);
}
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index fc8a5ea7f62..3560a040c85 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -77,7 +77,6 @@ init_renderbuffer_bits(struct st_renderbuffer *strb,
return info.size;
}
-
/**
* gl_renderbuffer::AllocStorage()
* This is called to allocate the original drawing surface, and
@@ -90,80 +89,94 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
{
struct pipe_context *pipe = ctx->st->pipe;
struct st_renderbuffer *strb = st_renderbuffer(rb);
- enum pipe_format pipeFormat;
- GLbitfield flags = 0x0; /* XXX needed? */
- int ret;
-
- if (!strb->surface) {
- /* first time surface creation */
- strb->surface = pipe->winsys->surface_alloc(pipe->winsys);
- assert(strb->surface);
- assert(strb->surface->refcount);
- assert(strb->surface->winsys);
- if (!strb->surface)
- return GL_FALSE;
+ struct pipe_texture template;
+ unsigned surface_usage;
+
+ /* Free the old surface (and texture if we hold the last
+ * reference):
+ */
+ pipe_surface_reference( &strb->surface, NULL );
+
+ memset(&template, 0, sizeof(template));
+
+ if (strb->format != PIPE_FORMAT_NONE) {
+ template.format = strb->format;
}
- else if (strb->surface->buffer) {
- /* release/discard the old surface buffer */
- pipe_reference_buffer(pipe, &strb->surface->buffer, NULL);
+ else {
+ template.format = st_choose_renderbuffer_format(pipe, internalFormat);
}
- /* Determine surface format here */
- if (strb->format != PIPE_FORMAT_NONE) {
- assert(strb->format != 0);
- /* we'll hit this for front/back color bufs */
- pipeFormat = strb->format;
+ strb->Base.Width = width;
+ strb->Base.Height = height;
+ init_renderbuffer_bits(strb, template.format);
+
+ template.target = PIPE_TEXTURE_2D;
+ template.compressed = 0;
+ template.cpp = pf_get_size(template.format);
+ template.width[0] = width;
+ template.height[0] = height;
+ template.depth[0] = 1;
+ template.last_level = 0;
+
+ if (pf_is_depth_stencil(template.format)) {
+ template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
}
else {
- pipeFormat = st_choose_renderbuffer_format(pipe, internalFormat);
+ template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET);
}
- init_renderbuffer_bits(strb, pipeFormat);
-
- ret = pipe->winsys->surface_alloc_storage(pipe->winsys,
- strb->surface,
- width,
- height,
- pipeFormat,
- flags);
- if (ret || !strb->surface->buffer) {
- if (pipeFormat == DEFAULT_ACCUM_PIPE_FORMAT) {
- /* Accum buffer. Try a different surface format. Since accum
- * buffers are s/w only for now, the surface pixel format doesn't
- * really matter, only that the buffer is large enough.
- */
- int sz, mult;
- enum pipe_format accum_format;
-
- /* allocate a buffer of (typically) double height to get 64bpp */
- accum_format = st_choose_renderbuffer_format(pipe, GL_RGBA);
- sz = pf_get_size(accum_format);
- mult = pf_get_size(DEFAULT_ACCUM_PIPE_FORMAT) / sz;
-
- ret = pipe->winsys->surface_alloc_storage(pipe->winsys,
- strb->surface,
- width, height * mult,
- accum_format, flags);
- if (ret)
- return GL_FALSE; /* we've _really_ failed */
-
- }
- else {
- return GL_FALSE; /* out of memory, try s/w buffer? */
- }
+
+ /* Probably need dedicated flags for surface usage too:
+ */
+ surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+#if 0
+ PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+#endif
+
+ strb->texture = pipe->screen->texture_create( pipe->screen,
+ &template );
+
+ /* Special path for accum buffers.
+ *
+ * Try a different surface format. Since accum buffers are s/w
+ * only for now, the surface pixel format doesn't really matter,
+ * only that the buffer is large enough.
+ */
+ if (!strb->texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT)
+ {
+ /* Actually, just setting this usage value should be sufficient
+ * to tell the driver to go ahead and allocate the buffer, even
+ * if HW doesn't support the format.
+ */
+ template.tex_usage = 0;
+ surface_usage = (PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ strb->texture = pipe->screen->texture_create( pipe->screen,
+ &template );
+
}
- ASSERT(strb->surface->buffer);
- ASSERT(strb->surface->format);
- ASSERT(strb->surface->cpp);
- ASSERT(strb->surface->width == width);
- /*ASSERT(strb->surface->height == height);*/
- ASSERT(strb->surface->pitch);
+ if (!strb->texture)
+ return FALSE;
- strb->Base.Width = width;
- strb->Base.Height = height;
+ strb->surface = pipe->screen->get_tex_surface( pipe->screen,
+ strb->texture,
+ 0, 0, 0,
+ surface_usage );
+
+ assert(strb->surface->buffer);
+ assert(strb->surface->format);
+ assert(strb->surface->cpp);
+ assert(strb->surface->width == width);
+ assert(strb->surface->height == height);
+ assert(strb->surface->pitch);
- return GL_TRUE;
+
+ return strb->surface != NULL;
}
@@ -175,10 +188,8 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb)
{
struct st_renderbuffer *strb = st_renderbuffer(rb);
ASSERT(strb);
- if (strb->surface) {
- struct pipe_winsys *ws = strb->surface->winsys;
- ws->surface_release(ws, &strb->surface);
- }
+ pipe_surface_reference(&strb->surface, NULL);
+ pipe_texture_reference(&strb->texture, NULL);
free(strb);
}
@@ -341,6 +352,10 @@ st_render_texture(GLcontext *ctx,
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_texture *pt;
+ struct st_texture_object *stObj;
+ const struct gl_texture_image *texImage =
+ att->Texture->Image[att->CubeMapFace][att->TextureLevel];
+
assert(!att->Renderbuffer);
@@ -357,21 +372,27 @@ st_render_texture(GLcontext *ctx,
strb = st_renderbuffer(rb);
/* get the texture for the texture object */
+ stObj = st_texture_object(att->Texture);
+
+ /* point renderbuffer at texobject */
+ strb->rtt = stObj;
+ strb->rtt_level = att->TextureLevel;
+ strb->rtt_face = att->CubeMapFace;
+ strb->rtt_slice = att->Zoffset;
+
+ rb->Width = texImage->Width2;
+ rb->Height = texImage->Height2;
+ /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/
+
pt = st_get_texobj_texture(att->Texture);
assert(pt);
- assert(pt->width[att->TextureLevel]);
+ /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/
+
+ pipe_texture_reference( &strb->texture, pt );
- rb->Width = pt->width[att->TextureLevel];
- rb->Height = pt->height[att->TextureLevel];
+ pipe_surface_reference(&strb->surface, NULL);
- /* the renderbuffer's surface is inside the texture */
- strb->surface = screen->get_tex_surface(screen, pt,
- att->CubeMapFace,
- att->TextureLevel,
- att->Zoffset);
- assert(strb->surface);
- assert(screen->is_format_supported(screen, strb->surface->format, PIPE_TEXTURE));
- assert(screen->is_format_supported(screen, strb->surface->format, PIPE_SURFACE));
+ /* the new surface will be created during framebuffer validation */
init_renderbuffer_bits(strb, pt->format);
@@ -396,22 +417,22 @@ static void
st_finish_render_texture(GLcontext *ctx,
struct gl_renderbuffer_attachment *att)
{
+ struct pipe_screen *screen = ctx->st->pipe->screen;
struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer);
assert(strb);
ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
- ctx->st->pipe->texture_update(ctx->st->pipe,
- st_get_texobj_texture(att->Texture),
- att->CubeMapFace, 1 << att->TextureLevel);
+ if (strb->surface)
+ screen->tex_surface_release( screen, &strb->surface );
+
+ strb->rtt = NULL;
/*
printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface);
*/
- pipe_surface_reference(&strb->surface, NULL);
-
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
/* restore previous framebuffer state */
diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h
index c1aa14f9b22..87b0734a0c8 100644
--- a/src/mesa/state_tracker/st_cb_fbo.h
+++ b/src/mesa/state_tracker/st_cb_fbo.h
@@ -41,8 +41,12 @@
struct st_renderbuffer
{
struct gl_renderbuffer Base;
- struct pipe_surface *surface;
+ struct pipe_texture *texture;
+ struct pipe_surface *surface; /* temporary view into texture */
enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */
+
+ struct st_texture_object *rtt; /**< GL render to texture's texture */
+ int rtt_level, rtt_face, rtt_slice;
};
diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c
index 1b50792bd1c..19021411cfc 100644
--- a/src/mesa/state_tracker/st_cb_feedback.c
+++ b/src/mesa/state_tracker/st_cb_feedback.c
@@ -173,6 +173,12 @@ feedback_reset_stipple_counter( struct draw_stage *stage )
}
+static void
+feedback_destroy( struct draw_stage *stage )
+{
+ /* no-op */
+}
+
/**
* Create GL feedback drawing stage.
*/
@@ -188,6 +194,7 @@ draw_glfeedback_stage(GLcontext *ctx, struct draw_context *draw)
fs->stage.tri = feedback_tri;
fs->stage.flush = feedback_flush;
fs->stage.reset_stipple_counter = feedback_reset_stipple_counter;
+ fs->stage.destroy = feedback_destroy;
fs->ctx = ctx;
return &fs->stage;
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 5f753afdd36..11ba5d56f30 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -182,6 +182,7 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
assert(0); /* problem */
}
+ /* delete base class */
_mesa_delete_program( ctx, prog );
}
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 745755566e7..08934af3195 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -61,13 +61,18 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
GLvoid *pixels)
{
struct gl_framebuffer *fb = ctx->ReadBuffer;
+ struct pipe_screen *screen = ctx->st->pipe->screen;
struct st_renderbuffer *strb = st_renderbuffer(fb->_StencilBuffer);
- struct pipe_surface *ps = strb->surface;
+ struct pipe_surface *ps;
ubyte *stmap;
GLint j;
+ /* Create a CPU-READ surface/view into the renderbuffer's texture */
+ ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
/* map the stencil buffer */
- stmap = pipe_surface_map(ps);
+ stmap = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
/* width should never be > MAX_WIDTH since we did clipping earlier */
ASSERT(width <= MAX_WIDTH);
@@ -124,7 +129,8 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
/* unmap the stencil buffer */
- pipe_surface_unmap(ps);
+ screen->surface_unmap(screen, ps);
+ pipe_surface_reference(&ps, NULL);
}
@@ -168,12 +174,16 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
GLvoid *dest)
{
struct pipe_context *pipe = ctx->st->pipe;
+ struct pipe_screen *screen = pipe->screen;
GLfloat temp[MAX_WIDTH][4];
const GLbitfield transferOps = ctx->_ImageTransferState;
GLint i, yStep, dfStride;
GLfloat *df;
struct st_renderbuffer *strb;
struct gl_pixelstore_attrib clippedPacking = *pack;
+ struct pipe_surface *surf;
+
+ assert(ctx->ReadBuffer->Width > 0);
/* XXX convolution not done yet */
assert((transferOps & IMAGE_CONVOLUTION_BIT) == 0);
@@ -229,6 +239,10 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
yStep = 1;
}
+ /* Create a CPU-READ surface/view into the renderbuffer's texture */
+ surf = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
/*
* Copy pixels from pipe_surface to user memory
*/
@@ -240,15 +254,14 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width,
format, type);
- if (strb->surface->format == PIPE_FORMAT_S8Z24_UNORM ||
- strb->surface->format == PIPE_FORMAT_X8Z24_UNORM) {
+ if (surf->format == PIPE_FORMAT_S8Z24_UNORM ||
+ surf->format == PIPE_FORMAT_X8Z24_UNORM) {
if (format == GL_DEPTH_COMPONENT) {
for (i = 0; i < height; i++) {
GLuint ztemp[MAX_WIDTH], j;
GLfloat zfloat[MAX_WIDTH];
const double scale = 1.0 / ((1 << 24) - 1);
- pipe_get_tile_raw(pipe, strb->surface, x, y,
- width, 1, ztemp, 0);
+ pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0);
y += yStep;
for (j = 0; j < width; j++) {
zfloat[j] = (float) (scale * (ztemp[j] & 0xffffff));
@@ -262,18 +275,18 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
/* untested, but simple: */
assert(format == GL_DEPTH_STENCIL_EXT);
for (i = 0; i < height; i++) {
- pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, dst, 0);
+ pipe_get_tile_raw(pipe, surf, x, y, width, 1, dst, 0);
y += yStep;
dst += dstStride;
}
}
}
- else if (strb->surface->format == PIPE_FORMAT_Z16_UNORM) {
+ else if (surf->format == PIPE_FORMAT_Z16_UNORM) {
for (i = 0; i < height; i++) {
GLushort ztemp[MAX_WIDTH], j;
GLfloat zfloat[MAX_WIDTH];
const double scale = 1.0 / 0xffff;
- pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, ztemp, 0);
+ pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0);
y += yStep;
for (j = 0; j < width; j++) {
zfloat[j] = (float) (scale * ztemp[j]);
@@ -283,12 +296,12 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
dst += dstStride;
}
}
- else if (strb->surface->format == PIPE_FORMAT_Z32_UNORM) {
+ else if (surf->format == PIPE_FORMAT_Z32_UNORM) {
for (i = 0; i < height; i++) {
GLuint ztemp[MAX_WIDTH], j;
GLfloat zfloat[MAX_WIDTH];
const double scale = 1.0 / 0xffffffff;
- pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, ztemp, 0);
+ pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0);
y += yStep;
for (j = 0; j < width; j++) {
zfloat[j] = (float) (scale * ztemp[j]);
@@ -302,7 +315,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
/* RGBA format */
/* Do a row at a time to flip image data vertically */
for (i = 0; i < height; i++) {
- pipe_get_tile_rgba(pipe, strb->surface, x, y, width, 1, df);
+ pipe_get_tile_rgba(pipe, surf, x, y, width, 1, df);
y += yStep;
df += dfStride;
if (!dfStride) {
@@ -314,6 +327,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
}
}
+ pipe_surface_reference(&surf, NULL);
+
_mesa_unmap_readpix_pbo(ctx, &clippedPacking);
}
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index cc17bebc6b6..e15ccec89b4 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -272,6 +272,7 @@ guess_and_alloc_texture(struct st_context *st,
GLuint height = stImage->base.Height2;
GLuint depth = stImage->base.Depth2;
GLuint i, comp_byte = 0;
+ enum pipe_format fmt;
DBG("%s\n", __FUNCTION__);
@@ -306,6 +307,11 @@ guess_and_alloc_texture(struct st_context *st,
depth <<= 1;
}
+ if (width == 0 || height == 0 || depth == 0) {
+ /* no texture needed */
+ return;
+ }
+
/* Guess a reasonable value for lastLevel. This is probably going
* to be wrong fairly often and might mean that we have to look at
* resizable buffers, or require that buffers implement lazy
@@ -326,14 +332,19 @@ guess_and_alloc_texture(struct st_context *st,
if (stImage->base.IsCompressed)
comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat);
+ fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat);
stObj->pt = st_texture_create(st,
gl_target_to_pipe(stObj->base.Target),
- st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat),
+ fmt,
lastLevel,
width,
height,
depth,
- comp_byte);
+ comp_byte,
+ ( (pf_is_depth_stencil(fmt) ?
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
+ PIPE_TEXTURE_USAGE_RENDER_TARGET) |
+ PIPE_TEXTURE_USAGE_SAMPLER ));
DBG("%s - success\n", __FUNCTION__);
}
@@ -478,7 +489,6 @@ st_TexImage(GLcontext * ctx,
struct gl_texture_image *texImage,
GLsizei imageSize, int compressed)
{
- struct pipe_context *pipe = ctx->st->pipe;
struct st_texture_object *stObj = st_texture_object(texObj);
struct st_texture_image *stImage = st_texture_image(texImage);
GLint postConvWidth, postConvHeight;
@@ -637,8 +647,10 @@ st_TexImage(GLcontext * ctx,
return;
if (stImage->pt) {
- texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
- dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
+ texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ if (stImage->surface)
+ dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
}
else {
/* Allocate regular memory and store the image there temporarily. */
@@ -656,6 +668,11 @@ st_TexImage(GLcontext * ctx,
texImage->Data = malloc(sizeInBytes);
}
+ if (!texImage->Data) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ return;
+ }
+
DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
width, height, depth, width * texelBytes, dstRowStride);
@@ -686,8 +703,9 @@ st_TexImage(GLcontext * ctx,
}
if (stImage->pt && i < depth) {
- st_texture_image_unmap(stImage);
- texImage->Data = st_texture_image_map(ctx->st, stImage, i);
+ st_texture_image_unmap(ctx->st, stImage);
+ texImage->Data = st_texture_image_map(ctx->st, stImage, i,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
src += srcImageStride;
}
}
@@ -696,13 +714,10 @@ st_TexImage(GLcontext * ctx,
_mesa_unmap_teximage_pbo(ctx, unpack);
if (stImage->pt) {
- st_texture_image_unmap(stImage);
+ st_texture_image_unmap(ctx->st, stImage);
texImage->Data = NULL;
}
- if (stObj->pt)
- pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
-
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
@@ -795,7 +810,8 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
/* Image is stored in hardware format in a buffer managed by the
* kernel. Need to explicitly map and unmap it.
*/
- texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
+ texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
texImage->RowStride = stImage->surface->pitch;
}
else {
@@ -825,8 +841,9 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
}
if (stImage->pt && i < depth) {
- st_texture_image_unmap(stImage);
- texImage->Data = st_texture_image_map(ctx->st, stImage, i);
+ st_texture_image_unmap(ctx->st, stImage);
+ texImage->Data = st_texture_image_map(ctx->st, stImage, i,
+ PIPE_BUFFER_USAGE_CPU_READ);
dest += dstImageStride;
}
}
@@ -835,7 +852,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
/* Unmap */
if (stImage->pt) {
- st_texture_image_unmap(stImage);
+ st_texture_image_unmap(ctx->st, stImage);
texImage->Data = NULL;
}
}
@@ -876,8 +893,6 @@ st_TexSubimage(GLcontext * ctx,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- struct pipe_context *pipe = ctx->st->pipe;
- struct st_texture_object *stObj = st_texture_object(texObj);
struct st_texture_image *stImage = st_texture_image(texImage);
GLuint dstRowStride;
GLuint srcImageStride = _mesa_image_image_stride(packing, width, height,
@@ -899,8 +914,10 @@ st_TexSubimage(GLcontext * ctx,
* from uploading the buffer under us.
*/
if (stImage->pt) {
- texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset);
- dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
+ texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ if (stImage->surface)
+ dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
}
if (!texImage->Data) {
@@ -924,8 +941,9 @@ st_TexSubimage(GLcontext * ctx,
if (stImage->pt && i < depth) {
/* map next slice of 3D texture */
- st_texture_image_unmap(stImage);
- texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i);
+ st_texture_image_unmap(ctx->st, stImage);
+ texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
src += srcImageStride;
}
}
@@ -937,11 +955,9 @@ st_TexSubimage(GLcontext * ctx,
_mesa_unmap_teximage_pbo(ctx, packing);
if (stImage->pt) {
- st_texture_image_unmap(stImage);
+ st_texture_image_unmap(ctx->st, stImage);
texImage->Data = NULL;
}
-
- pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
}
@@ -1059,8 +1075,11 @@ fallback_copy_texsubimage(GLcontext *ctx,
}
src_surf = strb->surface;
+ src_surf = screen->get_tex_surface(screen, strb->texture, face, level, destZ,
+ PIPE_BUFFER_USAGE_CPU_READ);
- dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ);
+ dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
assert(width <= MAX_WIDTH);
@@ -1094,6 +1113,9 @@ fallback_copy_texsubimage(GLcontext *ctx,
pipe_put_tile_rgba(pipe, dest_surf, destX, destY, width, 1, data);
}
}
+
+ screen->tex_surface_release(screen, &dest_surf);
+ screen->tex_surface_release(screen, &src_surf);
}
@@ -1121,13 +1143,11 @@ do_copy_texsubimage(GLcontext *ctx,
struct gl_texture_image *texImage =
_mesa_select_tex_image(ctx, texObj, target, level);
struct st_texture_image *stImage = st_texture_image(texImage);
- struct st_texture_object *stObj = st_texture_object(texObj);
GLenum baseFormat = texImage->InternalFormat;
struct gl_framebuffer *fb = ctx->ReadBuffer;
struct st_renderbuffer *strb;
struct pipe_context *pipe = ctx->st->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_surface *dest_surface;
uint dest_format, src_format;
uint do_flip = FALSE;
GLboolean use_fallback = GL_TRUE;
@@ -1158,12 +1178,7 @@ do_copy_texsubimage(GLcontext *ctx,
src_format = strb->surface->format;
dest_format = stImage->pt->format;
- dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face,
- stImage->level, destZ);
-
- if (ctx->_ImageTransferState == 0x0 &&
- strb->surface->buffer &&
- dest_surface->buffer) {
+ if (ctx->_ImageTransferState == 0x0) {
/* do blit-style copy */
/* XXX may need to invert image depending on window
@@ -1186,6 +1201,14 @@ do_copy_texsubimage(GLcontext *ctx,
x, y + height, dstx, dsty, width, height,
GL_COPY); /* ? */
#else
+ struct pipe_surface *dest_surface;
+
+ dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face,
+ stImage->level, destZ,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ assert(strb->surface->buffer);
+ assert(dest_surface->buffer);
if (src_format == dest_format) {
pipe->surface_copy(pipe,
@@ -1213,6 +1236,8 @@ do_copy_texsubimage(GLcontext *ctx,
0.0, PIPE_TEX_MIPFILTER_NEAREST);
use_fallback = GL_FALSE;
}
+
+ pipe_surface_reference(&dest_surface, NULL);
#endif
}
@@ -1223,10 +1248,6 @@ do_copy_texsubimage(GLcontext *ctx,
srcX, srcY, width, height);
}
- pipe_surface_reference(&dest_surface, NULL);
-
- pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
-
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
@@ -1483,20 +1504,28 @@ st_finalize_texture(GLcontext *ctx,
stObj->pt->cpp != cpp ||
stObj->pt->compressed != firstImage->base.IsCompressed) {
pipe_texture_release(&stObj->pt);
+ ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER;
}
}
/* May need to create a new gallium texture:
*/
if (!stObj->pt) {
+ const enum pipe_format fmt =
+ st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
stObj->pt = st_texture_create(ctx->st,
gl_target_to_pipe(stObj->base.Target),
- st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat),
+ fmt,
stObj->lastLevel,
firstImage->base.Width2,
firstImage->base.Height2,
firstImage->base.Depth2,
- comp_byte);
+ comp_byte,
+ ( (pf_is_depth_stencil(fmt) ?
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
+ PIPE_TEXTURE_USAGE_RENDER_TARGET) |
+ PIPE_TEXTURE_USAGE_SAMPLER ));
+
if (!stObj->pt) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
return GL_FALSE;
@@ -1516,7 +1545,6 @@ st_finalize_texture(GLcontext *ctx,
if (stImage && stObj->pt != stImage->pt) {
copy_image_data_to_texture(ctx->st, stObj, level, stImage);
*needFlush = GL_TRUE;
- pipe->texture_update(pipe, stObj->pt, face, (1 << level));
}
}
}
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 46c16e45e66..96333902a91 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -53,6 +53,7 @@ struct bitmap_cache;
#define ST_NEW_MESA 0x1 /* Mesa state has changed */
#define ST_NEW_FRAGMENT_PROGRAM 0x2
#define ST_NEW_VERTEX_PROGRAM 0x4
+#define ST_NEW_FRAMEBUFFER 0x8
struct st_state_flags {
@@ -121,6 +122,8 @@ struct st_context
struct st_state_flags dirty;
+ GLboolean missing_textures;
+
GLfloat polygon_offset_scale; /* ?? */
/** Mapping from VERT_RESULT_x to post-transformed vertex slot */
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 047743689dc..f51eff05dce 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -123,8 +123,10 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
const ubyte *srcData;
ubyte *dstData;
- 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);
srcData = (ubyte *) pipe_buffer_map(pipe, srcSurf->buffer,
PIPE_BUFFER_USAGE_CPU_READ)
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index f68bef1207c..9553b34e317 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -75,7 +75,8 @@ st_texture_create(struct st_context *st,
GLuint width0,
GLuint height0,
GLuint depth0,
- GLuint compress_byte)
+ GLuint compress_byte,
+ GLuint usage )
{
struct pipe_texture pt, *newtex;
struct pipe_screen *screen = st->pipe->screen;
@@ -98,6 +99,7 @@ st_texture_create(struct st_context *st,
pt.depth[0] = depth0;
pt.compressed = compress_byte ? 1 : 0;
pt.cpp = pt.compressed ? compress_byte : st_sizeof_format(format);
+ pt.tex_usage = usage;
newtex = screen->texture_create(screen, &pt);
@@ -184,25 +186,33 @@ st_texture_image_offset(const struct pipe_texture * pt,
*/
GLubyte *
st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
- GLuint zoffset)
+ GLuint zoffset,
+ GLuint flags )
{
struct pipe_screen *screen = st->pipe->screen;
struct pipe_texture *pt = stImage->pt;
DBG("%s \n", __FUNCTION__);
stImage->surface = screen->get_tex_surface(screen, pt, stImage->face,
- stImage->level, zoffset);
+ stImage->level, zoffset,
+ flags);
- return pipe_surface_map(stImage->surface);
+ if (stImage->surface)
+ return screen->surface_map(screen, stImage->surface, flags);
+ else
+ return NULL;
}
void
-st_texture_image_unmap(struct st_texture_image *stImage)
+st_texture_image_unmap(struct st_context *st,
+ struct st_texture_image *stImage)
{
+ struct pipe_screen *screen = st->pipe->screen;
+
DBG("%s\n", __FUNCTION__);
- pipe_surface_unmap(stImage->surface);
+ screen->surface_unmap(screen, stImage->surface);
pipe_surface_reference(&stImage->surface, NULL);
}
@@ -224,12 +234,15 @@ st_surface_data(struct pipe_context *pipe,
const void *src, unsigned src_pitch,
unsigned srcx, unsigned srcy, unsigned width, unsigned height)
{
- pipe_copy_rect(pipe_surface_map(dst),
+ struct pipe_screen *screen = pipe->screen;
+ void *map = screen->surface_map(screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ pipe_copy_rect(map,
dst->cpp,
dst->pitch,
dstx, dsty, width, height, src, src_pitch, srcx, srcy);
- pipe_surface_unmap(dst);
+ screen->surface_unmap(screen, dst);
}
@@ -256,7 +269,8 @@ st_texture_image_data(struct pipe_context *pipe,
if(dst->compressed)
height /= 4;
- dst_surface = screen->get_tex_surface(screen, dst, face, level, i);
+ dst_surface = screen->get_tex_surface(screen, dst, face, level, i,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
st_surface_data(pipe, dst_surface,
0, 0, /* dstx, dsty */
@@ -265,7 +279,7 @@ st_texture_image_data(struct pipe_context *pipe,
0, 0, /* source x, y */
dst->width[level], height); /* width, height */
- pipe_surface_reference(&dst_surface, NULL);
+ screen->tex_surface_release(screen, &dst_surface);
srcUB += src_image_pitch * dst->cpp;
}
@@ -304,8 +318,27 @@ st_texture_image_copy(struct pipe_context *pipe,
assert(src->width[srcLevel] == width);
assert(src->height[srcLevel] == height);
- dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i);
- src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i);
+#if 0
+ {
+ src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ ubyte *map = screen->surface_map(screen, src_surface, PIPE_BUFFER_USAGE_CPU_READ);
+ map += src_surface->width * src_surface->height * 4 / 2;
+ printf("%s center pixel: %d %d %d %d (pt %p[%d] -> %p[%d])\n",
+ __FUNCTION__,
+ map[0], map[1], map[2], map[3],
+ src, srcLevel, dst, dstLevel);
+
+ screen->surface_unmap(screen, src_surface);
+ pipe_surface_reference(&src_surface, NULL);
+ }
+#endif
+
+ dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i,
+ PIPE_BUFFER_USAGE_GPU_READ);
pipe->surface_copy(pipe,
FALSE,
@@ -315,7 +348,7 @@ st_texture_image_copy(struct pipe_context *pipe,
0, 0, /* srcX, Y */
width, copyHeight);
- pipe_surface_reference(&dst_surface, NULL);
- pipe_surface_reference(&src_surface, NULL);
+ screen->tex_surface_release(screen, &src_surface);
+ screen->tex_surface_release(screen, &dst_surface);
}
}
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index b05762113cc..3febe6a7cb0 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -93,6 +93,11 @@ st_get_stobj_texture(struct st_texture_object *stObj)
return stObj ? stObj->pt : NULL;
}
+static INLINE GLboolean pf_is_depth_stencil( enum pipe_format format )
+{
+ return (pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) +
+ pf_get_component_bits( format, PIPE_FORMAT_COMP_S )) != 0;
+}
extern struct pipe_texture *
@@ -103,7 +108,8 @@ st_texture_create(struct st_context *st,
GLuint width0,
GLuint height0,
GLuint depth0,
- GLuint compress_byte);
+ GLuint compress_byte,
+ GLuint tex_usage );
/* Check if an image fits into an existing texture object.
@@ -119,10 +125,12 @@ st_texture_match_image(const struct pipe_texture *pt,
extern GLubyte *
st_texture_image_map(struct st_context *st,
struct st_texture_image *stImage,
- GLuint zoffset);
+ GLuint zoffset,
+ GLuint flags);
extern void
-st_texture_image_unmap(struct st_texture_image *stImage);
+st_texture_image_unmap(struct st_context *st,
+ struct st_texture_image *stImage);
/* Return pointers to each 2d slice within an image. Indexed by depth