summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-01-27 12:35:33 +1100
committerBen Skeggs <skeggsb@gmail.com>2008-01-27 12:35:33 +1100
commita556034514582dc8e1b8b65f56020031d513331b (patch)
tree182aaf4be24733e2943f9e39cfb86bc22f942efb /src/mesa
parent9043323f1437f9c6791845b3ddbb9af912b45110 (diff)
parentb717de3238a028a3fdfbaf13eb02dbde262f03e7 (diff)
Merge branch 'upstream-gallium-0.1' into darktama-gallium-0.1
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/Makefile3
-rw-r--r--src/mesa/drivers/dri/intel_winsys/intel_winsys.h23
-rw-r--r--src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c2
-rw-r--r--src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c131
-rw-r--r--src/mesa/drivers/x11/xm_winsys.c24
-rw-r--r--src/mesa/glapi/glthread.h6
-rw-r--r--src/mesa/pipe/cell/common.h42
-rw-r--r--src/mesa/pipe/cell/ppu/cell_batch.c7
-rw-r--r--src/mesa/pipe/cell/ppu/cell_batch.h2
-rw-r--r--src/mesa/pipe/cell/ppu/cell_clear.c5
-rw-r--r--src/mesa/pipe/cell/ppu/cell_clear.h6
-rw-r--r--src/mesa/pipe/cell/ppu/cell_context.c13
-rw-r--r--src/mesa/pipe/cell/ppu/cell_context.h4
-rw-r--r--src/mesa/pipe/cell/ppu/cell_draw_arrays.c17
-rw-r--r--src/mesa/pipe/cell/ppu/cell_draw_arrays.h2
-rw-r--r--src/mesa/pipe/cell/ppu/cell_flush.c19
-rw-r--r--src/mesa/pipe/cell/ppu/cell_flush.h3
-rw-r--r--src/mesa/pipe/cell/ppu/cell_render.c2
-rw-r--r--src/mesa/pipe/cell/ppu/cell_spu.c65
-rw-r--r--src/mesa/pipe/cell/ppu/cell_spu.h7
-rw-r--r--src/mesa/pipe/cell/ppu/cell_state.h1
-rw-r--r--src/mesa/pipe/cell/ppu/cell_state_derived.c164
-rw-r--r--src/mesa/pipe/cell/ppu/cell_state_emit.c20
-rw-r--r--src/mesa/pipe/cell/ppu/cell_state_fs.c3
-rw-r--r--src/mesa/pipe/cell/ppu/cell_state_surface.c128
-rw-r--r--src/mesa/pipe/cell/ppu/cell_surface.c4
-rw-r--r--src/mesa/pipe/cell/ppu/cell_texture.c13
-rw-r--r--src/mesa/pipe/cell/ppu/cell_texture.h2
-rw-r--r--src/mesa/pipe/cell/ppu/cell_vbuf.c28
-rw-r--r--src/mesa/pipe/cell/spu/spu_main.c79
-rw-r--r--src/mesa/pipe/cell/spu/spu_main.h13
-rw-r--r--src/mesa/pipe/cell/spu/spu_tri.c46
-rw-r--r--src/mesa/pipe/draw/draw_clip.c19
-rw-r--r--src/mesa/pipe/draw/draw_context.c35
-rw-r--r--src/mesa/pipe/draw/draw_context.h1
-rw-r--r--src/mesa/pipe/draw/draw_cull.c31
-rw-r--r--src/mesa/pipe/draw/draw_flatshade.c120
-rw-r--r--src/mesa/pipe/draw/draw_offset.c37
-rw-r--r--src/mesa/pipe/draw/draw_prim.c104
-rw-r--r--src/mesa/pipe/draw/draw_private.h50
-rw-r--r--src/mesa/pipe/draw/draw_stipple.c46
-rw-r--r--src/mesa/pipe/draw/draw_twoside.c99
-rw-r--r--src/mesa/pipe/draw/draw_unfilled.c33
-rw-r--r--src/mesa/pipe/draw/draw_validate.c80
-rw-r--r--src/mesa/pipe/draw/draw_vbuf.c44
-rw-r--r--src/mesa/pipe/draw/draw_vertex.c88
-rw-r--r--src/mesa/pipe/draw/draw_vertex.h43
-rw-r--r--src/mesa/pipe/draw/draw_vertex_cache.c10
-rw-r--r--src/mesa/pipe/draw/draw_vertex_fetch.c200
-rw-r--r--src/mesa/pipe/draw/draw_vertex_shader.c11
-rw-r--r--src/mesa/pipe/draw/draw_vertex_shader_llvm.c5
-rw-r--r--src/mesa/pipe/draw/draw_wide_prims.c53
-rw-r--r--src/mesa/pipe/failover/fo_context.c3
-rw-r--r--src/mesa/pipe/i915simple/i915_blit.c6
-rw-r--r--src/mesa/pipe/i915simple/i915_blit.h6
-rw-r--r--src/mesa/pipe/i915simple/i915_context.c6
-rw-r--r--src/mesa/pipe/i915simple/i915_context.h4
-rw-r--r--src/mesa/pipe/i915simple/i915_fpc_translate.c7
-rw-r--r--src/mesa/pipe/i915simple/i915_prim_emit.c25
-rw-r--r--src/mesa/pipe/i915simple/i915_prim_vbuf.c11
-rw-r--r--src/mesa/pipe/i915simple/i915_state.c3
-rw-r--r--src/mesa/pipe/i915simple/i915_state_derived.c26
-rw-r--r--src/mesa/pipe/i915simple/i915_state_emit.c17
-rw-r--r--src/mesa/pipe/i915simple/i915_surface.c26
-rw-r--r--src/mesa/pipe/i915simple/i915_texture.c16
-rw-r--r--src/mesa/pipe/i915simple/i915_winsys.h4
-rw-r--r--src/mesa/pipe/i965simple/brw_batch.h3
-rw-r--r--src/mesa/pipe/i965simple/brw_blit.c6
-rw-r--r--src/mesa/pipe/i965simple/brw_blit.h8
-rw-r--r--src/mesa/pipe/i965simple/brw_context.h6
-rw-r--r--src/mesa/pipe/i965simple/brw_curbe.c7
-rw-r--r--src/mesa/pipe/i965simple/brw_draw.c4
-rw-r--r--src/mesa/pipe/i965simple/brw_draw.h2
-rw-r--r--src/mesa/pipe/i965simple/brw_draw_upload.c10
-rw-r--r--src/mesa/pipe/i965simple/brw_misc_state.c8
-rw-r--r--src/mesa/pipe/i965simple/brw_state.h2
-rw-r--r--src/mesa/pipe/i965simple/brw_state_pool.c17
-rw-r--r--src/mesa/pipe/i965simple/brw_surface.c6
-rw-r--r--src/mesa/pipe/i965simple/brw_tex_layout.c17
-rw-r--r--src/mesa/pipe/i965simple/brw_vs_emit.c34
-rw-r--r--src/mesa/pipe/i965simple/brw_winsys.h12
-rw-r--r--src/mesa/pipe/i965simple/brw_wm_surface_state.c2
-rw-r--r--src/mesa/pipe/llvm/Makefile2
-rw-r--r--src/mesa/pipe/llvm/gallivm.cpp11
-rw-r--r--src/mesa/pipe/llvm/gallivm.h4
-rw-r--r--src/mesa/pipe/llvm/llvm_entry.c89
-rw-r--r--src/mesa/pipe/p_compiler.h3
-rw-r--r--src/mesa/pipe/p_context.h38
-rw-r--r--src/mesa/pipe/p_defines.h27
-rw-r--r--src/mesa/pipe/p_inlines.h47
-rw-r--r--src/mesa/pipe/p_state.h26
-rw-r--r--src/mesa/pipe/p_thread.h54
-rw-r--r--src/mesa/pipe/p_util.h2
-rw-r--r--src/mesa/pipe/p_winsys.h76
-rw-r--r--src/mesa/pipe/pipebuffer/Makefile3
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer.c49
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer.h127
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_client.c62
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_fenced.c121
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_fenced.h10
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_handle.c182
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_handle.h120
-rw-r--r--src/mesa/pipe/pipebuffer/pb_buffer_malloc.c51
-rw-r--r--src/mesa/pipe/pipebuffer/pb_bufmgr.h31
-rw-r--r--src/mesa/pipe/pipebuffer/pb_bufmgr_fenced.c48
-rw-r--r--src/mesa/pipe/pipebuffer/pb_bufmgr_mm.c420
-rw-r--r--src/mesa/pipe/pipebuffer/pb_bufmgr_pool.c109
-rw-r--r--src/mesa/pipe/softpipe/sp_clear.c11
-rw-r--r--src/mesa/pipe/softpipe/sp_context.c28
-rw-r--r--src/mesa/pipe/softpipe/sp_context.h12
-rw-r--r--src/mesa/pipe/softpipe/sp_draw_arrays.c17
-rw-r--r--src/mesa/pipe/softpipe/sp_flush.c7
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_setup.c335
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_setup.h10
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_vbuf.c388
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_vbuf.h (renamed from src/mesa/pipe/pipebuffer/pb_buffer_null.c)82
-rw-r--r--src/mesa/pipe/softpipe/sp_quad.c4
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_depth_test.c4
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_fs.c5
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_stencil.c4
-rw-r--r--src/mesa/pipe/softpipe/sp_state.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_state_derived.c142
-rw-r--r--src/mesa/pipe/softpipe/sp_state_fs.c7
-rw-r--r--src/mesa/pipe/softpipe/sp_state_surface.c10
-rw-r--r--src/mesa/pipe/softpipe/sp_surface.c25
-rw-r--r--src/mesa/pipe/softpipe/sp_texture.c13
-rw-r--r--src/mesa/pipe/softpipe/sp_texture.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_tile_cache.c14
-rw-r--r--src/mesa/pipe/util/p_tile.c4
-rw-r--r--src/mesa/pipe/xlib/fakeglx.c8
-rw-r--r--src/mesa/pipe/xlib/xm_winsys.c149
-rw-r--r--src/mesa/pipe/xlib/xm_winsys_aub.c200
-rw-r--r--src/mesa/pipe/xlib/xm_winsys_aub.h4
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c17
-rw-r--r--src/mesa/state_tracker/st_atom_framebuffer.c15
-rw-r--r--src/mesa/state_tracker/st_atom_rasterizer.c15
-rw-r--r--src/mesa/state_tracker/st_cb_bufferobjects.c109
-rw-r--r--src/mesa/state_tracker/st_cb_bufferobjects.h5
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c6
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c4
-rw-r--r--src/mesa/state_tracker/st_cb_feedback.c24
-rw-r--r--src/mesa/state_tracker/st_cb_flush.c44
-rw-r--r--src/mesa/state_tracker/st_cb_rasterpos.c19
-rw-r--r--src/mesa/state_tracker/st_context.c3
-rw-r--r--src/mesa/state_tracker/st_context.h7
-rw-r--r--src/mesa/state_tracker/st_draw.c72
-rw-r--r--src/mesa/state_tracker/st_framebuffer.c27
-rw-r--r--src/mesa/state_tracker/st_public.h1
-rw-r--r--src/mesa/state_tracker/st_texture.c35
-rw-r--r--src/mesa/x86/Makefile2
150 files changed, 2675 insertions, 3226 deletions
diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index 681c566140..b16d74bf49 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -125,6 +125,7 @@ osmesa-only: depend subdirs $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME)
# Make the GL library
$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) $(LLVM_LIB)
@ $(TOP)/bin/mklib -o $(GL_LIB) \
+ -linker $(CC) \
-major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
-install $(TOP)/$(LIB_DIR) \
$(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \
@@ -134,12 +135,14 @@ $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(CELL_LIB)
$(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OSMESA_DRIVER_OBJECTS) $(OSMESA16_OBJECTS)
@ if [ "${DRIVER_DIRS}" = "osmesa" ] ; then \
$(TOP)/bin/mklib -o $(OSMESA_LIB) \
+ -linker $(CC) \
-major $(MESA_MAJOR) \
-minor $(MESA_MINOR) -patch $(MESA_TINY) \
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
$(OSMESA_LIB_DEPS) $(OSMESA16_OBJECTS) ; \
else \
$(TOP)/bin/mklib -o $(OSMESA_LIB) \
+ -linker $(CC) \
-major $(MESA_MAJOR) \
-minor $(MESA_MINOR) -patch $(GL_TINY) \
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
diff --git a/src/mesa/drivers/dri/intel_winsys/intel_winsys.h b/src/mesa/drivers/dri/intel_winsys/intel_winsys.h
index 89e63e0a79..ffc40782be 100644
--- a/src/mesa/drivers/dri/intel_winsys/intel_winsys.h
+++ b/src/mesa/drivers/dri/intel_winsys/intel_winsys.h
@@ -28,10 +28,12 @@
#ifndef INTEL_WINSYS_H
#define INTEL_WINSYS_H
+#include "pipe/p_state.h"
+
struct intel_context;
struct pipe_context;
struct pipe_winsys;
-struct pipe_buffer_handle;
+struct pipe_buffer;
struct _DriBufferObject;
struct pipe_winsys *
@@ -49,20 +51,21 @@ intel_create_i915simple( struct intel_context *intel,
struct pipe_winsys *winsys );
+struct intel_buffer {
+ struct pipe_buffer base;
+ struct _DriBufferObject *driBO;
+};
-/* Turn the pipe opaque buffer pointer into a dri_bufmgr opaque
- * buffer pointer...
- */
-static INLINE struct _DriBufferObject *
-dri_bo( struct pipe_buffer_handle *bo )
+static INLINE struct intel_buffer *
+intel_buffer( struct pipe_buffer *buf )
{
- return (struct _DriBufferObject *)bo;
+ return (struct intel_buffer *)buf;
}
-static INLINE struct pipe_buffer_handle *
-pipe_bo( struct _DriBufferObject *bo )
+static INLINE struct _DriBufferObject *
+dri_bo( struct pipe_buffer *buf )
{
- return (struct pipe_buffer_handle *)bo;
+ return intel_buffer(buf)->driBO;
}
diff --git a/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c b/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c
index 8e0eea4392..1ba6a9e1b2 100644
--- a/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c
+++ b/src/mesa/drivers/dri/intel_winsys/intel_winsys_i915.c
@@ -85,7 +85,7 @@ static void intel_i915_batch_dword( struct i915_winsys *sws,
}
static void intel_i915_batch_reloc( struct i915_winsys *sws,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned access_flags,
unsigned delta )
{
diff --git a/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c b/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c
index 340fa2fb85..910c0d2cc5 100644
--- a/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c
+++ b/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c
@@ -43,6 +43,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
@@ -65,100 +66,98 @@ intel_pipe_winsys( struct pipe_winsys *winsys )
/* Most callbacks map direcly onto dri_bufmgr operations:
*/
static void *intel_buffer_map(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned flags )
{
unsigned drm_flags = 0;
- if (flags & PIPE_BUFFER_FLAG_WRITE)
+ if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
drm_flags |= DRM_BO_FLAG_WRITE;
- if (flags & PIPE_BUFFER_FLAG_READ)
+ if (flags & PIPE_BUFFER_USAGE_CPU_READ)
drm_flags |= DRM_BO_FLAG_READ;
return driBOMap( dri_bo(buf), drm_flags, 0 );
}
static void intel_buffer_unmap(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf)
+ struct pipe_buffer *buf)
{
driBOUnmap( dri_bo(buf) );
}
static void
-intel_buffer_reference(struct pipe_winsys *winsys,
- struct pipe_buffer_handle **ptr,
- struct pipe_buffer_handle *buf)
+intel_buffer_destroy(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf)
{
- if (*ptr) {
- driBOUnReference( dri_bo(*ptr) );
- *ptr = NULL;
- }
-
- if (buf) {
- driBOReference( dri_bo(buf) );
- *ptr = buf;
- }
+ driBOUnReference( dri_bo(buf) );
}
-/* Grabs the hardware lock!
- */
-static int intel_buffer_data(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf,
- unsigned size, const void *data,
- unsigned usage )
-{
- driBOData( dri_bo(buf), size, data, 0 );
- return 0;
-}
-
-static int intel_buffer_subdata(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf,
- unsigned long offset,
- unsigned long size,
- const void *data)
-{
- driBOSubData( dri_bo(buf), offset, size, data );
- return 0;
-}
-
-static int intel_buffer_get_subdata(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf,
- unsigned long offset,
- unsigned long size,
- void *data)
-{
- driBOGetSubData( dri_bo(buf), offset, size, data );
- return 0;
-}
-
/* Pipe has no concept of pools. We choose the tex/region pool
* for all buffers.
+ * Grabs the hardware lock!
*/
-static struct pipe_buffer_handle *
+static struct pipe_buffer *
intel_buffer_create(struct pipe_winsys *winsys,
unsigned alignment,
- unsigned flags,
- unsigned hint )
+ unsigned usage,
+ unsigned size )
{
- struct _DriBufferObject *buffer;
+ struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer );
struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
+ unsigned flags = 0;
+
+ buffer->base.refcount = 1;
+ buffer->base.alignment = alignment;
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ if (usage & (PIPE_BUFFER_USAGE_VERTEX /*| IWS_BUFFER_USAGE_LOCAL*/)) {
+ flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED;
+ } else {
+ flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT;
+ }
+
+ if (usage & PIPE_BUFFER_USAGE_GPU_READ)
+ flags |= DRM_BO_FLAG_READ;
+
+ if (usage & PIPE_BUFFER_USAGE_GPU_WRITE)
+ flags |= DRM_BO_FLAG_WRITE;
+
+ /* drm complains if we don't set any read/write flags.
+ */
+ if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0)
+ flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE;
+
+#if 0
+ if (flags & IWS_BUFFER_USAGE_EXE)
+ flags |= DRM_BO_FLAG_EXE;
+
+ if (usage & IWS_BUFFER_USAGE_CACHED)
+ flags |= DRM_BO_FLAG_CACHED;
+#endif
+
driGenBuffers( iws->regionPool,
- "pipe buffer", 1, &buffer, alignment, flags, hint );
- return pipe_bo(buffer);
+ "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 );
+
+ driBOData( buffer->driBO, size, NULL, 0 );
+
+ return &buffer->base;
}
-static struct pipe_buffer_handle *
+static struct pipe_buffer *
intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
{
- struct _DriBufferObject *buffer;
+ struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer );
struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
+
driGenUserBuffer( iws->regionPool,
- "pipe user buffer", &buffer, ptr, bytes);
- return pipe_bo(buffer);
+ "pipe user buffer", &buffer->driBO, ptr, bytes);
+
+ return &buffer->base;
}
@@ -219,17 +218,14 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys,
surf->pitch = round_up(width, alignment / surf->cpp);
assert(!surf->buffer);
- surf->buffer = winsys->buffer_create(winsys, alignment, 0, 0);
+ surf->buffer = winsys->buffer_create(winsys, alignment,
+ PIPE_BUFFER_USAGE_PIXEL,
+ surf->pitch * surf->cpp * height);
if(!surf->buffer)
return -1;
- ret = winsys->buffer_data(winsys,
- surf->buffer,
- surf->pitch * surf->cpp * height,
- NULL,
- PIPE_BUFFER_USAGE_PIXEL);
if(ret) {
- winsys->buffer_reference(winsys, &surf->buffer, NULL);
+ pipe_buffer_reference(winsys, &surf->buffer, NULL);
return ret;
}
@@ -244,7 +240,7 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
surf->refcount--;
if (surf->refcount == 0) {
if (surf->buffer)
- winsys->buffer_reference(winsys, &surf->buffer, NULL);
+ pipe_buffer_reference(winsys, &surf->buffer, NULL);
free(surf);
}
*s = NULL;
@@ -284,10 +280,7 @@ intel_create_pipe_winsys( int fd )
iws->winsys.user_buffer_create = intel_user_buffer_create;
iws->winsys.buffer_map = intel_buffer_map;
iws->winsys.buffer_unmap = intel_buffer_unmap;
- iws->winsys.buffer_reference = intel_buffer_reference;
- iws->winsys.buffer_data = intel_buffer_data;
- iws->winsys.buffer_subdata = intel_buffer_subdata;
- iws->winsys.buffer_get_subdata = intel_buffer_get_subdata;
+ iws->winsys.buffer_destroy = intel_buffer_destroy;
iws->winsys.flush_frontbuffer = intel_flush_frontbuffer;
iws->winsys.printf = intel_printf;
iws->winsys.get_name = intel_get_name;
diff --git a/src/mesa/drivers/x11/xm_winsys.c b/src/mesa/drivers/x11/xm_winsys.c
index dafbe96a1e..a690df2772 100644
--- a/src/mesa/drivers/x11/xm_winsys.c
+++ b/src/mesa/drivers/x11/xm_winsys.c
@@ -71,15 +71,15 @@ struct xm_buffer
* buffer pointer...
*/
static inline struct xm_buffer *
-xm_bo( struct pipe_buffer_handle *bo )
+xm_bo( struct pipe_buffer *bo )
{
return (struct xm_buffer *) bo;
}
-static inline struct pipe_buffer_handle *
+static inline struct pipe_buffer *
pipe_bo( struct xm_buffer *bo )
{
- return (struct pipe_buffer_handle *) bo;
+ return (struct pipe_buffer *) bo;
}
/* Turn a softpipe winsys into an xm/softpipe winsys:
@@ -94,7 +94,7 @@ xm_winsys(struct softpipe_winsys *sws)
/* Most callbacks map direcly onto dri_bufmgr operations:
*/
static void *
-xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
+xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
unsigned flags)
{
struct xm_buffer *xm_buf = xm_bo(buf);
@@ -103,7 +103,7 @@ xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
}
static void
-xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer_handle *buf)
+xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
{
struct xm_buffer *xm_buf = xm_bo(buf);
xm_buf->mapped = NULL;
@@ -111,8 +111,8 @@ xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer_handle *buf)
static void
xm_buffer_reference(struct pipe_winsys *pws,
- struct pipe_buffer_handle **ptr,
- struct pipe_buffer_handle *buf)
+ struct pipe_buffer **ptr,
+ struct pipe_buffer *buf)
{
if (*ptr) {
struct xm_buffer *oldBuf = xm_bo(*ptr);
@@ -139,7 +139,7 @@ xm_buffer_reference(struct pipe_winsys *pws,
}
static void
-xm_buffer_data(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
+xm_buffer_data(struct pipe_winsys *pws, struct pipe_buffer *buf,
unsigned size, const void *data, unsigned usage)
{
struct xm_buffer *xm_buf = xm_bo(buf);
@@ -155,7 +155,7 @@ xm_buffer_data(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
}
static void
-xm_buffer_subdata(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
+xm_buffer_subdata(struct pipe_winsys *pws, struct pipe_buffer *buf,
unsigned long offset, unsigned long size, const void *data)
{
struct xm_buffer *xm_buf = xm_bo(buf);
@@ -166,7 +166,7 @@ xm_buffer_subdata(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
}
static void
-xm_buffer_get_subdata(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
+xm_buffer_get_subdata(struct pipe_winsys *pws, struct pipe_buffer *buf,
unsigned long offset, unsigned long size, void *data)
{
const struct xm_buffer *xm_buf = xm_bo(buf);
@@ -209,7 +209,7 @@ xm_get_name(struct pipe_winsys *pws)
}
-static struct pipe_buffer_handle *
+static struct pipe_buffer *
xm_buffer_create(struct pipe_winsys *pws,
unsigned alignment,
unsigned flags,
@@ -224,7 +224,7 @@ xm_buffer_create(struct pipe_winsys *pws,
/**
* Create buffer which wraps user-space data.
*/
-static struct pipe_buffer_handle *
+static struct pipe_buffer *
xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
{
struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
diff --git a/src/mesa/glapi/glthread.h b/src/mesa/glapi/glthread.h
index a61086d0dc..afb04f7bf2 100644
--- a/src/mesa/glapi/glthread.h
+++ b/src/mesa/glapi/glthread.h
@@ -259,11 +259,11 @@ typedef benaphore _glthread_Mutex;
* THREADS not defined
*/
-typedef GLuint _glthread_TSD;
+typedef unsigned _glthread_TSD;
-typedef GLuint _glthread_Thread;
+typedef unsigned _glthread_Thread;
-typedef GLuint _glthread_Mutex;
+typedef unsigned _glthread_Mutex;
#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0
diff --git a/src/mesa/pipe/cell/common.h b/src/mesa/pipe/cell/common.h
index 4c998722a2..e925299119 100644
--- a/src/mesa/pipe/cell/common.h
+++ b/src/mesa/pipe/cell/common.h
@@ -38,11 +38,25 @@
#include "pipe/p_format.h"
+/** The standard assert macro doesn't seem to work reliably */
+#define ASSERT(x) \
+ if (!(x)) { \
+ ubyte *p = NULL; \
+ fprintf(stderr, "%s:%d: %s(): assertion %s failed.\n", \
+ __FILE__, __LINE__, __FUNCTION__, #x); \
+ *p = 0; \
+ exit(1); \
+ }
+
+
/** for sanity checking */
#define ASSERT_ALIGN16(ptr) \
assert((((unsigned long) (ptr)) & 0xf) == 0);
+/** round up value to next multiple of 16 */
+#define ROUNDUP16(k) (((k) + 0xf) & ~0xf)
+
#define TILE_SIZE 32
@@ -53,14 +67,15 @@
*/
#define CELL_CMD_OPCODE_MASK 0xf
-#define CELL_CMD_EXIT 1
-#define CELL_CMD_FRAMEBUFFER 2
-#define CELL_CMD_CLEAR_SURFACE 3
-#define CELL_CMD_FINISH 4
-#define CELL_CMD_RENDER 5
-#define CELL_CMD_BATCH 6
-#define CELL_CMD_STATE_DEPTH_STENCIL 7
-#define CELL_CMD_STATE_SAMPLER 8
+#define CELL_CMD_EXIT 1
+#define CELL_CMD_CLEAR_SURFACE 2
+#define CELL_CMD_FINISH 3
+#define CELL_CMD_RENDER 4
+#define CELL_CMD_BATCH 5
+#define CELL_CMD_STATE_FRAMEBUFFER 10
+#define CELL_CMD_STATE_DEPTH_STENCIL 11
+#define CELL_CMD_STATE_SAMPLER 12
+#define CELL_CMD_STATE_VERTEX_INFO 13
#define CELL_NUM_BATCH_BUFFERS 3
@@ -96,12 +111,15 @@ struct cell_command_clear_surface
#define CELL_MAX_VBUF_SIZE (16 * 1024)
#define CELL_MAX_VBUF_INDEXES 1024
-#define CELL_MAX_ATTRIBS 2 /* temporary! */
+
+
struct cell_command_render
{
- uint opcode;
- uint prim_type;
- uint num_verts, num_attribs;
+ uint opcode; /**< CELL_CMD_RENDER */
+ uint prim_type; /**< PIPE_PRIM_x */
+ uint num_verts;
+ uint vertex_size; /**< bytes per vertex */
+ uint dummy; /* XXX this dummy field works around a compiler bug */
uint num_indexes;
const void *vertex_data;
const ushort *index_data;
diff --git a/src/mesa/pipe/cell/ppu/cell_batch.c b/src/mesa/pipe/cell/ppu/cell_batch.c
index ab4553f16c..5a25f1b266 100644
--- a/src/mesa/pipe/cell/ppu/cell_batch.c
+++ b/src/mesa/pipe/cell/ppu/cell_batch.c
@@ -34,13 +34,18 @@
void
cell_batch_flush(struct cell_context *cell)
{
+ static boolean flushing = FALSE;
uint batch = cell->cur_batch;
const uint size = cell->batch_buffer_size[batch];
uint spu, cmd_word;
+ assert(!flushing);
+
if (size == 0)
return;
+ flushing = TRUE;
+
assert(batch < CELL_NUM_BATCH_BUFFERS);
/*
@@ -86,6 +91,8 @@ cell_batch_flush(struct cell_context *cell)
cell->batch_buffer_size[batch] = 0; /* empty */
cell->cur_batch = batch;
+
+ flushing = FALSE;
}
diff --git a/src/mesa/pipe/cell/ppu/cell_batch.h b/src/mesa/pipe/cell/ppu/cell_batch.h
index 7a5c6392d7..47e3287626 100644
--- a/src/mesa/pipe/cell/ppu/cell_batch.h
+++ b/src/mesa/pipe/cell/ppu/cell_batch.h
@@ -29,6 +29,8 @@
#ifndef CELL_BATCH_H
#define CELL_BATCH_H
+#include "pipe/p_compiler.h"
+
struct cell_context;
diff --git a/src/mesa/pipe/cell/ppu/cell_clear.c b/src/mesa/pipe/cell/ppu/cell_clear.c
index 48c1c8e2c8..e01640b994 100644
--- a/src/mesa/pipe/cell/ppu/cell_clear.c
+++ b/src/mesa/pipe/cell/ppu/cell_clear.c
@@ -39,6 +39,7 @@
#include "cell_clear.h"
#include "cell_context.h"
#include "cell_batch.h"
+#include "cell_flush.h"
#include "cell_spu.h"
@@ -47,13 +48,13 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps,
unsigned clearValue)
{
struct cell_context *cell = cell_context(pipe);
- uint i;
+ /*uint i;*/
uint surfIndex;
if (!cell->cbuf_map[0])
cell->cbuf_map[0] = pipe_surface_map(ps);
- if (ps == cell->framebuffer.zbuf) {
+ if (ps == cell->framebuffer.zsbuf) {
surfIndex = 1;
}
else {
diff --git a/src/mesa/pipe/cell/ppu/cell_clear.h b/src/mesa/pipe/cell/ppu/cell_clear.h
index 4c69c4c89f..ff47d43f4c 100644
--- a/src/mesa/pipe/cell/ppu/cell_clear.h
+++ b/src/mesa/pipe/cell/ppu/cell_clear.h
@@ -26,8 +26,8 @@
**************************************************************************/
-#ifndef CELL_SURFACE_H
-#define CELL_SURFACE_H
+#ifndef CELL_CLEAR_H
+#define CELL_CLEAR_H
struct pipe_context;
@@ -40,4 +40,4 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps,
-#endif /* CELL_SURFACE_H */
+#endif /* CELL_CLEAR_H */
diff --git a/src/mesa/pipe/cell/ppu/cell_context.c b/src/mesa/pipe/cell/ppu/cell_context.c
index 3db1dbdb46..8cb0c48f40 100644
--- a/src/mesa/pipe/cell/ppu/cell_context.c
+++ b/src/mesa/pipe/cell/ppu/cell_context.c
@@ -56,7 +56,7 @@ static boolean
cell_is_format_supported( struct pipe_context *pipe,
enum pipe_format format, uint type )
{
- struct cell_context *cell = cell_context( pipe );
+ /*struct cell_context *cell = cell_context( pipe );*/
switch (type) {
case PIPE_TEXTURE:
@@ -268,16 +268,5 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws)
}
}
-
-#if 0
- test_spus(cell);
-#endif
-
return &cell->pipe;
}
-
-
-#if 0
-/** [4] to ensure 16-byte alignment for each status word */
-uint buffer_status[CELL_MAX_SPUS][CELL_NUM_BATCH_BUFFERS][4] ALIGN16_ATTRIB;
-#endif
diff --git a/src/mesa/pipe/cell/ppu/cell_context.h b/src/mesa/pipe/cell/ppu/cell_context.h
index 1937812e2d..3bd88bfd5b 100644
--- a/src/mesa/pipe/cell/ppu/cell_context.h
+++ b/src/mesa/pipe/cell/ppu/cell_context.h
@@ -82,7 +82,7 @@ struct cell_context
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
- ubyte *zbuf_map;
+ ubyte *zsbuf_map;
uint dirty;
@@ -102,7 +102,7 @@ struct cell_context
uint num_spus;
- ubyte batch_buffer_size[CELL_NUM_BATCH_BUFFERS];
+ uint batch_buffer_size[CELL_NUM_BATCH_BUFFERS];
ubyte batch_buffer[CELL_NUM_BATCH_BUFFERS][CELL_BATCH_BUFFER_SIZE] ALIGN16_ATTRIB;
int cur_batch; /**< which batch buffer is being filled */
diff --git a/src/mesa/pipe/cell/ppu/cell_draw_arrays.c b/src/mesa/pipe/cell/ppu/cell_draw_arrays.c
index 537cec8785..717cd8370f 100644
--- a/src/mesa/pipe/cell/ppu/cell_draw_arrays.c
+++ b/src/mesa/pipe/cell/ppu/cell_draw_arrays.c
@@ -51,7 +51,7 @@ cell_map_constant_buffers(struct cell_context *sp)
for (i = 0; i < 2; i++) {
if (sp->constants[i].size)
sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer,
- PIPE_BUFFER_FLAG_READ);
+ PIPE_BUFFER_USAGE_CPU_READ);
}
draw_set_mapped_constant_buffer(sp->draw,
@@ -89,7 +89,7 @@ cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
*/
boolean
cell_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer_handle *indexBuffer,
+ struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
@@ -123,7 +123,7 @@ cell_draw_elements(struct pipe_context *pipe,
if (sp->vertex_buffer[i].buffer) {
void *buf = pipe->winsys->buffer_map(pipe->winsys,
sp->vertex_buffer[i].buffer,
- PIPE_BUFFER_FLAG_READ);
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(draw, i, buf);
}
}
@@ -131,7 +131,7 @@ cell_draw_elements(struct pipe_context *pipe,
if (indexBuffer) {
void *mapped_indexes = pipe->winsys->buffer_map(pipe->winsys,
indexBuffer,
- PIPE_BUFFER_FLAG_READ);
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
}
else {
@@ -143,21 +143,18 @@ cell_draw_elements(struct pipe_context *pipe,
/* draw! */
draw_arrays(draw, mode, start, count);
- /* always flush for now */
- draw_flush(draw);
-
/*
- * unmap vertex/index buffers
+ * unmap vertex/index buffers - will cause draw module to flush
*/
for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
if (sp->vertex_buffer[i].buffer) {
- pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, NULL);
+ pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
}
}
if (indexBuffer) {
- pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
draw_set_mapped_element_buffer(draw, 0, NULL);
+ pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
}
/* Note: leave drawing surfaces mapped */
diff --git a/src/mesa/pipe/cell/ppu/cell_draw_arrays.h b/src/mesa/pipe/cell/ppu/cell_draw_arrays.h
index bd5b703f3b..d5df4aa05f 100644
--- a/src/mesa/pipe/cell/ppu/cell_draw_arrays.h
+++ b/src/mesa/pipe/cell/ppu/cell_draw_arrays.h
@@ -33,7 +33,7 @@ boolean cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
unsigned start, unsigned count);
boolean cell_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer_handle *indexBuffer,
+ struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count);
diff --git a/src/mesa/pipe/cell/ppu/cell_flush.c b/src/mesa/pipe/cell/ppu/cell_flush.c
index 33cbe2a085..b98bb566b1 100644
--- a/src/mesa/pipe/cell/ppu/cell_flush.c
+++ b/src/mesa/pipe/cell/ppu/cell_flush.c
@@ -27,17 +27,34 @@
#include "cell_context.h"
+#include "cell_batch.h"
#include "cell_flush.h"
#include "cell_spu.h"
#include "cell_render.h"
+#include "pipe/draw/draw_context.h"
void
cell_flush(struct pipe_context *pipe, unsigned flags)
{
struct cell_context *cell = cell_context(pipe);
+
+ draw_flush( cell->draw );
+ cell_flush_int(pipe, flags);
+}
+
+
+/** internal flush */
+void
+cell_flush_int(struct pipe_context *pipe, unsigned flags)
+{
+ static boolean flushing = FALSE; /* recursion catcher */
+ struct cell_context *cell = cell_context(pipe);
uint i;
+ ASSERT(!flushing);
+ flushing = TRUE;
+
if (flags & PIPE_FLUSH_WAIT) {
uint *cmd = (uint *) cell_batch_alloc(cell, sizeof(uint));
*cmd = CELL_CMD_FINISH;
@@ -59,4 +76,6 @@ cell_flush(struct pipe_context *pipe, unsigned flags)
assert(k == CELL_CMD_FINISH);
}
}
+
+ flushing = FALSE;
}
diff --git a/src/mesa/pipe/cell/ppu/cell_flush.h b/src/mesa/pipe/cell/ppu/cell_flush.h
index cf1a104f97..eda351b1cb 100644
--- a/src/mesa/pipe/cell/ppu/cell_flush.h
+++ b/src/mesa/pipe/cell/ppu/cell_flush.h
@@ -32,4 +32,7 @@
extern void
cell_flush(struct pipe_context *pipe, unsigned flags);
+extern void
+cell_flush_int(struct pipe_context *pipe, unsigned flags);
+
#endif
diff --git a/src/mesa/pipe/cell/ppu/cell_render.c b/src/mesa/pipe/cell/ppu/cell_render.c
index ecdd47e28b..4ab277a4b2 100644
--- a/src/mesa/pipe/cell/ppu/cell_render.c
+++ b/src/mesa/pipe/cell/ppu/cell_render.c
@@ -152,7 +152,7 @@ cell_flush_prim_buffer(struct cell_context *cell)
struct cell_command_render *render = &cell_global.command[i].render;
render->prim_type = PIPE_PRIM_TRIANGLES;
render->num_verts = cell->prim_buffer.num_verts;
- render->num_attribs = CELL_MAX_ATTRIBS;
+ render->vertex_size = cell->vertex_info->size * 4;
render->xmin = cell->prim_buffer.xmin;
render->ymin = cell->prim_buffer.ymin;
render->xmax = cell->prim_buffer.xmax;
diff --git a/src/mesa/pipe/cell/ppu/cell_spu.c b/src/mesa/pipe/cell/ppu/cell_spu.c
index a21ab9ff3a..4627bc8d1f 100644
--- a/src/mesa/pipe/cell/ppu/cell_spu.c
+++ b/src/mesa/pipe/cell/ppu/cell_spu.c
@@ -133,71 +133,6 @@ cell_start_spus(struct cell_context *cell)
}
-/** wait for all SPUs to finish working */
-/** XXX temporary */
-void
-finish_all(uint num_spus)
-{
- uint i;
-
- for (i = 0; i < num_spus; i++) {
- send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_FINISH);
- }
- for (i = 0; i < num_spus; i++) {
- /* wait for mbox message */
- unsigned k;
-
- while (spe_out_mbox_read(cell_global.spe_contexts[i], &k, 1) < 1)
- ;
-
- assert(k == CELL_CMD_FINISH);
- }
-}
-
-
-/**
- ** Send test commands (XXX temporary)
- **/
-void
-test_spus(struct cell_context *cell)
-{
- uint i;
- struct pipe_surface *csurf = cell->framebuffer.cbufs[0];
- struct pipe_surface *zsurf = cell->framebuffer.zbuf;
-
- printf("PPU: sleep(2)\n\n\n");
- sleep(2);
-
- for (i = 0; i < cell->num_spus; i++) {
- cell_global.command[i].fb.color_start = cell->cbuf_map[0];
- cell_global.command[i].fb.depth_start = cell->zbuf_map;
- cell_global.command[i].fb.width = csurf->width;
- cell_global.command[i].fb.height = csurf->height;
- cell_global.command[i].fb.color_format = PIPE_FORMAT_A8R8G8B8_UNORM;
- cell_global.command[i].fb.depth_format = PIPE_FORMAT_Z32_UNORM;
- send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_FRAMEBUFFER);
- }
-
- for (i = 0; i < cell->num_spus; i++) {
- cell_global.command[i].clear.value = 0xff880044; /* XXX */
- cell_global.command[i].clear.surface = 0;
- send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_SURFACE);
- }
-
- finish_all(cell->num_spus);
-
- {
- uint *b = (uint*) cell->cbuf_map[0];
- printf("PPU: Clear results: 0x%x 0x%x 0x%x 0x%x\n",
- b[0], b[1000], b[2000], b[3000]);
- }
-
- for (i = 0; i < cell->num_spus; i++) {
- send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_EXIT);
- }
-}
-
-
/**
* Tell all the SPUs to stop/exit.
*/
diff --git a/src/mesa/pipe/cell/ppu/cell_spu.h b/src/mesa/pipe/cell/ppu/cell_spu.h
index b4bfbced80..19eff94f96 100644
--- a/src/mesa/pipe/cell/ppu/cell_spu.h
+++ b/src/mesa/pipe/cell/ppu/cell_spu.h
@@ -76,13 +76,6 @@ cell_start_spus(struct cell_context *cell);
extern void
-finish_all(uint num_spus);
-
-extern void
-test_spus(struct cell_context *cell);
-
-
-extern void
cell_spu_exit(struct cell_context *cell);
diff --git a/src/mesa/pipe/cell/ppu/cell_state.h b/src/mesa/pipe/cell/ppu/cell_state.h
index fbca7c9574..3a71ba14fa 100644
--- a/src/mesa/pipe/cell/ppu/cell_state.h
+++ b/src/mesa/pipe/cell/ppu/cell_state.h
@@ -19,6 +19,7 @@
#define CELL_NEW_VERTEX 0x1000
#define CELL_NEW_VS 0x2000
#define CELL_NEW_CONSTANTS 0x4000
+#define CELL_NEW_VERTEX_INFO 0x8000
diff --git a/src/mesa/pipe/cell/ppu/cell_state_derived.c b/src/mesa/pipe/cell/ppu/cell_state_derived.c
index 1e31c11ecd..56daf5dfde 100644
--- a/src/mesa/pipe/cell/ppu/cell_state_derived.c
+++ b/src/mesa/pipe/cell/ppu/cell_state_derived.c
@@ -30,103 +30,96 @@
#include "pipe/draw/draw_context.h"
#include "pipe/draw/draw_vertex.h"
#include "cell_context.h"
+#include "cell_batch.h"
#include "cell_state.h"
+#include "cell_state_emit.h"
+
+
+static int
+find_vs_output(const struct pipe_shader_state *vs,
+ uint semantic_name,
+ uint semantic_index)
+{
+ uint i;
+ for (i = 0; i < vs->num_outputs; i++) {
+ if (vs->output_semantic_name[i] == semantic_name &&
+ vs->output_semantic_index[i] == semantic_index)
+ return i;
+ }
+ return -1;
+}
/**
- * Determine which post-transform / pre-rasterization vertex attributes
- * we need.
- * Derived from: fs, setup states.
+ * Determine how to map vertex program outputs to fragment program inputs.
+ * Basically, this will be used when computing the triangle interpolation
+ * coefficients from the post-transform vertex attributes.
*/
-static void calculate_vertex_layout( struct cell_context *cell )
+static void
+calculate_vertex_layout( struct cell_context *cell )
{
-#if 0
- const struct pipe_shader_state *vs = cell->vs->state;
+ const struct pipe_shader_state *vs = &cell->vs->shader;
const struct pipe_shader_state *fs = &cell->fs->shader;
const enum interp_mode colorInterp
= cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
struct vertex_info *vinfo = &cell->vertex_info;
- boolean emitBack0 = FALSE, emitBack1 = FALSE, emitPsize = FALSE;
- uint front0 = 0, back0 = 0, front1 = 0, back1 = 0;
uint i;
-#endif
- const enum interp_mode colorInterp
- = cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
- struct vertex_info *vinfo = &cell->vertex_info;
- uint front0;
- uint src = 0;
-
- memset(vinfo, 0, sizeof(*vinfo));
+ int src;
#if 0
- if (fs->input_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
- /* Need Z if depth test is enabled or the fragment program uses the
- * fragment position (XYZW).
+ if (cell->vbuf) {
+ /* if using the post-transform vertex buffer, tell draw_vbuf to
+ * simply emit the whole post-xform vertex as-is:
*/
+ struct vertex_info *vinfo_vbuf = &cell->vertex_info_vbuf;
+ vinfo_vbuf->num_attribs = 0;
+ draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0);
+ vinfo_vbuf->size = 4 * vs->num_outputs + sizeof(struct vertex_header)/4;
}
-
- cell->psize_slot = -1;
#endif
- /* always emit vertex pos */
- draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR, src++);
+ /* reset vinfo */
+ vinfo->num_attribs = 0;
+
+ /* we always want to emit vertex pos */
+ src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
-#if 1
- front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++);
-#endif
-#if 0
/*
- * XXX I think we need to reconcile the vertex shader outputs with
- * the fragment shader inputs here to make sure the slots line up.
- * Might just be getting lucky so far.
- * Or maybe do that in the state tracker?
+ * Loop over fragment shader inputs, searching for the matching output
+ * from the vertex shader.
*/
-
- for (i = 0; i < vs->num_outputs; i++) {
- switch (vs->output_semantic_name[i]) {
-
+ for (i = 0; i < fs->num_inputs; i++) {
+ switch (fs->input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
- /* vertex programs always emit position, but might not be
- * needed for fragment progs.
- */
- /* no-op */
+ /* already done above */
break;
case TGSI_SEMANTIC_COLOR:
- if (vs->output_semantic_index[i] == 0) {
- front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++);
- }
- else {
- assert(vs->output_semantic_index[i] == 1);
- front1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++);
- }
- break;
-
- case TGSI_SEMANTIC_BCOLOR:
- if (vs->output_semantic_index[i] == 0) {
- emitBack0 = TRUE;
- }
- else {
- assert(vs->output_semantic_index[i] == 1);
- emitBack1 = TRUE;
- }
+ src = find_vs_output(vs, TGSI_SEMANTIC_COLOR,
+ fs->input_semantic_index[i]);
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
break;
case TGSI_SEMANTIC_FOG:
- draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_PERSPECTIVE, src++);
- break;
-
- case TGSI_SEMANTIC_PSIZE:
- /* XXX only emit if drawing points or front/back polygon mode
- * is point mode
- */
- emitPsize = TRUE;
+ src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0);
+#if 1
+ if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
+ src = 0;
+#endif
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
break;
case TGSI_SEMANTIC_GENERIC:
/* this includes texcoords and varying vars */
- draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE, src++);
+ src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
+ fs->input_semantic_index[i]);
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
break;
default:
@@ -134,40 +127,10 @@ static void calculate_vertex_layout( struct cell_context *cell )
}
}
- cell->nr_frag_attrs = fs->num_inputs;
+ draw_compute_vertex_size(vinfo);
- /* We want these after all other attribs since they won't get passed
- * to the fragment shader. All prior vertex output attribs should match
- * up 1:1 with the fragment shader inputs.
- */
- if (emitBack0) {
- back0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++);
- }
- if (emitBack1) {
- back1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++);
- }
- if (emitPsize) {
- cell->psize_slot
- = draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_CONSTANT, src++);
- }
-
- /* If the attributes have changed, tell the draw module about
- * the new vertex layout.
- */
- /* XXX we also need to do this when the shading mode (interp modes) change: */
-#endif
-
- if (1/*vinfo->attr_mask != cell->attr_mask*/) {
- /*cell->attr_mask = vinfo->attr_mask;*/
-
- draw_compute_vertex_size(vinfo);
- draw_set_vertex_info(cell->draw, vinfo);
-
-#if 0
- draw_set_twoside_attributes(cell->draw,
- front0, back0, front1, back1);
-#endif
- }
+ /* XXX only signal this if format really changes */
+ cell->dirty |= CELL_NEW_VERTEX_INFO;
}
@@ -208,9 +171,12 @@ compute_cliprect(struct cell_context *sp)
#endif
+
void cell_update_derived( struct cell_context *cell )
{
- if (cell->dirty & (CELL_NEW_RASTERIZER | CELL_NEW_FS))
+ if (cell->dirty & (CELL_NEW_RASTERIZER |
+ CELL_NEW_FS |
+ CELL_NEW_VS))
calculate_vertex_layout( cell );
#if 0
diff --git a/src/mesa/pipe/cell/ppu/cell_state_emit.c b/src/mesa/pipe/cell/ppu/cell_state_emit.c
index e7d14d0d25..dbca900c35 100644
--- a/src/mesa/pipe/cell/ppu/cell_state_emit.c
+++ b/src/mesa/pipe/cell/ppu/cell_state_emit.c
@@ -36,6 +36,20 @@
void
cell_emit_state(struct cell_context *cell)
{
+ if (cell->dirty & CELL_NEW_FRAMEBUFFER) {
+ struct pipe_surface *cbuf = cell->framebuffer.cbufs[0];
+ struct pipe_surface *zbuf = cell->framebuffer.zsbuf;
+ struct cell_command_framebuffer *fb
+ = cell_batch_alloc(cell, sizeof(*fb));
+ fb->opcode = CELL_CMD_STATE_FRAMEBUFFER;
+ fb->color_start = cell->cbuf_map[0];
+ fb->color_format = cbuf->format;
+ fb->depth_start = cell->zsbuf_map;
+ fb->depth_format = zbuf ? zbuf->format : PIPE_FORMAT_NONE;
+ fb->width = cell->framebuffer.cbufs[0]->width;
+ fb->height = cell->framebuffer.cbufs[0]->height;
+ }
+
if (cell->dirty & CELL_NEW_DEPTH_STENCIL) {
uint cmd = CELL_CMD_STATE_DEPTH_STENCIL;
cell_batch_append(cell, &cmd, 4);
@@ -49,4 +63,10 @@ cell_emit_state(struct cell_context *cell)
cell_batch_append(cell, cell->sampler[0],
sizeof(struct pipe_sampler_state));
}
+
+ if (cell->dirty & CELL_NEW_VERTEX_INFO) {
+ uint cmd = CELL_CMD_STATE_VERTEX_INFO;
+ cell_batch_append(cell, &cmd, 4);
+ cell_batch_append(cell, &cell->vertex_info, sizeof(struct vertex_info));
+ }
}
diff --git a/src/mesa/pipe/cell/ppu/cell_state_fs.c b/src/mesa/pipe/cell/ppu/cell_state_fs.c
index 5a935f2de1..81c2ac14dd 100644
--- a/src/mesa/pipe/cell/ppu/cell_state_fs.c
+++ b/src/mesa/pipe/cell/ppu/cell_state_fs.c
@@ -27,6 +27,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_winsys.h"
#include "pipe/draw/draw_context.h"
#if 0
@@ -163,7 +164,7 @@ cell_set_constant_buffer(struct pipe_context *pipe,
assert(index == 0);
/* note: reference counting */
- ws->buffer_reference(ws,
+ pipe_buffer_reference(ws,
&cell->constants[shader].buffer,
buf->buffer);
cell->constants[shader].size = buf->size;
diff --git a/src/mesa/pipe/cell/ppu/cell_state_surface.c b/src/mesa/pipe/cell/ppu/cell_state_surface.c
index 9bf3c339d2..287610b76b 100644
--- a/src/mesa/pipe/cell/ppu/cell_state_surface.c
+++ b/src/mesa/pipe/cell/ppu/cell_state_surface.c
@@ -27,10 +27,8 @@
#include "pipe/p_inlines.h"
-#include "cell_batch.h"
#include "cell_context.h"
#include "cell_state.h"
-#include "cell_spu.h"
void
@@ -39,14 +37,11 @@ cell_set_framebuffer_state(struct pipe_context *pipe,
{
struct cell_context *cell = cell_context(pipe);
- /* XXX revisit this memcmp! */
- if (memcmp(&cell->framebuffer, fb, sizeof(*fb))) {
+ if (1 /*memcmp(&cell->framebuffer, fb, sizeof(*fb))*/) {
struct pipe_surface *csurf = fb->cbufs[0];
- struct pipe_surface *zsurf = fb->zbuf;
+ struct pipe_surface *zsurf = fb->zsbuf;
uint i;
- /* change in fb state */
-
/* unmap old surfaces */
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
if (cell->framebuffer.cbufs[i] && cell->cbuf_map[i]) {
@@ -55,9 +50,9 @@ cell_set_framebuffer_state(struct pipe_context *pipe,
}
}
- if (cell->framebuffer.zbuf && cell->zbuf_map) {
- pipe_surface_unmap(cell->framebuffer.zbuf);
- cell->zbuf_map = NULL;
+ if (cell->framebuffer.zsbuf && cell->zsbuf_map) {
+ pipe_surface_unmap(cell->framebuffer.zsbuf);
+ cell->zsbuf_map = NULL;
}
/* update my state */
@@ -68,120 +63,9 @@ cell_set_framebuffer_state(struct pipe_context *pipe,
cell->cbuf_map[0] = pipe_surface_map(csurf);
if (zsurf)
- cell->zbuf_map = pipe_surface_map(zsurf);
+ cell->zsbuf_map = pipe_surface_map(zsurf);
-#if 0
- for (i = 0; i < cell->num_spus; i++) {
- struct cell_command_framebuffer *fb = &cell_global.command[i].fb;
- fb->opcode = CELL_CMD_FRAMEBUFFER;
- fb->color_start = csurf->map;
- fb->color_format = csurf->format;
- fb->depth_start = zsurf ? zsurf->map : NULL;
- fb->depth_format = zsurf ? zsurf->format : PIPE_FORMAT_NONE;
- fb->width = csurf->width;
- fb->height = csurf->height;
- send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_FRAMEBUFFER);
- }
-#endif
-#if 1
- {
- struct cell_command_framebuffer *fb
- = cell_batch_alloc(cell, sizeof(*fb));
- fb->opcode = CELL_CMD_FRAMEBUFFER;
- fb->color_start = cell->cbuf_map[0];
- fb->color_format = csurf->format;
- fb->depth_start = cell->zbuf_map;
- fb->depth_format = zsurf ? zsurf->format : PIPE_FORMAT_NONE;
- fb->width = csurf->width;
- fb->height = csurf->height;
- /*cell_batch_flush(cell);*/
- /*cell_flush(&cell->pipe, 0x0);*/
- }
-#endif
cell->dirty |= CELL_NEW_FRAMEBUFFER;
}
-
-#if 0
- struct pipe_surface *ps;
- uint i;
-
- for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
- /* check if changing cbuf */
- if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) {
- /* flush old */
- sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
- /* unmap old */
- ps = sp->framebuffer.cbufs[i];
- if (ps && ps->map)
- pipe_surface_unmap(ps);
- /* map new */
- ps = fb->cbufs[i];
- if (ps)
- pipe_surface_map(ps);
- /* assign new */
- sp->framebuffer.cbufs[i] = fb->cbufs[i];
-
- /* update cache */
- sp_tile_cache_set_surface(sp, sp->cbuf_cache[i], ps);
- }
- }
-
- sp->framebuffer.num_cbufs = fb->num_cbufs;
-
- /* zbuf changing? */
- if (sp->framebuffer.zbuf != fb->zbuf) {
- /* flush old */
- sp_flush_tile_cache(sp, sp->zbuf_cache);
- /* unmap old */
- ps = sp->framebuffer.zbuf;
- if (ps && ps->map)
- pipe_surface_unmap(ps);
- if (sp->framebuffer.sbuf == sp->framebuffer.zbuf) {
- /* combined z/stencil */
- sp->framebuffer.sbuf = NULL;
- }
- /* map new */
- ps = fb->zbuf;
- if (ps)
- pipe_surface_map(ps);
- /* assign new */
- sp->framebuffer.zbuf = fb->zbuf;
-
- /* update cache */
- sp_tile_cache_set_surface(sp, sp->zbuf_cache, ps);
- }
-
- /* XXX combined depth/stencil here */
-
- /* sbuf changing? */
- if (sp->framebuffer.sbuf != fb->sbuf) {
- /* flush old */
- sp_flush_tile_cache(sp, sp->sbuf_cache_sep);
- /* unmap old */
- ps = sp->framebuffer.sbuf;
- if (ps && ps->map)
- pipe_surface_unmap(ps);
- /* map new */
- ps = fb->sbuf;
- if (ps && fb->sbuf != fb->zbuf)
- pipe_surface_map(ps);
- /* assign new */
- sp->framebuffer.sbuf = fb->sbuf;
-
- /* update cache */
- if (fb->sbuf != fb->zbuf) {
- /* separate stencil buf */
- sp->sbuf_cache = sp->sbuf_cache_sep;
- sp_tile_cache_set_surface(sp, sp->sbuf_cache, ps);
- }
- else {
- /* combined depth/stencil */
- sp->sbuf_cache = sp->zbuf_cache;
- sp_tile_cache_set_surface(sp, sp->sbuf_cache, ps);
- }
- }
-
- sp->dirty |= SP_NEW_FRAMEBUFFER;
-#endif
}
diff --git a/src/mesa/pipe/cell/ppu/cell_surface.c b/src/mesa/pipe/cell/ppu/cell_surface.c
index c8796dab43..6b7b918128 100644
--- a/src/mesa/pipe/cell/ppu/cell_surface.c
+++ b/src/mesa/pipe/cell/ppu/cell_surface.c
@@ -173,10 +173,6 @@ cell_surface_fill(struct pipe_context *pipe,
void
cell_init_surface_functions(struct cell_context *cell)
{
- cell->pipe.get_tile = pipe_get_tile_raw;
- cell->pipe.put_tile = pipe_put_tile_raw;
-
- cell->pipe.surface_data = cell_surface_data;
cell->pipe.surface_copy = cell_surface_copy;
cell->pipe.surface_fill = cell_surface_fill;
}
diff --git a/src/mesa/pipe/cell/ppu/cell_texture.c b/src/mesa/pipe/cell/ppu/cell_texture.c
index 8f342d8aad..0a8190d983 100644
--- a/src/mesa/pipe/cell/ppu/cell_texture.c
+++ b/src/mesa/pipe/cell/ppu/cell_texture.c
@@ -91,12 +91,9 @@ cell_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
cell_texture_layout(spt);
- spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32, 0, 0);
-
- if (spt->buffer) {
- pipe->winsys->buffer_data(pipe->winsys, spt->buffer, spt->buffer_size,
- NULL, PIPE_BUFFER_USAGE_PIXEL);
- }
+ spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32,
+ PIPE_BUFFER_USAGE_PIXEL,
+ spt->buffer_size);
if (!spt->buffer) {
FREE(spt);
@@ -124,7 +121,7 @@ cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
*/
- pipe->winsys->buffer_reference(pipe->winsys, &spt->buffer, NULL);
+ pipe_buffer_reference(pipe->winsys, &spt->buffer, NULL);
FREE(spt);
}
@@ -147,7 +144,7 @@ cell_get_tex_surface(struct pipe_context *pipe,
if (ps) {
assert(ps->refcount);
assert(ps->winsys);
- pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, spt->buffer);
+ pipe_buffer_reference(pipe->winsys, &ps->buffer, spt->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
ps->width = pt->width[level];
diff --git a/src/mesa/pipe/cell/ppu/cell_texture.h b/src/mesa/pipe/cell/ppu/cell_texture.h
index 97d8bd1230..ef5808c086 100644
--- a/src/mesa/pipe/cell/ppu/cell_texture.h
+++ b/src/mesa/pipe/cell/ppu/cell_texture.h
@@ -44,7 +44,7 @@ struct cell_texture
/* The data is held here:
*/
- struct pipe_buffer_handle *buffer;
+ struct pipe_buffer *buffer;
unsigned long buffer_size;
};
diff --git a/src/mesa/pipe/cell/ppu/cell_vbuf.c b/src/mesa/pipe/cell/ppu/cell_vbuf.c
index a420de041a..00ff990eab 100644
--- a/src/mesa/pipe/cell/ppu/cell_vbuf.c
+++ b/src/mesa/pipe/cell/ppu/cell_vbuf.c
@@ -31,7 +31,9 @@
*/
+#include "cell_batch.h"
#include "cell_context.h"
+#include "cell_flush.h"
#include "cell_spu.h"
#include "cell_vbuf.h"
#include "pipe/draw/draw_vbuf.h"
@@ -141,26 +143,7 @@ cell_vbuf_draw(struct vbuf_render *vbr,
if (cvbr->prim != PIPE_PRIM_TRIANGLES)
return; /* only render tris for now */
-#if 0
- for (i = 0; i < cell->num_spus; i++) {
- struct cell_command_render *render = &cell_global.command[i].render;
- render->opcode = CELL_CMD_RENDER;
- render->prim_type = cvbr->prim;
- render->num_verts = nr_vertices;
- render->num_attribs = CELL_MAX_ATTRIBS; /* XXX fix */
- render->vertex_data = vertices;
- render->index_data = indices;
- render->num_indexes = nr_indices;
- render->xmin = xmin;
- render->ymin = ymin;
- render->xmax = xmax;
- render->ymax = ymax;
-
- ASSERT_ALIGN16(render->vertex_data);
- ASSERT_ALIGN16(render->index_data);
- send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_RENDER);
- }
-#else
+ /* build/insert batch RENDER command */
{
struct cell_command_render *render
= (struct cell_command_render *)
@@ -168,7 +151,7 @@ cell_vbuf_draw(struct vbuf_render *vbr,
render->opcode = CELL_CMD_RENDER;
render->prim_type = cvbr->prim;
render->num_verts = nr_vertices;
- render->num_attribs = CELL_MAX_ATTRIBS; /* XXX fix */
+ render->vertex_size = 4 * cell->vertex_info.size;
render->vertex_data = vertices;
render->index_data = indices;
render->num_indexes = nr_indices;
@@ -180,11 +163,10 @@ cell_vbuf_draw(struct vbuf_render *vbr,
ASSERT_ALIGN16(render->vertex_data);
ASSERT_ALIGN16(render->index_data);
}
-#endif
#if 01
/* XXX this is temporary */
- cell_flush(&cell->pipe, PIPE_FLUSH_WAIT);
+ cell_flush_int(&cell->pipe, PIPE_FLUSH_WAIT);
#endif
}
diff --git a/src/mesa/pipe/cell/spu/spu_main.c b/src/mesa/pipe/cell/spu/spu_main.c
index 2e5cb76b4a..ef605a5197 100644
--- a/src/mesa/pipe/cell/spu/spu_main.c
+++ b/src/mesa/pipe/cell/spu/spu_main.c
@@ -210,8 +210,8 @@ cmd_render(const struct cell_command_render *render)
/* we'll DMA into these buffers */
ubyte vertex_data[CELL_MAX_VBUF_SIZE] ALIGN16_ATTRIB;
ushort indexes[CELL_MAX_VBUF_INDEXES] ALIGN16_ATTRIB;
-
- uint i, j, vertex_size, vertex_bytes, index_bytes;
+ uint i, j, total_vertex_bytes, total_index_bytes;
+ const uint vertex_size = render->vertex_size; /* in bytes */
if (Debug) {
printf("SPU %u: RENDER prim %u, indices: %u, nr_vert: %u\n",
@@ -228,36 +228,34 @@ cmd_render(const struct cell_command_render *render)
ASSERT_ALIGN16(render->vertex_data);
ASSERT_ALIGN16(render->index_data);
- vertex_size = render->num_attribs * 4 * sizeof(float);
-
/* how much vertex data */
- vertex_bytes = render->num_verts * vertex_size;
- index_bytes = render->num_indexes * sizeof(ushort);
- if (index_bytes < 16)
- index_bytes = 16;
+ total_vertex_bytes = render->num_verts * vertex_size;
+ total_index_bytes = render->num_indexes * sizeof(ushort);
+ if (total_index_bytes < 16)
+ total_index_bytes = 16;
else
- index_bytes = (index_bytes + 15) & ~0xf; /* multiple of 16 */
+ total_index_bytes = ROUNDUP16(total_index_bytes);
/*
- printf("VBUF: indices at %p, vertices at %p vertex_bytes %u ind_bytes %u\n",
- render->index_data, render->vertex_data, vertex_bytes, index_bytes);
+ printf("VBUF: indices at %p, vertices at %p total_vertex_bytes %u ind_bytes %u\n",
+ render->index_data, render->vertex_data, total_vertex_bytes, total_index_bytes);
*/
- ASSERT(vertex_bytes % 16 == 0);
+ ASSERT(total_vertex_bytes % 16 == 0);
/* get vertex data from main memory */
mfc_get(vertex_data, /* dest */
(unsigned int) render->vertex_data, /* src */
- vertex_bytes, /* size */
+ total_vertex_bytes, /* size */
TAG_VERTEX_BUFFER,
0, /* tid */
0 /* rid */);
- ASSERT(index_bytes % 16 == 0);
+ ASSERT(total_index_bytes % 16 == 0);
/* get index data from main memory */
mfc_get(indexes, /* dest */
(unsigned int) render->index_data, /* src */
- index_bytes,
+ total_index_bytes,
TAG_INDEX_BUFFER,
0, /* tid */
0 /* rid */);
@@ -340,7 +338,7 @@ cmd_render(const struct cell_command_render *render)
static void
-cmd_framebuffer(const struct cell_command_framebuffer *cmd)
+cmd_state_framebuffer(const struct cell_command_framebuffer *cmd)
{
if (Debug)
printf("SPU %u: FRAMEBUFFER: %d x %d at %p, cformat 0x%x zformat 0x%x\n",
@@ -351,6 +349,9 @@ cmd_framebuffer(const struct cell_command_framebuffer *cmd)
cmd->color_format,
cmd->depth_format);
+ ASSERT_ALIGN16(cmd->color_start);
+ ASSERT_ALIGN16(cmd->depth_start);
+
spu.fb.color_start = cmd->color_start;
spu.fb.depth_start = cmd->depth_start;
spu.fb.color_format = cmd->color_format;
@@ -393,6 +394,17 @@ cmd_state_sampler(const struct pipe_sampler_state *state)
static void
+cmd_state_vertex_info(const struct vertex_info *vinfo)
+{
+ if (Debug)
+ printf("SPU %u: VERTEX_INFO num_attribs=%u\n", spu.init.id,
+ vinfo->num_attribs);
+ memcpy(&spu.vertex_info, vinfo, sizeof(*vinfo));
+}
+
+
+
+static void
cmd_finish(void)
{
if (Debug)
@@ -459,10 +471,9 @@ cmd_batch(uint opcode)
ASSERT_ALIGN16(spu.init.batch_buffers[buf]);
- size = (size + 0xf) & ~0xf;
+ size = ROUNDUP16(size);
- ASSERT(size % 16 == 0);
- ASSERT((unsigned int) spu.init.batch_buffers[buf] % 16 == 0);
+ ASSERT_ALIGN16(spu.init.batch_buffers[buf]);
mfc_get(buffer, /* dest */
(unsigned int) spu.init.batch_buffers[buf], /* src */
@@ -475,14 +486,13 @@ cmd_batch(uint opcode)
/* Tell PPU we're done copying the buffer to local store */
release_batch_buffer(buf);
-
for (pos = 0; pos < usize; /* no incr */) {
switch (buffer[pos]) {
- case CELL_CMD_FRAMEBUFFER:
+ case CELL_CMD_STATE_FRAMEBUFFER:
{
struct cell_command_framebuffer *fb
= (struct cell_command_framebuffer *) &buffer[pos];
- cmd_framebuffer(fb);
+ cmd_state_framebuffer(fb);
pos += sizeof(*fb) / 4;
}
break;
@@ -512,10 +522,13 @@ cmd_batch(uint opcode)
pos += (1 + sizeof(struct pipe_depth_stencil_alpha_state) / 4);
break;
case CELL_CMD_STATE_SAMPLER:
- cmd_state_sampler((struct pipe_sampler_state *)
- &buffer[pos+1]);
+ cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]);
pos += (1 + sizeof(struct pipe_sampler_state) / 4);
break;
+ case CELL_CMD_STATE_VERTEX_INFO:
+ cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]);
+ pos += (1 + sizeof(struct vertex_info) / 4);
+ break;
default:
printf("SPU %u: bad opcode: 0x%x\n", spu.init.id, buffer[pos]);
ASSERT(0);
@@ -571,8 +584,8 @@ main_loop(void)
printf("SPU %u: EXIT\n", spu.init.id);
exitFlag = 1;
break;
- case CELL_CMD_FRAMEBUFFER:
- cmd_framebuffer(&cmd.fb);
+ case CELL_CMD_STATE_FRAMEBUFFER:
+ cmd_state_framebuffer(&cmd.fb);
break;
case CELL_CMD_CLEAR_SURFACE:
cmd_clear_surface(&cmd.clear);
@@ -606,13 +619,21 @@ one_time_init(void)
}
+/* In some versions of the SDK the SPE main takes 'unsigned long' as a
+ * parameter. In others it takes 'unsigned long long'. Use a define to
+ * select between the two.
+ */
+#ifdef SPU_MAIN_PARAM_LONG_LONG
+typedef unsigned long long main_param_t;
+#else
+typedef unsigned long main_param_t;
+#endif
+
/**
* SPE entrypoint.
- * Note: example programs declare params as 'unsigned long long' but
- * that doesn't work.
*/
int
-main(unsigned long speid, unsigned long argp)
+main(main_param_t speid, main_param_t argp)
{
int tag = 0;
diff --git a/src/mesa/pipe/cell/spu/spu_main.h b/src/mesa/pipe/cell/spu/spu_main.h
index 3ef73c9473..5bc5d9fa99 100644
--- a/src/mesa/pipe/cell/spu/spu_main.h
+++ b/src/mesa/pipe/cell/spu/spu_main.h
@@ -30,6 +30,7 @@
#include "pipe/cell/common.h"
+#include "pipe/draw/draw_vertex.h"
#include "pipe/p_state.h"
@@ -59,6 +60,9 @@ struct spu_global
struct pipe_depth_stencil_alpha_state depth_stencil;
struct pipe_blend_state blend;
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
+
+ struct vertex_info vertex_info;
+
/* XXX more state to come */
} ALIGN16_ATTRIB;
@@ -82,15 +86,6 @@ extern struct spu_global spu;
#define TAG_MISC 18
-/** The standard assert macro doesn't seem to work on SPUs */
-#define ASSERT(x) \
- if (!(x)) { \
- fprintf(stderr, "SPU %d: %s:%d: %s(): assertion %s failed.\n", \
- spu.init.id, __FILE__, __LINE__, __FUNCTION__, #x); \
- exit(1); \
- }
-
-
extern void
wait_on_mask(unsigned tag);
diff --git a/src/mesa/pipe/cell/spu/spu_tri.c b/src/mesa/pipe/cell/spu/spu_tri.c
index 1d73c5171c..3d0d106c10 100644
--- a/src/mesa/pipe/cell/spu/spu_tri.c
+++ b/src/mesa/pipe/cell/spu/spu_tri.c
@@ -42,7 +42,7 @@
* Simplified types taken from other parts of Gallium
*/
struct vertex_header {
- float data[2][4]; /* pos and color */
+ float data[0][4];
};
struct prim_header {
@@ -727,40 +727,32 @@ static void tri_persp_coeff( struct setup_stage *setup,
*/
static void setup_tri_coefficients( struct setup_stage *setup )
{
-#if 0
- const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
- unsigned slot, j;
-
- /* z and w are done by linear interpolation:
- */
- tri_linear_coeff(setup, 0, 2);
- tri_linear_coeff(setup, 0, 3);
+#if 1
+ uint i;
- /* setup interpolation for all the remaining attributes:
- */
- for (slot = 1; slot < setup->quad.nr_attrs; slot++) {
- switch (interp[slot]) {
+ for (i = 0; i < spu.vertex_info.num_attribs; i++) {
+ switch (spu.vertex_info.interp_mode[i]) {
+ case INTERP_NONE:
+ break;
+ case INTERP_POS:
+ tri_linear_coeff(setup, i, 2, 3); /* slot 0, z */
+ /* XXX interp W if PERSPECTIVE... */
+ break;
case INTERP_CONSTANT:
- for (j = 0; j < NUM_CHANNELS; j++)
- const_coeff(setup, slot, j);
- break;
-
+ /* fall-through */
case INTERP_LINEAR:
- for (j = 0; j < NUM_CHANNELS; j++)
- tri_linear_coeff(setup, slot, j);
- break;
-
+ tri_linear_coeff(setup, i, 0, 4); /* slot 1, color */
+ break;
case INTERP_PERSPECTIVE:
- for (j = 0; j < NUM_CHANNELS; j++)
- tri_persp_coeff(setup, slot, j);
- break;
-
+ break;
default:
- /* invalid interp mode */
- assert(0);
+ ASSERT(0);
}
}
#else
+ ASSERT(spu.vertex_info.interp_mode[0] == INTERP_POS);
+ ASSERT(spu.vertex_info.interp_mode[1] == INTERP_LINEAR ||
+ spu.vertex_info.interp_mode[1] == INTERP_CONSTANT);
tri_linear_coeff(setup, 0, 2, 3); /* slot 0, z */
tri_linear_coeff(setup, 1, 0, 4); /* slot 1, color */
#endif
diff --git a/src/mesa/pipe/draw/draw_clip.c b/src/mesa/pipe/draw/draw_clip.c
index c50376f11f..2d410e3244 100644
--- a/src/mesa/pipe/draw/draw_clip.c
+++ b/src/mesa/pipe/draw/draw_clip.c
@@ -93,7 +93,7 @@ static void interp( const struct clipper *clip,
const struct vertex_header *out,
const struct vertex_header *in )
{
- const unsigned nr_attrs = clip->stage.draw->vertex_info.num_attribs;
+ const unsigned nr_attrs = clip->stage.draw->num_vs_outputs;
unsigned j;
/* Vertex header.
@@ -346,15 +346,6 @@ do_clip_line( struct draw_stage *stage,
}
-static void clip_begin( struct draw_stage *stage )
-{
- /* should always have position, at least */
- assert(stage->draw->vertex_info.num_attribs >= 1);
-
- stage->next->begin( stage->next );
-}
-
-
static void
clip_point( struct draw_stage *stage,
struct prim_header *header )
@@ -402,10 +393,9 @@ clip_tri( struct draw_stage *stage,
}
}
-
-static void clip_end( struct draw_stage *stage )
+static void clip_flush( struct draw_stage *stage, unsigned flags )
{
- stage->next->end( stage->next );
+ stage->next->flush( stage->next, flags );
}
@@ -433,11 +423,10 @@ struct draw_stage *draw_clip_stage( struct draw_context *draw )
draw_alloc_tmps( &clipper->stage, MAX_CLIPPED_VERTICES );
clipper->stage.draw = draw;
- clipper->stage.begin = clip_begin;
clipper->stage.point = clip_point;
clipper->stage.line = clip_line;
clipper->stage.tri = clip_tri;
- clipper->stage.end = clip_end;
+ clipper->stage.flush = clip_flush;
clipper->stage.reset_stipple_counter = clip_reset_stipple_counter;
clipper->stage.destroy = clip_destroy;
diff --git a/src/mesa/pipe/draw/draw_context.c b/src/mesa/pipe/draw/draw_context.c
index 5b9ea55630..e8ca1f035b 100644
--- a/src/mesa/pipe/draw/draw_context.c
+++ b/src/mesa/pipe/draw/draw_context.c
@@ -77,15 +77,10 @@ struct draw_context *draw_create( void )
draw->vcache.vertex[i] = (struct vertex_header *)(tmp + i * MAX_VERTEX_SIZE);
}
- draw->attrib_front0 = 0;
- draw->attrib_back0 = 0;
- draw->attrib_front1 = 0;
- draw->attrib_back1 = 0;
-
draw->convert_wide_points = TRUE;
draw->convert_wide_lines = TRUE;
- draw->prim = ~0; /* != any of PIPE_PRIM_x */
+ draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */
draw_vertex_cache_invalidate( draw );
draw_set_mapped_element_buffer( draw, 0, NULL );
@@ -116,8 +111,7 @@ void draw_destroy( struct draw_context *draw )
void draw_flush( struct draw_context *draw )
{
- if (draw->drawing)
- draw_do_flush( draw, DRAW_FLUSH_DRAW );
+ draw_do_flush( draw, DRAW_FLUSH_BACKEND );
}
@@ -129,7 +123,8 @@ void draw_flush( struct draw_context *draw )
void draw_set_rasterizer_state( struct draw_context *draw,
const struct pipe_rasterizer_state *raster )
{
- draw_flush( draw );
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+
draw->rasterizer = raster;
}
@@ -142,7 +137,8 @@ void draw_set_rasterizer_state( struct draw_context *draw,
void draw_set_rasterize_stage( struct draw_context *draw,
struct draw_stage *stage )
{
- draw_flush( draw );
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+
draw->pipeline.rasterize = stage;
}
@@ -153,7 +149,7 @@ void draw_set_rasterize_stage( struct draw_context *draw,
void draw_set_clip_state( struct draw_context *draw,
const struct pipe_clip_state *clip )
{
- draw_flush( draw );
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
assert(clip->nr <= PIPE_MAX_CLIP_PLANES);
memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0]));
@@ -167,7 +163,7 @@ void draw_set_clip_state( struct draw_context *draw,
void draw_set_viewport_state( struct draw_context *draw,
const struct pipe_viewport_state *viewport )
{
- draw_flush( draw );
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
draw->viewport = *viewport; /* struct copy */
}
@@ -178,8 +174,7 @@ draw_set_vertex_buffer(struct draw_context *draw,
unsigned attr,
const struct pipe_vertex_buffer *buffer)
{
- draw_flush( draw );
-
+ draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ );
assert(attr < PIPE_ATTRIB_MAX);
draw->vertex_buffer[attr] = *buffer;
}
@@ -190,8 +185,7 @@ draw_set_vertex_element(struct draw_context *draw,
unsigned attr,
const struct pipe_vertex_element *element)
{
- draw_flush( draw );
-
+ draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ );
assert(attr < PIPE_ATTRIB_MAX);
draw->vertex_element[attr] = *element;
}
@@ -204,8 +198,7 @@ void
draw_set_mapped_vertex_buffer(struct draw_context *draw,
unsigned attr, const void *buffer)
{
- draw_flush( draw );
-
+ draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ );
draw->user.vbuffer[attr] = buffer;
}
@@ -214,8 +207,7 @@ void
draw_set_mapped_constant_buffer(struct draw_context *draw,
const void *buffer)
{
- draw_flush( draw );
-
+ draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ );
draw->user.constants = buffer;
}
@@ -227,6 +219,7 @@ draw_set_mapped_constant_buffer(struct draw_context *draw,
void
draw_convert_wide_points(struct draw_context *draw, boolean enable)
{
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
draw->convert_wide_points = enable;
}
@@ -238,11 +231,11 @@ draw_convert_wide_points(struct draw_context *draw, boolean enable)
void
draw_convert_wide_lines(struct draw_context *draw, boolean enable)
{
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
draw->convert_wide_lines = enable;
}
-
/**
* Allocate space for temporary post-transform vertices, such as for clipping.
*/
diff --git a/src/mesa/pipe/draw/draw_context.h b/src/mesa/pipe/draw/draw_context.h
index cfde26ceb7..ddeb184497 100644
--- a/src/mesa/pipe/draw/draw_context.h
+++ b/src/mesa/pipe/draw/draw_context.h
@@ -122,7 +122,6 @@ void draw_set_mapped_constant_buffer(struct draw_context *draw,
const void *buffer);
-
/***********************************************************************
* draw_prim.c
*/
diff --git a/src/mesa/pipe/draw/draw_cull.c b/src/mesa/pipe/draw/draw_cull.c
index 9bd53f45f2..05c274e4dc 100644
--- a/src/mesa/pipe/draw/draw_cull.c
+++ b/src/mesa/pipe/draw/draw_cull.c
@@ -50,14 +50,6 @@ static INLINE struct cull_stage *cull_stage( struct draw_stage *stage )
}
-static void cull_begin( struct draw_stage *stage )
-{
- struct cull_stage *cull = cull_stage(stage);
-
- cull->winding = stage->draw->rasterizer->cull_mode;
-
- stage->next->begin( stage->next );
-}
static void cull_tri( struct draw_stage *stage,
@@ -90,6 +82,18 @@ static void cull_tri( struct draw_stage *stage,
}
}
+static void cull_first_tri( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ struct cull_stage *cull = cull_stage(stage);
+
+ cull->winding = stage->draw->rasterizer->cull_mode;
+
+ stage->tri = cull_tri;
+ stage->tri( stage, header );
+}
+
+
static void cull_line( struct draw_stage *stage,
struct prim_header *header )
@@ -105,12 +109,12 @@ static void cull_point( struct draw_stage *stage,
}
-static void cull_end( struct draw_stage *stage )
+static void cull_flush( struct draw_stage *stage, unsigned flags )
{
- stage->next->end( stage->next );
+ stage->tri = cull_first_tri;
+ stage->next->flush( stage->next, flags );
}
-
static void cull_reset_stipple_counter( struct draw_stage *stage )
{
stage->next->reset_stipple_counter( stage->next );
@@ -135,11 +139,10 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw )
cull->stage.draw = draw;
cull->stage.next = NULL;
- cull->stage.begin = cull_begin;
cull->stage.point = cull_point;
cull->stage.line = cull_line;
- cull->stage.tri = cull_tri;
- cull->stage.end = cull_end;
+ cull->stage.tri = cull_first_tri;
+ cull->stage.flush = cull_flush;
cull->stage.reset_stipple_counter = cull_reset_stipple_counter;
cull->stage.destroy = cull_destroy;
diff --git a/src/mesa/pipe/draw/draw_flatshade.c b/src/mesa/pipe/draw/draw_flatshade.c
index d7551e7948..1419f287d2 100644
--- a/src/mesa/pipe/draw/draw_flatshade.c
+++ b/src/mesa/pipe/draw/draw_flatshade.c
@@ -29,42 +29,53 @@
*/
#include "pipe/p_util.h"
+#include "pipe/p_shader_tokens.h"
#include "draw_private.h"
-static void flatshade_begin( struct draw_stage *stage )
+/** subclass of draw_stage */
+struct flat_stage
{
- stage->next->begin( stage->next );
-}
+ struct draw_stage stage;
+ uint num_color_attribs;
+ uint color_attribs[4]; /* front/back primary/secondary colors */
+};
-static INLINE void copy_attr( unsigned attr,
- struct vertex_header *dst,
- const struct vertex_header *src )
+static INLINE struct flat_stage *
+flat_stage(struct draw_stage *stage)
{
- if (attr) {
- memcpy( dst->data[attr],
- src->data[attr],
- sizeof(src->data[0]) );
- }
+ return (struct flat_stage *) stage;
}
-static INLINE void copy_colors( struct draw_stage *stage,
- struct vertex_header *dst,
+/** Copy all the color attributes from 'src' vertex to 'dst' vertex */
+static INLINE void copy_colors( struct draw_stage *stage,
+ struct vertex_header *dst,
const struct vertex_header *src )
{
- const uint num_attribs = stage->draw->vertex_info.num_attribs;
- const enum interp_mode *interp = stage->draw->vertex_info.interp_mode;
+ const struct flat_stage *flat = flat_stage(stage);
uint i;
+ for (i = 0; i < flat->num_color_attribs; i++) {
+ const uint attr = flat->color_attribs[i];
+ COPY_4FV(dst->data[attr], src->data[attr]);
+ }
+}
- /* Look for constant/flat attribs and duplicate from src to dst vertex */
- /* skip attrib[0] which is vert pos */
- for (i = 1; i < num_attribs; i++) {
- if (interp[i] == INTERP_CONSTANT) {
- copy_attr( i, dst, src );
- }
+
+/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */
+static INLINE void copy_colors2( struct draw_stage *stage,
+ struct vertex_header *dst0,
+ struct vertex_header *dst1,
+ const struct vertex_header *src )
+{
+ const struct flat_stage *flat = flat_stage(stage);
+ uint i;
+ for (i = 0; i < flat->num_color_attribs; i++) {
+ const uint attr = flat->color_attribs[i];
+ COPY_4FV(dst0->data[attr], src->data[attr]);
+ COPY_4FV(dst1->data[attr], src->data[attr]);
}
}
@@ -84,8 +95,7 @@ static void flatshade_tri( struct draw_stage *stage,
tmp.v[1] = dup_vert(stage, header->v[1], 1);
tmp.v[2] = header->v[2];
- copy_colors(stage, tmp.v[0], tmp.v[2]);
- copy_colors(stage, tmp.v[1], tmp.v[2]);
+ copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]);
stage->next->tri( stage->next, &tmp );
}
@@ -115,9 +125,46 @@ static void flatshade_point( struct draw_stage *stage,
}
-static void flatshade_end( struct draw_stage *stage )
+static void flatshade_init_state( struct draw_stage *stage )
+{
+ struct flat_stage *flat = flat_stage(stage);
+ const struct pipe_shader_state *vs = stage->draw->vertex_shader->state;
+ uint i;
+
+ /* Find which vertex shader outputs are colors, make a list */
+ flat->num_color_attribs = 0;
+ for (i = 0; i < vs->num_outputs; i++) {
+ if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
+ vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
+ flat->color_attribs[flat->num_color_attribs++] = i;
+ }
+ }
+
+ stage->line = flatshade_line;
+ stage->tri = flatshade_tri;
+}
+
+static void flatshade_first_tri( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ flatshade_init_state( stage );
+ stage->tri( stage, header );
+}
+
+static void flatshade_first_line( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ flatshade_init_state( stage );
+ stage->line( stage, header );
+}
+
+
+static void flatshade_flush( struct draw_stage *stage,
+ unsigned flags )
{
- stage->next->end( stage->next );
+ stage->tri = flatshade_first_tri;
+ stage->line = flatshade_first_line;
+ stage->next->flush( stage->next, flags );
}
@@ -139,21 +186,20 @@ static void flatshade_destroy( struct draw_stage *stage )
*/
struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
{
- struct draw_stage *flatshade = CALLOC_STRUCT(draw_stage);
+ struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage);
- draw_alloc_tmps( flatshade, 2 );
+ draw_alloc_tmps( &flatshade->stage, 2 );
- flatshade->draw = draw;
- flatshade->next = NULL;
- flatshade->begin = flatshade_begin;
- flatshade->point = flatshade_point;
- flatshade->line = flatshade_line;
- flatshade->tri = flatshade_tri;
- flatshade->end = flatshade_end;
- flatshade->reset_stipple_counter = flatshade_reset_stipple_counter;
- flatshade->destroy = flatshade_destroy;
+ flatshade->stage.draw = draw;
+ flatshade->stage.next = NULL;
+ flatshade->stage.point = flatshade_point;
+ flatshade->stage.line = flatshade_first_line;
+ flatshade->stage.tri = flatshade_first_tri;
+ flatshade->stage.flush = flatshade_flush;
+ flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter;
+ flatshade->stage.destroy = flatshade_destroy;
- return flatshade;
+ return &flatshade->stage;
}
diff --git a/src/mesa/pipe/draw/draw_offset.c b/src/mesa/pipe/draw/draw_offset.c
index f8a01db3dd..a2990ee8a8 100644
--- a/src/mesa/pipe/draw/draw_offset.c
+++ b/src/mesa/pipe/draw/draw_offset.c
@@ -52,16 +52,7 @@ static INLINE struct offset_stage *offset_stage( struct draw_stage *stage )
}
-static void offset_begin( struct draw_stage *stage )
-{
- struct offset_stage *offset = offset_stage(stage);
- float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */
- offset->units = stage->draw->rasterizer->offset_units * mrd;
- offset->scale = stage->draw->rasterizer->offset_scale;
-
- stage->next->begin( stage->next );
-}
/**
@@ -124,24 +115,39 @@ static void offset_tri( struct draw_stage *stage,
}
+static void offset_first_tri( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ struct offset_stage *offset = offset_stage(stage);
+ float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */
+
+ offset->units = stage->draw->rasterizer->offset_units * mrd;
+ offset->scale = stage->draw->rasterizer->offset_scale;
+
+ stage->tri = offset_tri;
+ stage->tri( stage, header );
+}
+
static void offset_line( struct draw_stage *stage,
- struct prim_header *header )
+ struct prim_header *header )
{
stage->next->line( stage->next, header );
}
static void offset_point( struct draw_stage *stage,
- struct prim_header *header )
+ struct prim_header *header )
{
stage->next->point( stage->next, header );
}
-static void offset_end( struct draw_stage *stage )
+static void offset_flush( struct draw_stage *stage,
+ unsigned flags )
{
- stage->next->end( stage->next );
+ stage->tri = offset_first_tri;
+ stage->next->flush( stage->next, flags );
}
@@ -169,11 +175,10 @@ struct draw_stage *draw_offset_stage( struct draw_context *draw )
offset->stage.draw = draw;
offset->stage.next = NULL;
- offset->stage.begin = offset_begin;
offset->stage.point = offset_point;
offset->stage.line = offset_line;
- offset->stage.tri = offset_tri;
- offset->stage.end = offset_end;
+ offset->stage.tri = offset_first_tri;
+ offset->stage.flush = offset_flush;
offset->stage.reset_stipple_counter = offset_reset_stipple_counter;
offset->stage.destroy = offset_destroy;
diff --git a/src/mesa/pipe/draw/draw_prim.c b/src/mesa/pipe/draw/draw_prim.c
index f8fc23b510..243381aec0 100644
--- a/src/mesa/pipe/draw/draw_prim.c
+++ b/src/mesa/pipe/draw/draw_prim.c
@@ -57,39 +57,40 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
static void draw_prim_queue_flush( struct draw_context *draw )
{
- struct draw_stage *first = draw->pipeline.first;
unsigned i;
if (0)
fprintf(stdout,"Flushing with %d prims, %d verts\n",
draw->pq.queue_nr, draw->vs.queue_nr);
- /* Make sure all vertices are available/shaded:
- */
- if (draw->vs.queue_nr)
- draw_vertex_shader_queue_flush(draw);
+ if (draw->pq.queue_nr == 0)
+ return;
+ /* NOTE: we cannot save draw->pipeline->first in a local var because
+ * draw->pipeline->first is often changed by the first call to tri(),
+ * line(), etc.
+ */
switch (draw->reduced_prim) {
case RP_TRI:
for (i = 0; i < draw->pq.queue_nr; i++) {
if (draw->pq.queue[i].reset_line_stipple)
- first->reset_stipple_counter( first );
+ draw->pipeline.first->reset_stipple_counter( draw->pipeline.first );
- first->tri( first, &draw->pq.queue[i] );
+ draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] );
}
break;
case RP_LINE:
for (i = 0; i < draw->pq.queue_nr; i++) {
if (draw->pq.queue[i].reset_line_stipple)
- first->reset_stipple_counter( first );
+ draw->pipeline.first->reset_stipple_counter( draw->pipeline.first );
- first->line( first, &draw->pq.queue[i] );
+ draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] );
}
break;
case RP_POINT:
- first->reset_stipple_counter( first );
+ draw->pipeline.first->reset_stipple_counter( draw->pipeline.first );
for (i = 0; i < draw->pq.queue_nr; i++)
- first->point( first, &draw->pq.queue[i] );
+ draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] );
break;
}
@@ -98,33 +99,32 @@ static void draw_prim_queue_flush( struct draw_context *draw )
}
-void draw_do_flush( struct draw_context *draw,
- unsigned flush )
+
+void draw_do_flush( struct draw_context *draw, unsigned flags )
{
- if ((flush & (DRAW_FLUSH_PRIM_QUEUE |
- DRAW_FLUSH_VERTEX_CACHE_INVALIDATE |
- DRAW_FLUSH_DRAW)) &&
- draw->pq.queue_nr)
- {
- draw_prim_queue_flush(draw);
- }
+ if (0)
+ fprintf(stdout,"Flushing with %d verts, %d prims\n",
+ draw->vs.queue_nr,
+ draw->pq.queue_nr );
- if ((flush & (DRAW_FLUSH_VERTEX_CACHE_INVALIDATE |
- DRAW_FLUSH_DRAW)) &&
- draw->drawing)
- {
- draw_vertex_cache_invalidate(draw);
- }
- if ((flush & DRAW_FLUSH_DRAW) &&
- draw->drawing)
- {
- draw->pipeline.first->end( draw->pipeline.first );
- draw->drawing = FALSE;
- draw->prim = ~0;
- draw->pipeline.first = draw->pipeline.validate;
- }
+ if (flags >= DRAW_FLUSH_SHADER_QUEUE) {
+ draw_vertex_shader_queue_flush(draw);
+
+ if (flags >= DRAW_FLUSH_PRIM_QUEUE) {
+ draw_prim_queue_flush(draw);
+ if (flags >= DRAW_FLUSH_VERTEX_CACHE) {
+ draw_vertex_cache_invalidate(draw);
+
+ if (flags >= DRAW_FLUSH_STATE_CHANGE) {
+ draw->pipeline.first->flush( draw->pipeline.first, flags );
+ draw->pipeline.first = draw->pipeline.validate;
+ draw->reduced_prim = ~0;
+ }
+ }
+ }
+ }
}
@@ -139,7 +139,7 @@ static struct prim_header *get_queued_prim( struct draw_context *draw,
{
if (!draw_vertex_cache_check_space( draw, nr_verts )) {
// fprintf(stderr, "v");
- draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE_INVALIDATE );
+ draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE );
}
else if (draw->pq.queue_nr == PRIM_QUEUE_LENGTH) {
// fprintf(stderr, "p");
@@ -247,13 +247,14 @@ static void do_quad( struct draw_context *draw,
* Main entrypoint to draw some number of points/lines/triangles
*/
static void
-draw_prim( struct draw_context *draw, unsigned start, unsigned count )
+draw_prim( struct draw_context *draw,
+ unsigned prim, unsigned start, unsigned count )
{
unsigned i;
// _mesa_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count );
- switch (draw->prim) {
+ switch (prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i ++) {
do_point( draw,
@@ -385,21 +386,6 @@ draw_prim( struct draw_context *draw, unsigned start, unsigned count )
}
-static void
-draw_set_prim( struct draw_context *draw, unsigned prim )
-{
- assert(prim >= PIPE_PRIM_POINTS);
- assert(prim <= PIPE_PRIM_POLYGON);
-
- if (reduced_prim[prim] != draw->reduced_prim) {
- draw_do_flush( draw, DRAW_FLUSH_PRIM_QUEUE );
- draw->reduced_prim = reduced_prim[prim];
- }
-
- draw->prim = prim;
-}
-
-
/**
@@ -413,19 +399,13 @@ void
draw_arrays(struct draw_context *draw, unsigned prim,
unsigned start, unsigned count)
{
- if (!draw->drawing) {
- draw->drawing = TRUE;
-
- /* tell drawing pipeline we're beginning drawing */
- draw->pipeline.first->begin( draw->pipeline.first );
- }
-
- if (draw->prim != prim) {
- draw_set_prim( draw, prim );
+ if (reduced_prim[prim] != draw->reduced_prim) {
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+ draw->reduced_prim = reduced_prim[prim];
}
/* drawing done here: */
- draw_prim(draw, start, count);
+ draw_prim(draw, prim, start, count);
}
diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h
index a264fabfb4..1e59f5bd8d 100644
--- a/src/mesa/pipe/draw/draw_private.h
+++ b/src/mesa/pipe/draw/draw_private.h
@@ -44,8 +44,6 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
-#include "draw_vertex.h"
-
#include "x86/rtasm/x86sse.h"
#include "pipe/tgsi/exec/tgsi_exec.h"
@@ -103,8 +101,6 @@ struct draw_stage
struct vertex_header **tmp; /**< temp vert storage, such as for clipping */
unsigned nr_tmps;
- void (*begin)( struct draw_stage * );
-
void (*point)( struct draw_stage *,
struct prim_header * );
@@ -114,7 +110,8 @@ struct draw_stage
void (*tri)( struct draw_stage *,
struct prim_header * );
- void (*end)( struct draw_stage * );
+ void (*flush)( struct draw_stage *,
+ unsigned flags );
void (*reset_stipple_counter)( struct draw_stage * );
@@ -140,6 +137,13 @@ struct draw_vertex_shader {
#endif
};
+
+/* Internal function for vertex fetch.
+ */
+typedef void (*fetch_func)(const void *ptr, float *attrib);
+
+
+
/**
* Private context for the drawing module.
*/
@@ -170,6 +174,8 @@ struct draw_context
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
const struct draw_vertex_shader *vertex_shader;
+ uint num_vs_outputs; /**< convenience, from vertex_shader */
+
/* user-space vertex data, buffers */
struct {
/** vertex element/index buffer (ex: glDrawElements) */
@@ -189,22 +195,23 @@ struct draw_context
float plane[12][4];
unsigned nr_planes;
- /** Describes the layout of post-transformation vertices */
- struct vertex_info vertex_info;
- /** Two-sided attributes: */
- uint attrib_front0, attrib_back0;
- uint attrib_front1, attrib_back1;
-
boolean convert_wide_points; /**< convert wide points to tris? */
boolean convert_wide_lines; /**< convert side lines to tris? */
- boolean drawing; /**< do we presently have something queued for drawing? */
- unsigned prim; /**< current prim type: PIPE_PRIM_x */
unsigned reduced_prim;
/** TGSI program interpreter runtime state */
struct tgsi_exec_machine machine;
+ /* Vertex fetch internal state
+ */
+ struct {
+ const ubyte *src_ptr[PIPE_ATTRIB_MAX];
+ unsigned pitch[PIPE_ATTRIB_MAX];
+ fetch_func fetch[PIPE_ATTRIB_MAX];
+ unsigned nr_attrs;
+ } vertex_fetch;
+
/* Post-tnl vertex cache:
*/
struct {
@@ -279,20 +286,21 @@ extern void draw_vertex_shader_queue_flush_llvm( struct draw_context *draw );
struct tgsi_exec_machine;
+extern void draw_update_vertex_fetch( struct draw_context *draw );
extern void draw_vertex_fetch( struct draw_context *draw,
struct tgsi_exec_machine *machine,
const unsigned *elts,
unsigned count );
-#define DRAW_FLUSH_PRIM_QUEUE 0x1
-#define DRAW_FLUSH_VERTEX_CACHE_INVALIDATE 0x2
-#define DRAW_FLUSH_DRAW 0x4
-
+#define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */
+#define DRAW_FLUSH_PRIM_QUEUE 0x2
+#define DRAW_FLUSH_VERTEX_CACHE 0x4
+#define DRAW_FLUSH_STATE_CHANGE 0x8
+#define DRAW_FLUSH_BACKEND 0x10
-void draw_do_flush( struct draw_context *draw,
- unsigned flags );
+void draw_do_flush( struct draw_context *draw, unsigned flags );
@@ -309,7 +317,9 @@ dup_vert( struct draw_stage *stage,
unsigned idx )
{
struct vertex_header *tmp = stage->tmp[idx];
- memcpy(tmp, vert, stage->draw->vertex_info.size * sizeof(float) );
+ const uint vsize = sizeof(struct vertex_header)
+ + stage->draw->num_vs_outputs * 4 * sizeof(float);
+ memcpy(tmp, vert, vsize);
tmp->vertex_id = UNDEFINED_VERTEX_ID;
return tmp;
}
diff --git a/src/mesa/pipe/draw/draw_stipple.c b/src/mesa/pipe/draw/draw_stipple.c
index 3e0d5689e1..9029101916 100644
--- a/src/mesa/pipe/draw/draw_stipple.c
+++ b/src/mesa/pipe/draw/draw_stipple.c
@@ -61,6 +61,7 @@ stipple_stage(struct draw_stage *stage)
/**
* Compute interpolated vertex attributes for 'dst' at position 't'
* between 'v0' and 'v1'.
+ * XXX using linear interpolation for all attribs at this time.
*/
static void
screen_interp( struct draw_context *draw,
@@ -70,28 +71,13 @@ screen_interp( struct draw_context *draw,
const struct vertex_header *v1 )
{
uint attr;
- for (attr = 0; attr < draw->vertex_info.num_attribs; attr++) {
- switch (draw->vertex_info.interp_mode[attr]) {
- case INTERP_NONE:
- case INTERP_CONSTANT:
- COPY_4FV(dst->data[attr], v0->data[attr]);
- break;
- case INTERP_PERSPECTIVE:
- /* Fall-through */
- /* XXX special-case perspective? */
- case INTERP_LINEAR:
- {
- const float *val0 = v0->data[attr];
- const float *val1 = v1->data[attr];
- float *newv = dst->data[attr];
- uint i;
- for (i = 0; i < 4; i++) {
- newv[i] = val0[i] + t * (val1[i] - val0[i]);
- }
- }
- break;
- default:
- abort();
+ for (attr = 0; attr < draw->num_vs_outputs; attr++) {
+ const float *val0 = v0->data[attr];
+ const float *val1 = v1->data[attr];
+ float *newv = dst->data[attr];
+ uint i;
+ for (i = 0; i < 4; i++) {
+ newv[i] = val0[i] + t * (val1[i] - val0[i]);
}
}
}
@@ -187,7 +173,8 @@ reset_stipple_counter(struct draw_stage *stage)
static void
-stipple_begin(struct draw_stage *stage)
+stipple_first_line(struct draw_stage *stage,
+ struct prim_header *header)
{
struct stipple_stage *stipple = stipple_stage(stage);
struct draw_context *draw = stage->draw;
@@ -195,14 +182,16 @@ stipple_begin(struct draw_stage *stage)
stipple->pattern = draw->rasterizer->line_stipple_pattern;
stipple->factor = draw->rasterizer->line_stipple_factor + 1;
- stage->next->begin( stage->next );
+ stage->line = stipple_line;
+ stage->line( stage, header );
}
static void
-stipple_end(struct draw_stage *stage)
+stipple_flush(struct draw_stage *stage, unsigned flags)
{
- stage->next->end( stage->next );
+ stage->line = stipple_first_line;
+ stage->next->flush( stage->next, flags );
}
@@ -238,12 +227,11 @@ struct draw_stage *draw_stipple_stage( struct draw_context *draw )
stipple->stage.draw = draw;
stipple->stage.next = NULL;
- stipple->stage.begin = stipple_begin;
stipple->stage.point = passthrough_point;
- stipple->stage.line = stipple_line;
+ stipple->stage.line = stipple_first_line;
stipple->stage.tri = passthrough_tri;
stipple->stage.reset_stipple_counter = reset_stipple_counter;
- stipple->stage.end = stipple_end;
+ stipple->stage.flush = stipple_flush;
stipple->stage.destroy = stipple_destroy;
return &stipple->stage;
diff --git a/src/mesa/pipe/draw/draw_twoside.c b/src/mesa/pipe/draw/draw_twoside.c
index c7e268f11e..ad2aaf10bb 100644
--- a/src/mesa/pipe/draw/draw_twoside.c
+++ b/src/mesa/pipe/draw/draw_twoside.c
@@ -30,12 +30,15 @@
#include "pipe/p_util.h"
#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
#include "draw_private.h"
struct twoside_stage {
struct draw_stage stage;
float sign; /**< +1 or -1 */
+ uint attrib_front0, attrib_back0;
+ uint attrib_front1, attrib_back1;
};
@@ -45,44 +48,25 @@ static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage )
}
-static void twoside_begin( struct draw_stage *stage )
-{
- struct twoside_stage *twoside = twoside_stage(stage);
-
- /*
- * We'll multiply the primitive's determinant by this sign to determine
- * if the triangle is back-facing (negative).
- * sign = -1 for CCW, +1 for CW
- */
- twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f;
-
- stage->next->begin( stage->next );
-}
-
-
-static INLINE void copy_attrib( unsigned attr_dst,
- unsigned attr_src,
- struct vertex_header *v )
-{
- COPY_4FV(v->data[attr_dst], v->data[attr_src]);
-}
/**
* Copy back color(s) to front color(s).
*/
-static struct vertex_header *copy_bfc( struct twoside_stage *twoside,
- const struct vertex_header *v,
- unsigned idx )
+static INLINE struct vertex_header *
+copy_bfc( struct twoside_stage *twoside,
+ const struct vertex_header *v,
+ unsigned idx )
{
struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx );
- const struct draw_context *draw = twoside->stage.draw;
- if (draw->attrib_front0 && draw->attrib_back0) {
- copy_attrib(draw->attrib_front0, draw->attrib_back0, tmp);
+ if (twoside->attrib_back0) {
+ COPY_4FV(tmp->data[twoside->attrib_front0],
+ tmp->data[twoside->attrib_back0]);
}
- if (draw->attrib_front1 && draw->attrib_back1) {
- copy_attrib(draw->attrib_front1, draw->attrib_back1, tmp);
+ if (twoside->attrib_back1) {
+ COPY_4FV(tmp->data[twoside->attrib_front1],
+ tmp->data[twoside->attrib_back1]);
}
return tmp;
@@ -131,10 +115,56 @@ static void twoside_point( struct draw_stage *stage,
}
-static void twoside_end( struct draw_stage *stage )
+static void twoside_first_tri( struct draw_stage *stage,
+ struct prim_header *header )
{
- /* pass-through */
- stage->next->end( stage->next );
+ struct twoside_stage *twoside = twoside_stage(stage);
+ const struct pipe_shader_state *vs = stage->draw->vertex_shader->state;
+ uint i;
+
+ twoside->attrib_front0 = 0;
+ twoside->attrib_front1 = 0;
+ twoside->attrib_back0 = 0;
+ twoside->attrib_back1 = 0;
+
+ /* Find which vertex shader outputs are front/back colors */
+ for (i = 0; i < vs->num_outputs; i++) {
+ if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
+ if (vs->output_semantic_index[i] == 0)
+ twoside->attrib_front0 = i;
+ else
+ twoside->attrib_front1 = i;
+ }
+ if (vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
+ if (vs->output_semantic_index[i] == 0)
+ twoside->attrib_back0 = i;
+ else
+ twoside->attrib_back1 = i;
+ }
+ }
+
+ if (!twoside->attrib_back0)
+ twoside->attrib_front0 = 0;
+
+ if (!twoside->attrib_back1)
+ twoside->attrib_front1 = 0;
+
+ /*
+ * We'll multiply the primitive's determinant by this sign to determine
+ * if the triangle is back-facing (negative).
+ * sign = -1 for CCW, +1 for CW
+ */
+ twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f;
+
+ stage->tri = twoside_tri;
+ stage->tri( stage, header );
+}
+
+
+static void twoside_flush( struct draw_stage *stage, unsigned flags )
+{
+ stage->tri = twoside_first_tri;
+ stage->next->flush( stage->next, flags );
}
@@ -162,11 +192,10 @@ struct draw_stage *draw_twoside_stage( struct draw_context *draw )
twoside->stage.draw = draw;
twoside->stage.next = NULL;
- twoside->stage.begin = twoside_begin;
twoside->stage.point = twoside_point;
twoside->stage.line = twoside_line;
- twoside->stage.tri = twoside_tri;
- twoside->stage.end = twoside_end;
+ twoside->stage.tri = twoside_first_tri;
+ twoside->stage.flush = twoside_flush;
twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter;
twoside->stage.destroy = twoside_destroy;
diff --git a/src/mesa/pipe/draw/draw_unfilled.c b/src/mesa/pipe/draw/draw_unfilled.c
index 786826b33c..364bda8b79 100644
--- a/src/mesa/pipe/draw/draw_unfilled.c
+++ b/src/mesa/pipe/draw/draw_unfilled.c
@@ -55,15 +55,6 @@ static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage )
}
-static void unfilled_begin( struct draw_stage *stage )
-{
- struct unfilled_stage *unfilled = unfilled_stage(stage);
-
- unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */
- unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */
-
- stage->next->begin( stage->next );
-}
static void point( struct draw_stage *stage,
struct vertex_header *v0 )
@@ -142,6 +133,20 @@ static void unfilled_tri( struct draw_stage *stage,
}
}
+
+static void unfilled_first_tri( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ struct unfilled_stage *unfilled = unfilled_stage(stage);
+
+ unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */
+ unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */
+
+ stage->tri = unfilled_tri;
+ stage->tri( stage, header );
+}
+
+
static void unfilled_line( struct draw_stage *stage,
struct prim_header *header )
{
@@ -156,9 +161,10 @@ static void unfilled_point( struct draw_stage *stage,
}
-static void unfilled_end( struct draw_stage *stage )
+static void unfilled_flush( struct draw_stage *stage,
+ unsigned flags )
{
- stage->next->end( stage->next );
+ stage->next->flush( stage->next, flags );
}
@@ -187,11 +193,10 @@ struct draw_stage *draw_unfilled_stage( struct draw_context *draw )
unfilled->stage.draw = draw;
unfilled->stage.next = NULL;
unfilled->stage.tmp = NULL;
- unfilled->stage.begin = unfilled_begin;
unfilled->stage.point = unfilled_point;
unfilled->stage.line = unfilled_line;
- unfilled->stage.tri = unfilled_tri;
- unfilled->stage.end = unfilled_end;
+ unfilled->stage.tri = unfilled_first_tri;
+ unfilled->stage.flush = unfilled_flush;
unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter;
unfilled->stage.destroy = unfilled_destroy;
diff --git a/src/mesa/pipe/draw/draw_validate.c b/src/mesa/pipe/draw/draw_validate.c
index 3b1f5179a9..86d5a5f814 100644
--- a/src/mesa/pipe/draw/draw_validate.c
+++ b/src/mesa/pipe/draw/draw_validate.c
@@ -39,10 +39,17 @@
/**
* Rebuild the rendering pipeline.
*/
-static void validate_begin( struct draw_stage *stage )
+static struct draw_stage *validate_pipeline( struct draw_stage *stage )
{
struct draw_context *draw = stage->draw;
struct draw_stage *next = draw->pipeline.rasterize;
+ int need_det = 0;
+ int precalc_flat = 0;
+
+ /* Set the validate's next stage to the rasterize stage, so that it
+ * can be found later if needed for flushing.
+ */
+ stage->next = next;
/*
* NOTE: we build up the pipeline in end-to-start order.
@@ -61,29 +68,38 @@ static void validate_begin( struct draw_stage *stage )
if (draw->rasterizer->line_stipple_enable) {
draw->pipeline.stipple->next = next;
next = draw->pipeline.stipple;
+ precalc_flat = 1; /* only needed for lines really */
}
if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) {
draw->pipeline.unfilled->next = next;
next = draw->pipeline.unfilled;
+ precalc_flat = 1; /* only needed for triangles really */
+ need_det = 1;
}
if (draw->rasterizer->offset_cw ||
draw->rasterizer->offset_ccw) {
draw->pipeline.offset->next = next;
next = draw->pipeline.offset;
+ need_det = 1;
}
if (draw->rasterizer->light_twoside) {
draw->pipeline.twoside->next = next;
next = draw->pipeline.twoside;
+ need_det = 1;
}
/* Always run the cull stage as we calculate determinant there
- * also. Fix this..
+ * also.
+ *
+ * This can actually be a win as culling out the triangles can lead
+ * to less work emitting vertices, smaller vertex buffers, etc.
+ * It's difficult to say whether this will be true in general.
*/
- {
+ if (need_det || draw->rasterizer->cull_mode) {
draw->pipeline.cull->next = next;
next = draw->pipeline.cull;
}
@@ -94,19 +110,52 @@ static void validate_begin( struct draw_stage *stage )
{
draw->pipeline.clip->next = next;
next = draw->pipeline.clip;
+ precalc_flat = 1; /* XXX: FIX ME! Only needed for clipped prims */
}
- /* Do software flatshading prior to clipping. XXX: should only do
- * this for clipped primitives, ie it is a part of the clip
- * routine.
- */
- if (draw->rasterizer->flatshade) {
+ if (draw->rasterizer->flatshade && precalc_flat) {
draw->pipeline.flatshade->next = next;
next = draw->pipeline.flatshade;
}
-
+
draw->pipeline.first = next;
- draw->pipeline.first->begin( draw->pipeline.first );
+ return next;
+}
+
+static void validate_tri( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ struct draw_stage *pipeline = validate_pipeline( stage );
+ pipeline->tri( pipeline, header );
+}
+
+static void validate_line( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ struct draw_stage *pipeline = validate_pipeline( stage );
+ pipeline->line( pipeline, header );
+}
+
+static void validate_point( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ struct draw_stage *pipeline = validate_pipeline( stage );
+ pipeline->point( pipeline, header );
+}
+
+static void validate_reset_stipple_counter( struct draw_stage *stage )
+{
+ struct draw_stage *pipeline = validate_pipeline( stage );
+ pipeline->reset_stipple_counter( pipeline );
+}
+
+static void validate_flush( struct draw_stage *stage,
+ unsigned flags )
+{
+ /* May need to pass a backend flush on to the rasterize stage.
+ */
+ if (stage->next)
+ stage->next->flush( stage->next, flags );
}
@@ -125,12 +174,11 @@ struct draw_stage *draw_validate_stage( struct draw_context *draw )
stage->draw = draw;
stage->next = NULL;
- stage->begin = validate_begin;
- stage->point = NULL;
- stage->line = NULL;
- stage->tri = NULL;
- stage->end = NULL;
- stage->reset_stipple_counter = NULL;
+ stage->point = validate_point;
+ stage->line = validate_line;
+ stage->tri = validate_tri;
+ stage->flush = validate_flush;
+ stage->reset_stipple_counter = validate_reset_stipple_counter;
stage->destroy = validate_destroy;
return stage;
diff --git a/src/mesa/pipe/draw/draw_vbuf.c b/src/mesa/pipe/draw/draw_vbuf.c
index a4b6247e18..cd0b4fbbb9 100644
--- a/src/mesa/pipe/draw/draw_vbuf.c
+++ b/src/mesa/pipe/draw/draw_vbuf.c
@@ -141,37 +141,43 @@ emit_vertex( struct vbuf_stage *vbuf,
for (i = 0; i < vinfo->num_attribs; i++) {
uint j = vinfo->src_index[i];
- switch (vinfo->format[i]) {
- case FORMAT_OMIT:
+ switch (vinfo->emit[i]) {
+ case EMIT_OMIT:
/* no-op */
break;
- case FORMAT_1F:
+ case EMIT_ALL:
+ /* just copy the whole vertex as-is to the vbuf */
+ assert(i == 0);
+ memcpy(vbuf->vertex_ptr, vertex, vinfo->size * 4);
+ vbuf->vertex_ptr += vinfo->size;
+ return;
+ case EMIT_1F:
*vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
count++;
break;
- case FORMAT_1F_PSIZE:
+ case EMIT_1F_PSIZE:
*vbuf->vertex_ptr++ = fui(vbuf->stage.draw->rasterizer->point_size);
count++;
break;
- case FORMAT_2F:
+ case EMIT_2F:
*vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
*vbuf->vertex_ptr++ = fui(vertex->data[j][1]);
count += 2;
break;
- case FORMAT_3F:
+ case EMIT_3F:
*vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
*vbuf->vertex_ptr++ = fui(vertex->data[j][1]);
*vbuf->vertex_ptr++ = fui(vertex->data[j][2]);
count += 3;
break;
- case FORMAT_4F:
+ case EMIT_4F:
*vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
*vbuf->vertex_ptr++ = fui(vertex->data[j][1]);
*vbuf->vertex_ptr++ = fui(vertex->data[j][2]);
*vbuf->vertex_ptr++ = fui(vertex->data[j][3]);
count += 4;
break;
- case FORMAT_4UB:
+ case EMIT_4UB:
*vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[j][2] ),
float_to_ubyte( vertex->data[j][1] ),
float_to_ubyte( vertex->data[j][0] ),
@@ -381,29 +387,26 @@ vbuf_alloc_vertices( struct draw_stage *stage,
}
-static void
-vbuf_begin( struct draw_stage *stage )
-{
- /* no-op, vbuffer allocated by first point/line/tri */
-}
-
static void
-vbuf_end( struct draw_stage *stage )
+vbuf_flush( struct draw_stage *stage, unsigned flags )
{
-// vbuf_flush_indices( stage );
- /* XXX: Overkill */
- vbuf_flush_vertices( stage );
-
+ vbuf_flush_indices( stage );
+
stage->point = vbuf_first_point;
stage->line = vbuf_first_line;
stage->tri = vbuf_first_tri;
+
+ if (flags & DRAW_FLUSH_BACKEND)
+ vbuf_flush_vertices( stage );
}
static void
vbuf_reset_stipple_counter( struct draw_stage *stage )
{
+ /* XXX: Need to do something here for hardware with linestipple.
+ */
(void) stage;
}
@@ -426,11 +429,10 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw,
struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage);
vbuf->stage.draw = draw;
- vbuf->stage.begin = vbuf_begin;
vbuf->stage.point = vbuf_first_point;
vbuf->stage.line = vbuf_first_line;
vbuf->stage.tri = vbuf_first_tri;
- vbuf->stage.end = vbuf_end;
+ vbuf->stage.flush = vbuf_flush;
vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter;
vbuf->stage.destroy = vbuf_destroy;
diff --git a/src/mesa/pipe/draw/draw_vertex.c b/src/mesa/pipe/draw/draw_vertex.c
index 6191fcedbf..2d6592150f 100644
--- a/src/mesa/pipe/draw/draw_vertex.c
+++ b/src/mesa/pipe/draw/draw_vertex.c
@@ -38,17 +38,6 @@
#include "pipe/draw/draw_vertex.h"
-static INLINE void
-emit_vertex_attr(struct vertex_info *vinfo,
- enum attrib_format format, enum interp_mode interp)
-{
- const uint n = vinfo->num_attribs;
- vinfo->interp_mode[n] = interp;
- vinfo->format[n] = format;
- vinfo->num_attribs++;
-}
-
-
/**
* Compute the size of a vertex, in dwords/floats, to update the
* vinfo->size field.
@@ -60,25 +49,27 @@ draw_compute_vertex_size(struct vertex_info *vinfo)
vinfo->size = 0;
for (i = 0; i < vinfo->num_attribs; i++) {
- switch (vinfo->format[i]) {
- case FORMAT_OMIT:
+ switch (vinfo->emit[i]) {
+ case EMIT_OMIT:
break;
- case FORMAT_4UB:
+ case EMIT_4UB:
/* fall-through */
- case FORMAT_1F_PSIZE:
+ case EMIT_1F_PSIZE:
/* fall-through */
- case FORMAT_1F:
+ case EMIT_1F:
vinfo->size += 1;
break;
- case FORMAT_2F:
+ case EMIT_2F:
vinfo->size += 2;
break;
- case FORMAT_3F:
+ case EMIT_3F:
vinfo->size += 3;
break;
- case FORMAT_4F:
+ case EMIT_4F:
vinfo->size += 4;
break;
+ case EMIT_ALL:
+ /* fall-through */
default:
assert(0);
}
@@ -86,62 +77,3 @@ draw_compute_vertex_size(struct vertex_info *vinfo)
assert(vinfo->size * 4 <= MAX_VERTEX_SIZE);
}
-
-
-/**
- * Tell the drawing module about the contents of post-transformation vertices.
- * Note that the vertex attribute format info isn't used by 'draw'; all
- * attributes are handled as float[4]. But when the driver emits vertices
- * it'll use that info.
- * We _do_ care about the number of attributes and their interpolation modes.
- */
-void
-draw_set_vertex_info( struct draw_context *draw,
- const struct vertex_info *info)
-{
- assert(info->interp_mode[0] == INTERP_LINEAR); /* should be vert pos */
- assert(info->num_attribs <= PIPE_MAX_SHADER_OUTPUTS);
-
- memcpy(&draw->vertex_info, info, sizeof(*info));
-
- /* Need to know vertex size (in words) for vertex copying elsewhere.
- * Four words per attribute, plus vertex header (uint) and clip
- * position (float[4]).
- */
- draw->vertex_info.size = draw->vertex_info.num_attribs * 4 + 5;
-}
-
-
-/**
- * This function is used to tell the draw module about attributes
- * (like colors) that need to be selected based on front/back face
- * orientation.
- *
- * The logic is:
- * if (polygon is back-facing) {
- * vertex->attrib[front0] = vertex->attrib[back0];
- * vertex->attrib[front1] = vertex->attrib[back1];
- * }
- *
- * \param front0 first attrib to replace if the polygon is back-facing
- * \param back0 first attrib to copy if the polygon is back-facing
- * \param front1 second attrib to replace if the polygon is back-facing
- * \param back1 second attrib to copy if the polygon is back-facing
- *
- * Pass -1 to disable two-sided attributes.
- */
-void
-draw_set_twoside_attributes(struct draw_context *draw,
- uint front0, uint back0,
- uint front1, uint back1)
-{
- /* XXX we could alternately pass an array of front/back attribs if there's
- * ever need for more than two. One could imagine a shader extension
- * that allows arbitrary attributes to be selected based on polygon
- * orientation...
- */
- draw->attrib_front0 = front0;
- draw->attrib_back0 = back0;
- draw->attrib_front1 = front1;
- draw->attrib_back1 = back1;
-}
diff --git a/src/mesa/pipe/draw/draw_vertex.h b/src/mesa/pipe/draw/draw_vertex.h
index e4f85bc49f..dfc637b19b 100644
--- a/src/mesa/pipe/draw/draw_vertex.h
+++ b/src/mesa/pipe/draw/draw_vertex.h
@@ -34,20 +34,21 @@
#define DRAW_VERTEX_H
-struct draw_context;
+#include "pipe/p_state.h"
/**
- * Vertex attribute format
+ * Vertex attribute emit modes
*/
-enum attrib_format {
- FORMAT_OMIT, /**< don't emit the attribute */
- FORMAT_1F,
- FORMAT_1F_PSIZE, /**< insert constant point size */
- FORMAT_2F,
- FORMAT_3F,
- FORMAT_4F,
- FORMAT_4UB /**< XXX may need variations for RGBA vs BGRA, etc */
+enum attrib_emit {
+ EMIT_OMIT, /**< don't emit the attribute */
+ EMIT_ALL, /**< emit whole post-xform vertex, w/ header */
+ EMIT_1F,
+ EMIT_1F_PSIZE, /**< insert constant point size */
+ EMIT_2F,
+ EMIT_3F,
+ EMIT_4F,
+ EMIT_4UB /**< XXX may need variations for RGBA vs BGRA, etc */
};
@@ -56,6 +57,7 @@ enum attrib_format {
*/
enum interp_mode {
INTERP_NONE, /**< never interpolate vertex header info */
+ INTERP_POS, /**< special case for frag position */
INTERP_CONSTANT,
INTERP_LINEAR,
INTERP_PERSPECTIVE
@@ -63,15 +65,15 @@ enum interp_mode {
/**
- * Information about post-transformed vertex layout.
+ * Information about hardware/rasterization vertex layout.
*/
struct vertex_info
{
uint num_attribs;
uint hwfmt[4]; /**< hardware format info for this format */
- enum interp_mode interp_mode[PIPE_MAX_SHADER_OUTPUTS];
- enum attrib_format format[PIPE_MAX_SHADER_OUTPUTS]; /**< FORMAT_x */
- uint src_index[PIPE_MAX_SHADER_OUTPUTS];
+ enum interp_mode interp_mode[PIPE_MAX_SHADER_INPUTS];
+ enum attrib_emit emit[PIPE_MAX_SHADER_INPUTS]; /**< EMIT_x */
+ uint src_index[PIPE_MAX_SHADER_INPUTS]; /**< map to post-xform attribs */
uint size; /**< total vertex size in dwords */
};
@@ -85,12 +87,12 @@ struct vertex_info
*/
static INLINE uint
draw_emit_vertex_attr(struct vertex_info *vinfo,
- enum attrib_format format, enum interp_mode interp,
+ enum attrib_emit emit, enum interp_mode interp,
uint src_index)
{
const uint n = vinfo->num_attribs;
- assert(n < PIPE_MAX_SHADER_OUTPUTS);
- vinfo->format[n] = format;
+ assert(n < PIPE_MAX_SHADER_INPUTS);
+ vinfo->emit[n] = emit;
vinfo->interp_mode[n] = interp;
vinfo->src_index[n] = src_index;
vinfo->num_attribs++;
@@ -98,13 +100,6 @@ draw_emit_vertex_attr(struct vertex_info *vinfo,
}
-extern void draw_set_vertex_info( struct draw_context *draw,
- const struct vertex_info *info);
-
-extern void draw_set_twoside_attributes(struct draw_context *draw,
- uint front0, uint back0,
- uint front1, uint back1);
-
extern void draw_compute_vertex_size(struct vertex_info *vinfo);
diff --git a/src/mesa/pipe/draw/draw_vertex_cache.c b/src/mesa/pipe/draw/draw_vertex_cache.c
index 29993f14d2..44427999cc 100644
--- a/src/mesa/pipe/draw/draw_vertex_cache.c
+++ b/src/mesa/pipe/draw/draw_vertex_cache.c
@@ -33,21 +33,15 @@
#include "pipe/p_util.h"
#include "draw_private.h"
#include "draw_context.h"
-#include "draw_vertex.h"
void draw_vertex_cache_invalidate( struct draw_context *draw )
{
- unsigned i;
-
assert(draw->pq.queue_nr == 0);
assert(draw->vs.queue_nr == 0);
assert(draw->vcache.referenced == 0);
-
- for (i = 0; i < Elements( draw->vcache.idx ); i++)
- draw->vcache.idx[i] = ~0;
-// fprintf(stderr, "x\n");
+ memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx));
}
@@ -149,7 +143,7 @@ void draw_vertex_cache_unreference( struct draw_context *draw )
int draw_vertex_cache_check_space( struct draw_context *draw,
- unsigned nr_verts )
+ unsigned nr_verts )
{
if (draw->vcache.overflow + nr_verts < VCACHE_OVERFLOW) {
/* The vs queue is sized so that this can never happen:
diff --git a/src/mesa/pipe/draw/draw_vertex_fetch.c b/src/mesa/pipe/draw/draw_vertex_fetch.c
index 3ca17f8829..fb64723a19 100644
--- a/src/mesa/pipe/draw/draw_vertex_fetch.c
+++ b/src/mesa/pipe/draw/draw_vertex_fetch.c
@@ -34,7 +34,6 @@
#include "pipe/p_shader_tokens.h"
#include "draw_private.h"
#include "draw_context.h"
-#include "draw_vertex.h"
#define DRAW_DBG 0
@@ -43,53 +42,114 @@
/**
* Fetch a float[4] vertex attribute from memory, doing format/type
* conversion as needed.
- * XXX this might be a temporary thing.
+ *
+ * This is probably needed/dupliocated elsewhere, eg format
+ * conversion, texture sampling etc.
*/
-static void
-fetch_attrib4(const void *ptr, enum pipe_format format, float attrib[4])
+#define FETCH_ATTRIB( NAME, SZ, CVT ) \
+static void \
+fetch_##NAME(const void *ptr, float *attrib) \
+{ \
+ static const float defaults[4] = { 0,0,0,1 }; \
+ int i; \
+ \
+ for (i = 0; i < SZ; i++) { \
+ attrib[i] = CVT; \
+ } \
+ \
+ for (; i < 4; i++) { \
+ attrib[i] = defaults[i]; \
+ } \
+}
+
+#define CVT_32_FLOAT ((float *) ptr)[i]
+#define CVT_32_SSCALED (float) ((int *) ptr)[i]
+#define CVT_8_UNORM (float) ((unsigned char *) ptr)[i] / 255.0f
+
+FETCH_ATTRIB( R32G32B32A32_FLOAT, 4, CVT_32_FLOAT )
+FETCH_ATTRIB( R32G32B32_FLOAT, 3, CVT_32_FLOAT )
+FETCH_ATTRIB( R32G32_FLOAT, 2, CVT_32_FLOAT )
+FETCH_ATTRIB( R32_FLOAT, 1, CVT_32_FLOAT )
+FETCH_ATTRIB( R32G32B32A32_SSCALED, 4, CVT_32_SSCALED )
+FETCH_ATTRIB( R32G32B32_SSCALED, 3, CVT_32_SSCALED )
+FETCH_ATTRIB( R32G32_SSCALED, 2, CVT_32_SSCALED )
+FETCH_ATTRIB( R32_SSCALED, 1, CVT_32_SSCALED )
+FETCH_ATTRIB( A8R8G8B8_UNORM, 4, CVT_8_UNORM )
+FETCH_ATTRIB( R8G8B8A8_UNORM, 4, CVT_8_UNORM )
+
+
+
+static fetch_func get_fetch_func( enum pipe_format format )
{
- /* defaults */
- attrib[1] = 0.0;
- attrib[2] = 0.0;
- attrib[3] = 1.0;
switch (format) {
case PIPE_FORMAT_R32G32B32A32_FLOAT:
- attrib[3] = ((float *) ptr)[3];
- /* fall-through */
+ return fetch_R32G32B32A32_FLOAT;
case PIPE_FORMAT_R32G32B32_FLOAT:
- attrib[2] = ((float *) ptr)[2];
- /* fall-through */
+ return fetch_R32G32B32_FLOAT;
case PIPE_FORMAT_R32G32_FLOAT:
- attrib[1] = ((float *) ptr)[1];
- /* fall-through */
+ return fetch_R32G32_FLOAT;
case PIPE_FORMAT_R32_FLOAT:
- attrib[0] = ((float *) ptr)[0];
- break;
-
+ return fetch_R32_FLOAT;
case PIPE_FORMAT_R32G32B32A32_SSCALED:
- attrib[3] = (float) ((int *) ptr)[3];
- /* fall-through */
+ return fetch_R32G32B32A32_SSCALED;
case PIPE_FORMAT_R32G32B32_SSCALED:
- attrib[2] = (float) ((int *) ptr)[2];
- /* fall-through */
+ return fetch_R32G32B32_SSCALED;
case PIPE_FORMAT_R32G32_SSCALED:
- attrib[1] = (float) ((int *) ptr)[1];
- /* fall-through */
+ return fetch_R32G32_SSCALED;
case PIPE_FORMAT_R32_SSCALED:
- attrib[0] = (float) ((int *) ptr)[0];
- break;
-
+ return fetch_R32_SSCALED;
case PIPE_FORMAT_A8R8G8B8_UNORM:
+ return fetch_A8R8G8B8_UNORM;
case PIPE_FORMAT_R8G8B8A8_UNORM:
- attrib[0] = (float) ((unsigned char *) ptr)[2] / 255.0f;
- attrib[1] = (float) ((unsigned char *) ptr)[1] / 255.0f;
- attrib[2] = (float) ((unsigned char *) ptr)[0] / 255.0f;
- attrib[3] = (float) ((unsigned char *) ptr)[3] / 255.0f;
- break;
-
+ return fetch_R8G8B8A8_UNORM;
+ case 0:
+ return NULL;
default:
+ /* Lots of missing cases! */
assert(0);
+ return NULL;
+ }
+}
+
+
+static void
+transpose_4x4( float *out, const float *in )
+{
+ /* This can be achieved in 12 sse instructions, plus the final
+ * stores I guess. This is probably a bit more than that - maybe
+ * 32 or so?
+ */
+ out[0] = in[0]; out[1] = in[4]; out[2] = in[8]; out[3] = in[12];
+ out[4] = in[1]; out[5] = in[5]; out[6] = in[9]; out[7] = in[13];
+ out[8] = in[2]; out[9] = in[6]; out[10] = in[10]; out[11] = in[14];
+ out[12] = in[3]; out[13] = in[7]; out[14] = in[11]; out[15] = in[15];
+}
+
+
+
+void draw_update_vertex_fetch( struct draw_context *draw )
+{
+ unsigned nr_attrs, i;
+
+ /* this may happend during context init */
+ if (!draw->vertex_shader)
+ return;
+
+ nr_attrs = draw->vertex_shader->state->num_inputs;
+
+ for (i = 0; i < nr_attrs; i++) {
+ unsigned buf = draw->vertex_element[i].vertex_buffer_index;
+ enum pipe_format format = draw->vertex_element[i].src_format;
+
+ draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] +
+ draw->vertex_buffer[buf].buffer_offset +
+ draw->vertex_element[i].src_offset;
+
+ draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch;
+ draw->vertex_fetch.fetch[i] = get_fetch_func( format );
}
+
+ draw->vertex_fetch.nr_attrs = nr_attrs;
}
@@ -101,40 +161,48 @@ void draw_vertex_fetch( struct draw_context *draw,
const unsigned *elts,
unsigned count )
{
- unsigned j;
-
- /* loop over vertices */
- for (j = 0; j < count; j++) {
- uint attr;
-
-#if DRAW_DBG
- printf("fetch vertex %u: \n", j);
-#endif
-
- /* loop over vertex attributes (vertex shader inputs) */
- for (attr = 0; attr < draw->vertex_shader->state->num_inputs; attr++) {
-
- unsigned buf = draw->vertex_element[attr].vertex_buffer_index;
- const void *src
- = (const void *) ((const ubyte *) draw->user.vbuffer[buf]
- + draw->vertex_buffer[buf].buffer_offset
- + draw->vertex_element[attr].src_offset
- + elts[j] * draw->vertex_buffer[buf].pitch);
- float p[4];
-
- fetch_attrib4(src, draw->vertex_element[attr].src_format, p);
-
-#if DRAW_DBG
- printf(" %u: %f %f %f %f\n", attr, p[0], p[1], p[2], p[3]);
-#endif
-
- /* Transform to AoS xxxx/yyyy/zzzz/wwww representation:
- */
- machine->Inputs[attr].xyzw[0].f[j] = p[0]; /*X*/
- machine->Inputs[attr].xyzw[1].f[j] = p[1]; /*Y*/
- machine->Inputs[attr].xyzw[2].f[j] = p[2]; /*Z*/
- machine->Inputs[attr].xyzw[3].f[j] = p[3]; /*W*/
- }
+ unsigned nr_attrs = draw->vertex_fetch.nr_attrs;
+ unsigned attr;
+
+ assert(count <= 4);
+
+// _mesa_printf("%s %d\n", __FUNCTION__, count);
+
+ /* loop over vertex attributes (vertex shader inputs)
+ */
+ for (attr = 0; attr < nr_attrs; attr++) {
+
+ const unsigned pitch = draw->vertex_fetch.pitch[attr];
+ const ubyte *src = draw->vertex_fetch.src_ptr[attr];
+ const fetch_func fetch = draw->vertex_fetch.fetch[attr];
+ unsigned i;
+ float p[4][4];
+
+
+ /* Fetch four attributes for four vertices.
+ *
+ * Could fetch directly into AOS format, but this is meant to be
+ * a prototype for an sse implementation, which would have
+ * difficulties doing that.
+ */
+ for (i = 0; i < count; i++)
+ fetch( src + elts[i] * pitch, p[i] );
+
+ /* Be nice and zero out any missing vertices:
+ */
+ for ( ; i < 4; i++)
+ p[i][0] = p[i][1] = p[i][2] = p[i][3] = 0;
+
+ /* Transpose/swizzle into sse-friendly format. Currently
+ * assuming that all vertex shader inputs are float[4], but this
+ * isn't true -- if the vertex shader only wants tex0.xy, we
+ * could optimize for that.
+ *
+ * To do so fully without codegen would probably require an
+ * excessive number of fetch functions, but we could at least
+ * minimize the transpose step:
+ */
+ transpose_4x4( (float *)&machine->Inputs[attr].xyzw[0].f[0], (float *)p );
}
}
diff --git a/src/mesa/pipe/draw/draw_vertex_shader.c b/src/mesa/pipe/draw/draw_vertex_shader.c
index c2e038453e..3041974b9a 100644
--- a/src/mesa/pipe/draw/draw_vertex_shader.c
+++ b/src/mesa/pipe/draw/draw_vertex_shader.c
@@ -38,7 +38,6 @@
#endif
#include "draw_private.h"
#include "draw_context.h"
-#include "draw_vertex.h"
#include "x86/rtasm/x86sse.h"
#include "pipe/llvm/gallivm.h"
@@ -176,7 +175,7 @@ run_vertex_program(struct draw_context *draw,
/* Remaining attributes are packed into sequential post-transform
* vertex attrib slots.
*/
- for (slot = 1; slot < draw->vertex_info.num_attribs; slot++) {
+ for (slot = 1; slot < draw->num_vs_outputs; slot++) {
vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j];
vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j];
vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j];
@@ -202,6 +201,10 @@ draw_vertex_shader_queue_flush(struct draw_context *draw)
{
unsigned i, j;
+ /* XXX: do this on statechange:
+ */
+ draw_update_vertex_fetch( draw );
+
// fprintf(stderr, " q(%d) ", draw->vs.queue_nr );
#ifdef MESA_LLVM
if (draw->vertex_shader->llvm_prog) {
@@ -272,8 +275,10 @@ void
draw_bind_vertex_shader(struct draw_context *draw,
struct draw_vertex_shader *dvs)
{
- draw_flush(draw);
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+
draw->vertex_shader = dvs;
+ draw->num_vs_outputs = dvs->state->num_outputs;
/* specify the fragment program to interpret/execute */
tgsi_exec_machine_init(&draw->machine,
diff --git a/src/mesa/pipe/draw/draw_vertex_shader_llvm.c b/src/mesa/pipe/draw/draw_vertex_shader_llvm.c
index acd61163fa..4228c4f388 100644
--- a/src/mesa/pipe/draw/draw_vertex_shader_llvm.c
+++ b/src/mesa/pipe/draw/draw_vertex_shader_llvm.c
@@ -33,7 +33,6 @@
#include "pipe/p_util.h"
#include "draw_private.h"
#include "draw_context.h"
-#include "draw_vertex.h"
#ifdef MESA_LLVM
@@ -132,7 +131,7 @@ void draw_vertex_shader_queue_flush_llvm(struct draw_context *draw)
gallivm_prog_exec(prog, inputs, outputs, consts,
draw->vs.queue_nr,
draw->vertex_shader->state->num_inputs,
- draw->vertex_info.num_attribs - 2);
+ draw->vertex_shader->state->num_outputs);
/* store machine results */
@@ -173,7 +172,7 @@ void draw_vertex_shader_queue_flush_llvm(struct draw_context *draw)
/* Remaining attributes are packed into sequential post-transform
* vertex attrib slots.
*/
- for (slot = 1; slot < draw->vertex_info.num_attribs; slot++) {
+ for (slot = 1; slot < draw->num_vs_outputs; slot++) {
vOut->data[slot][0] = dests[slot][0];
vOut->data[slot][1] = dests[slot][1];
vOut->data[slot][2] = dests[slot][2];
diff --git a/src/mesa/pipe/draw/draw_wide_prims.c b/src/mesa/pipe/draw/draw_wide_prims.c
index a56c9b8893..9759e7e2e8 100644
--- a/src/mesa/pipe/draw/draw_wide_prims.c
+++ b/src/mesa/pipe/draw/draw_wide_prims.c
@@ -217,7 +217,7 @@ static void wide_point( struct draw_stage *stage,
/* point size is either per-vertex or fixed size */
if (wide->psize_slot >= 0) {
- half_size = header->v[0]->data[wide->psize_slot][0];
+ half_size = 0.5f * header->v[0]->data[wide->psize_slot][0];
}
else {
half_size = wide->half_point_size;
@@ -262,26 +262,19 @@ static void wide_point( struct draw_stage *stage,
}
-static void wide_begin( struct draw_stage *stage )
+static void wide_first_point( struct draw_stage *stage,
+ struct prim_header *header )
{
struct wide_stage *wide = wide_stage(stage);
struct draw_context *draw = stage->draw;
wide->half_point_size = 0.5f * draw->rasterizer->point_size;
- wide->half_line_width = 0.5f * draw->rasterizer->line_width;
-
- if (draw->rasterizer->line_width != 1.0) {
- wide->stage.line = wide_line;
- }
- else {
- wide->stage.line = passthrough_line;
- }
if (draw->rasterizer->point_size != 1.0) {
- wide->stage.point = wide_point;
+ stage->point = wide_point;
}
else {
- wide->stage.point = passthrough_point;
+ stage->point = passthrough_point;
}
if (draw->rasterizer->point_sprite) {
@@ -299,6 +292,7 @@ static void wide_begin( struct draw_stage *stage )
}
wide->psize_slot = -1;
+
if (draw->rasterizer->point_size_per_vertex) {
/* find PSIZ vertex output */
const struct draw_vertex_shader *vs = draw->vertex_shader;
@@ -311,13 +305,35 @@ static void wide_begin( struct draw_stage *stage )
}
}
- stage->next->begin( stage->next );
+ stage->point( stage, header );
+}
+
+
+
+static void wide_first_line( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ struct wide_stage *wide = wide_stage(stage);
+ struct draw_context *draw = stage->draw;
+
+ wide->half_line_width = 0.5f * draw->rasterizer->line_width;
+
+ if (draw->rasterizer->line_width != 1.0) {
+ wide->stage.line = wide_line;
+ }
+ else {
+ wide->stage.line = passthrough_line;
+ }
+
+ stage->line( stage, header );
}
-static void wide_end( struct draw_stage *stage )
+static void wide_flush( struct draw_stage *stage, unsigned flags )
{
- stage->next->end( stage->next );
+ stage->line = wide_first_line;
+ stage->point = wide_first_point;
+ stage->next->flush( stage->next, flags );
}
@@ -342,11 +358,10 @@ struct draw_stage *draw_wide_stage( struct draw_context *draw )
wide->stage.draw = draw;
wide->stage.next = NULL;
- wide->stage.begin = wide_begin;
- wide->stage.point = wide_point;
- wide->stage.line = wide_line;
+ wide->stage.point = wide_first_point;
+ wide->stage.line = wide_first_line;
wide->stage.tri = passthrough_tri;
- wide->stage.end = wide_end;
+ wide->stage.flush = wide_flush;
wide->stage.reset_stipple_counter = draw_reset_stipple_counter;
wide->stage.destroy = wide_destroy;
diff --git a/src/mesa/pipe/failover/fo_context.c b/src/mesa/pipe/failover/fo_context.c
index a1291f583b..cf6c9fed50 100644
--- a/src/mesa/pipe/failover/fo_context.c
+++ b/src/mesa/pipe/failover/fo_context.c
@@ -46,7 +46,7 @@ static void failover_destroy( struct pipe_context *pipe )
static boolean failover_draw_elements( struct pipe_context *pipe,
- struct pipe_buffer_handle *indexBuffer,
+ struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned prim, unsigned start, unsigned count)
{
@@ -140,7 +140,6 @@ struct pipe_context *failover_create( struct pipe_context *hw,
#endif
failover->pipe.get_tex_surface = hw->get_tex_surface;
- failover->pipe.surface_data = hw->surface_data;
failover->pipe.surface_copy = hw->surface_copy;
failover->pipe.surface_fill = hw->surface_fill;
failover->pipe.texture_create = hw->texture_create;
diff --git a/src/mesa/pipe/i915simple/i915_blit.c b/src/mesa/pipe/i915simple/i915_blit.c
index 6e95313a0d..d49876f970 100644
--- a/src/mesa/pipe/i915simple/i915_blit.c
+++ b/src/mesa/pipe/i915simple/i915_blit.c
@@ -38,7 +38,7 @@ void
i915_fill_blit(struct i915_context *i915,
unsigned cpp,
short dst_pitch,
- struct pipe_buffer_handle *dst_buffer,
+ struct pipe_buffer *dst_buffer,
unsigned dst_offset,
short x, short y,
short w, short h,
@@ -87,10 +87,10 @@ void
i915_copy_blit( struct i915_context *i915,
unsigned cpp,
short src_pitch,
- struct pipe_buffer_handle *src_buffer,
+ struct pipe_buffer *src_buffer,
unsigned src_offset,
short dst_pitch,
- struct pipe_buffer_handle *dst_buffer,
+ struct pipe_buffer *dst_buffer,
unsigned dst_offset,
short src_x, short src_y,
short dst_x, short dst_y,
diff --git a/src/mesa/pipe/i915simple/i915_blit.h b/src/mesa/pipe/i915simple/i915_blit.h
index 7ea4e979ec..d7a66be10a 100644
--- a/src/mesa/pipe/i915simple/i915_blit.h
+++ b/src/mesa/pipe/i915simple/i915_blit.h
@@ -33,10 +33,10 @@
extern void i915_copy_blit(struct i915_context *i915,
unsigned cpp,
short src_pitch,
- struct pipe_buffer_handle *src_buffer,
+ struct pipe_buffer *src_buffer,
unsigned src_offset,
short dst_pitch,
- struct pipe_buffer_handle *dst_buffer,
+ struct pipe_buffer *dst_buffer,
unsigned dst_offset,
short srcx, short srcy,
short dstx, short dsty,
@@ -45,7 +45,7 @@ extern void i915_copy_blit(struct i915_context *i915,
extern void i915_fill_blit(struct i915_context *i915,
unsigned cpp,
short dst_pitch,
- struct pipe_buffer_handle *dst_buffer,
+ struct pipe_buffer *dst_buffer,
unsigned dst_offset,
short x, short y,
short w, short h, unsigned color);
diff --git a/src/mesa/pipe/i915simple/i915_context.c b/src/mesa/pipe/i915simple/i915_context.c
index 1c6b8cbb05..497623a700 100644
--- a/src/mesa/pipe/i915simple/i915_context.c
+++ b/src/mesa/pipe/i915simple/i915_context.c
@@ -166,7 +166,7 @@ static void i915_destroy( struct pipe_context *pipe )
static boolean
i915_draw_elements( struct pipe_context *pipe,
- struct pipe_buffer_handle *indexBuffer,
+ struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned prim, unsigned start, unsigned count)
{
@@ -185,7 +185,7 @@ i915_draw_elements( struct pipe_context *pipe,
void *buf
= pipe->winsys->buffer_map(pipe->winsys,
i915->vertex_buffer[i].buffer,
- PIPE_BUFFER_FLAG_READ);
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(draw, i, buf);
}
}
@@ -193,7 +193,7 @@ i915_draw_elements( struct pipe_context *pipe,
if (indexBuffer) {
void *mapped_indexes
= pipe->winsys->buffer_map(pipe->winsys, indexBuffer,
- PIPE_BUFFER_FLAG_READ);
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
}
else {
diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h
index 2f1f036993..b4ea63c3e7 100644
--- a/src/mesa/pipe/i915simple/i915_context.h
+++ b/src/mesa/pipe/i915simple/i915_context.h
@@ -172,7 +172,7 @@ struct i915_texture {
/* The data is held here:
*/
- struct pipe_buffer_handle *buffer;
+ struct pipe_buffer *buffer;
};
struct i915_context
@@ -204,7 +204,7 @@ struct i915_context
unsigned *batch_start;
/** Vertex buffer */
- struct pipe_buffer_handle *vbo;
+ struct pipe_buffer *vbo;
struct i915_state current;
unsigned hardware_dirty;
diff --git a/src/mesa/pipe/i915simple/i915_fpc_translate.c b/src/mesa/pipe/i915simple/i915_fpc_translate.c
index d517b88acc..0185512aeb 100644
--- a/src/mesa/pipe/i915simple/i915_fpc_translate.c
+++ b/src/mesa/pipe/i915simple/i915_fpc_translate.c
@@ -200,6 +200,9 @@ src_vector(struct i915_fp_compile *p,
}
break;
+ case TGSI_FILE_IMMEDIATE:
+ /* XXX unfinished - need to append immediates onto const buffer */
+ /* fall-through */
case TGSI_FILE_CONSTANT:
src = UREG(REG_TYPE_CONST, index);
break;
@@ -928,9 +931,7 @@ i915_translate_instructions(struct i915_fp_compile *p,
break;
case TGSI_TOKEN_TYPE_IMMEDIATE:
- /* This is a no-op. We'll get immediates from the usual constant/
- * uniform buffer.
- */
+ /* XXX append the immediate to the const buffer... */
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
diff --git a/src/mesa/pipe/i915simple/i915_prim_emit.c b/src/mesa/pipe/i915simple/i915_prim_emit.c
index c50a591589..c4a706c37d 100644
--- a/src/mesa/pipe/i915simple/i915_prim_emit.c
+++ b/src/mesa/pipe/i915simple/i915_prim_emit.c
@@ -73,33 +73,33 @@ emit_hw_vertex( struct i915_context *i915,
uint count = 0; /* for debug/sanity */
for (i = 0; i < vinfo->num_attribs; i++) {
- switch (vinfo->format[i]) {
- case FORMAT_OMIT:
+ switch (vinfo->emit[i]) {
+ case EMIT_OMIT:
/* no-op */
break;
- case FORMAT_1F:
+ case EMIT_1F:
OUT_BATCH( fui(vertex->data[i][0]) );
count++;
break;
- case FORMAT_2F:
+ case EMIT_2F:
OUT_BATCH( fui(vertex->data[i][0]) );
OUT_BATCH( fui(vertex->data[i][1]) );
count += 2;
break;
- case FORMAT_3F:
+ case EMIT_3F:
OUT_BATCH( fui(vertex->data[i][0]) );
OUT_BATCH( fui(vertex->data[i][1]) );
OUT_BATCH( fui(vertex->data[i][2]) );
count += 3;
break;
- case FORMAT_4F:
+ case EMIT_4F:
OUT_BATCH( fui(vertex->data[i][0]) );
OUT_BATCH( fui(vertex->data[i][1]) );
OUT_BATCH( fui(vertex->data[i][2]) );
OUT_BATCH( fui(vertex->data[i][3]) );
count += 4;
break;
- case FORMAT_4UB:
+ case EMIT_4UB:
OUT_BATCH( pack_ub4(float_to_ubyte( vertex->data[i][2] ),
float_to_ubyte( vertex->data[i][1] ),
float_to_ubyte( vertex->data[i][0] ),
@@ -180,13 +180,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
}
-
-static void setup_begin( struct draw_stage *stage )
-{
-}
-
-
-static void setup_end( struct draw_stage *stage )
+static void setup_flush( struct draw_stage *stage, unsigned flags )
{
}
@@ -210,11 +204,10 @@ struct draw_stage *i915_draw_render_stage( struct i915_context *i915 )
setup->i915 = i915;
setup->stage.draw = i915->draw;
- setup->stage.begin = setup_begin;
setup->stage.point = setup_point;
setup->stage.line = setup_line;
setup->stage.tri = setup_tri;
- setup->stage.end = setup_end;
+ setup->stage.flush = setup_flush;
setup->stage.reset_stipple_counter = reset_stipple_counter;
setup->stage.destroy = render_destroy;
diff --git a/src/mesa/pipe/i915simple/i915_prim_vbuf.c b/src/mesa/pipe/i915simple/i915_prim_vbuf.c
index edc62e25e5..39154b2488 100644
--- a/src/mesa/pipe/i915simple/i915_prim_vbuf.c
+++ b/src/mesa/pipe/i915simple/i915_prim_vbuf.c
@@ -42,6 +42,7 @@
#include "pipe/draw/draw_vbuf.h"
#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_winsys.h"
#include "i915_context.h"
@@ -99,16 +100,14 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
/* FIXME: handle failure */
assert(!i915->vbo);
- i915->vbo = winsys->buffer_create(winsys, 64, 0, 0);
- winsys->buffer_data( winsys, i915->vbo,
- size, NULL,
- I915_BUFFER_USAGE_LIT_VERTEX );
+ i915->vbo = winsys->buffer_create(winsys, 64, I915_BUFFER_USAGE_LIT_VERTEX,
+ size);
i915->dirty |= I915_NEW_VBO;
return winsys->buffer_map(winsys,
i915->vbo,
- PIPE_BUFFER_FLAG_WRITE );
+ PIPE_BUFFER_USAGE_CPU_WRITE);
}
@@ -194,7 +193,7 @@ i915_vbuf_render_release_vertices( struct vbuf_render *render,
assert(i915->vbo);
winsys->buffer_unmap(winsys, i915->vbo);
- winsys->buffer_reference(winsys, &i915->vbo, NULL);
+ pipe_buffer_reference(winsys, &i915->vbo, NULL);
}
diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c
index 1190e05699..950ea52d60 100644
--- a/src/mesa/pipe/i915simple/i915_state.c
+++ b/src/mesa/pipe/i915simple/i915_state.c
@@ -476,7 +476,8 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
{
void *mapped;
if (buf->size &&
- (mapped = ws->buffer_map(ws, buf->buffer, PIPE_BUFFER_FLAG_READ))) {
+ (mapped = ws->buffer_map(ws, buf->buffer,
+ PIPE_BUFFER_USAGE_CPU_READ))) {
memcpy(i915->current.constants[shader], mapped, buf->size);
ws->buffer_unmap(ws, buf->buffer);
i915->current.num_user_constants[shader]
diff --git a/src/mesa/pipe/i915simple/i915_state_derived.c b/src/mesa/pipe/i915simple/i915_state_derived.c
index 466c704d87..62741e30f8 100644
--- a/src/mesa/pipe/i915simple/i915_state_derived.c
+++ b/src/mesa/pipe/i915simple/i915_state_derived.c
@@ -56,7 +56,7 @@ static void calculate_vertex_layout( struct i915_context *i915 )
memset(&vinfo, 0, sizeof(vinfo));
/* pos */
- draw_emit_vertex_attr(&vinfo, FORMAT_3F, INTERP_LINEAR, src++);
+ draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src++);
/* Note: we'll set the S4_VFMT_XYZ[W] bits below */
for (i = 0; i < fs->num_inputs; i++) {
@@ -65,12 +65,12 @@ static void calculate_vertex_layout( struct i915_context *i915 )
break;
case TGSI_SEMANTIC_COLOR:
if (fs->input_semantic_index[i] == 0) {
- front0 = draw_emit_vertex_attr(&vinfo, FORMAT_4UB, colorInterp, src++);
+ front0 = draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src++);
vinfo.hwfmt[0] |= S4_VFMT_COLOR;
}
else {
assert(fs->input_semantic_index[i] == 1);
- front1 = draw_emit_vertex_attr(&vinfo, FORMAT_4UB, colorInterp, src++);
+ front1 = draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src++);
vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
}
break;
@@ -80,7 +80,7 @@ static void calculate_vertex_layout( struct i915_context *i915 )
const uint unit = fs->input_semantic_index[i];
uint hwtc;
texCoords[unit] = TRUE;
- draw_emit_vertex_attr(&vinfo, FORMAT_4F, INTERP_PERSPECTIVE, src++);
+ draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
hwtc = TEXCOORDFMT_4D;
needW = TRUE;
vinfo.hwfmt[1] |= hwtc << (unit * 4);
@@ -88,7 +88,7 @@ static void calculate_vertex_layout( struct i915_context *i915 )
break;
case TGSI_SEMANTIC_FOG:
fprintf(stderr, "i915 fogcoord not implemented yet\n");
- draw_emit_vertex_attr(&vinfo, FORMAT_1F, INTERP_PERSPECTIVE, src++);
+ draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src++);
break;
default:
assert(0);
@@ -107,11 +107,11 @@ static void calculate_vertex_layout( struct i915_context *i915 )
/* go back and fill in the vertex position info now that we have needW */
if (needW) {
vinfo.hwfmt[0] |= S4_VFMT_XYZW;
- vinfo.format[0] = FORMAT_4F;
+ vinfo.emit[0] = EMIT_4F;
}
else {
vinfo.hwfmt[0] |= S4_VFMT_XYZ;
- vinfo.format[0] = FORMAT_3F;
+ vinfo.emit[0] = EMIT_3F;
}
/* Additional attributes required for setup: Just twosided
@@ -120,24 +120,16 @@ static void calculate_vertex_layout( struct i915_context *i915 )
*/
if (i915->rasterizer->light_twoside) {
if (front0) {
- back0 = draw_emit_vertex_attr(&vinfo, FORMAT_OMIT, colorInterp, src++);
+ back0 = draw_emit_vertex_attr(&vinfo, EMIT_OMIT, colorInterp, src++);
}
if (back0) {
- back1 = draw_emit_vertex_attr(&vinfo, FORMAT_OMIT, colorInterp, src++);
+ back1 = draw_emit_vertex_attr(&vinfo, EMIT_OMIT, colorInterp, src++);
}
}
draw_compute_vertex_size(&vinfo);
if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) {
- /* If the attributes have changed, tell the draw module about the new
- * vertex layout. We'll also update the hardware vertex format info.
- */
- draw_set_vertex_info( i915->draw, &vinfo);
-
- draw_set_twoside_attributes(i915->draw,
- front0, back0, front1, back1);
-
/* Need to set this flag so that the LIS2/4 registers get set.
* It also means the i915_update_immediate() function must be called
* after this one, in i915_update_derived().
diff --git a/src/mesa/pipe/i915simple/i915_state_emit.c b/src/mesa/pipe/i915simple/i915_state_emit.c
index 09bf1fa2d6..657f523893 100644
--- a/src/mesa/pipe/i915simple/i915_state_emit.c
+++ b/src/mesa/pipe/i915simple/i915_state_emit.c
@@ -74,14 +74,9 @@ framebuffer_size(const struct pipe_framebuffer_state *fb,
*height = fb->cbufs[0]->height;
return TRUE;
}
- else if (fb->zbuf) {
- *width = fb->zbuf->width;
- *height = fb->zbuf->height;
- return TRUE;
- }
- else if (fb->sbuf) {
- *width = fb->sbuf->width;
- *height = fb->sbuf->height;
+ else if (fb->zsbuf) {
+ *width = fb->zsbuf->width;
+ *height = fb->zsbuf->height;
return TRUE;
}
else {
@@ -209,7 +204,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
if (i915->hardware_dirty & I915_HW_STATIC)
{
struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
- struct pipe_surface *depth_surface = i915->framebuffer.zbuf;
+ struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
if (cbuf_surface) {
unsigned pitch = (cbuf_surface->pitch * cbuf_surface->cpp);
@@ -251,7 +246,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
cformat = translate_format(cformat);
if (depth_surface)
- zformat = translate_depth_format( i915->framebuffer.zbuf->format );
+ zformat = translate_depth_format( i915->framebuffer.zsbuf->format );
OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */
@@ -283,7 +278,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
OUT_BATCH(enabled);
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
if (enabled & (1 << unit)) {
- struct pipe_buffer_handle *buf =
+ struct pipe_buffer *buf =
i915->texture[unit]->buffer;
uint offset = 0;
assert(buf);
diff --git a/src/mesa/pipe/i915simple/i915_surface.c b/src/mesa/pipe/i915simple/i915_surface.c
index e625f5a68c..1bdaba773f 100644
--- a/src/mesa/pipe/i915simple/i915_surface.c
+++ b/src/mesa/pipe/i915simple/i915_surface.c
@@ -65,7 +65,7 @@ i915_get_tex_surface(struct pipe_context *pipe,
if (ps) {
assert(ps->refcount);
assert(ps->winsys);
- pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, tex->buffer);
+ pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
ps->width = pt->width[level];
@@ -77,27 +77,6 @@ i915_get_tex_surface(struct pipe_context *pipe,
}
-/* 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
-i915_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->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.
@@ -204,10 +183,7 @@ void
i915_init_surface_functions(struct i915_context *i915)
{
i915->pipe.get_tex_surface = i915_get_tex_surface;
- i915->pipe.get_tile = pipe_get_tile_raw;
- i915->pipe.put_tile = pipe_put_tile_raw;
- i915->pipe.surface_data = i915_surface_data;
i915->pipe.surface_copy = i915_surface_copy;
i915->pipe.surface_fill = i915_surface_fill;
}
diff --git a/src/mesa/pipe/i915simple/i915_texture.c b/src/mesa/pipe/i915simple/i915_texture.c
index 6b0a4a96f3..61944fe7d9 100644
--- a/src/mesa/pipe/i915simple/i915_texture.c
+++ b/src/mesa/pipe/i915simple/i915_texture.c
@@ -490,15 +490,11 @@ i915_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
sizeof(struct i915_texture) - sizeof(struct pipe_texture));
if (i915->flags.is_i945 ? i945_miptree_layout(pipe, tex) :
- i915_miptree_layout(pipe, tex)) {
- tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64, 0, 0);
-
- if (tex->buffer)
- pipe->winsys->buffer_data(pipe->winsys, tex->buffer,
- tex->pitch * tex->base.cpp *
- tex->total_height, NULL,
- PIPE_BUFFER_USAGE_PIXEL);
- }
+ i915_miptree_layout(pipe, tex))
+ tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64,
+ PIPE_BUFFER_USAGE_PIXEL,
+ tex->pitch * tex->base.cpp *
+ tex->total_height);
if (!tex->buffer) {
FREE(tex);
@@ -527,7 +523,7 @@ i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
*/
- pipe->winsys->buffer_reference(pipe->winsys, &tex->buffer, NULL);
+ pipe_buffer_reference(pipe->winsys, &tex->buffer, NULL);
for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
if (tex->image_offset[i])
diff --git a/src/mesa/pipe/i915simple/i915_winsys.h b/src/mesa/pipe/i915simple/i915_winsys.h
index 2c0f335d34..fe49710852 100644
--- a/src/mesa/pipe/i915simple/i915_winsys.h
+++ b/src/mesa/pipe/i915simple/i915_winsys.h
@@ -50,7 +50,7 @@
* etc.
*/
-struct pipe_buffer_handle;
+struct pipe_buffer;
struct pipe_winsys;
@@ -93,7 +93,7 @@ struct i915_winsys {
* I915_BUFFER_ACCESS_READ macros.
*/
void (*batch_reloc)( struct i915_winsys *sws,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned access_flags,
unsigned delta );
diff --git a/src/mesa/pipe/i965simple/brw_batch.h b/src/mesa/pipe/i965simple/brw_batch.h
index 8605d7c108..5f5932a488 100644
--- a/src/mesa/pipe/i965simple/brw_batch.h
+++ b/src/mesa/pipe/i965simple/brw_batch.h
@@ -44,7 +44,8 @@
#define OUT_RELOC( buf, flags, delta ) \
brw->winsys->batch_reloc(brw->winsys, buf, flags, delta)
-#define ADVANCE_BATCH()
+#define ADVANCE_BATCH() \
+ brw->winsys->batch_end( brw->winsys )
/* XXX: this is bogus - need proper handling for out-of-memory in batchbuffer.
*/
diff --git a/src/mesa/pipe/i965simple/brw_blit.c b/src/mesa/pipe/i965simple/brw_blit.c
index 4692129e40..bbd366294f 100644
--- a/src/mesa/pipe/i965simple/brw_blit.c
+++ b/src/mesa/pipe/i965simple/brw_blit.c
@@ -42,7 +42,7 @@
void brw_fill_blit(struct brw_context *brw,
unsigned cpp,
short dst_pitch,
- struct pipe_buffer_handle *dst_buffer,
+ struct pipe_buffer *dst_buffer,
unsigned dst_offset,
boolean dst_tiled,
short x, short y,
@@ -113,11 +113,11 @@ static unsigned translate_raster_op(unsigned logicop)
void brw_copy_blit(struct brw_context *brw,
unsigned cpp,
short src_pitch,
- struct pipe_buffer_handle *src_buffer,
+ struct pipe_buffer *src_buffer,
unsigned src_offset,
boolean src_tiled,
short dst_pitch,
- struct pipe_buffer_handle *dst_buffer,
+ struct pipe_buffer *dst_buffer,
unsigned dst_offset,
boolean dst_tiled,
short src_x, short src_y,
diff --git a/src/mesa/pipe/i965simple/brw_blit.h b/src/mesa/pipe/i965simple/brw_blit.h
index 371a135375..7f17a70173 100644
--- a/src/mesa/pipe/i965simple/brw_blit.h
+++ b/src/mesa/pipe/i965simple/brw_blit.h
@@ -3,13 +3,13 @@
#include "pipe/p_compiler.h"
-struct pipe_buffer_handle;
+struct pipe_buffer;
struct brw_context;
void brw_fill_blit(struct brw_context *intel,
unsigned cpp,
short dst_pitch,
- struct pipe_buffer_handle *dst_buffer,
+ struct pipe_buffer *dst_buffer,
unsigned dst_offset,
boolean dst_tiled,
short x, short y,
@@ -18,11 +18,11 @@ void brw_fill_blit(struct brw_context *intel,
void brw_copy_blit(struct brw_context *intel,
unsigned cpp,
short src_pitch,
- struct pipe_buffer_handle *src_buffer,
+ struct pipe_buffer *src_buffer,
unsigned src_offset,
boolean src_tiled,
short dst_pitch,
- struct pipe_buffer_handle *dst_buffer,
+ struct pipe_buffer *dst_buffer,
unsigned dst_offset,
boolean dst_tiled,
short src_x, short src_y,
diff --git a/src/mesa/pipe/i965simple/brw_context.h b/src/mesa/pipe/i965simple/brw_context.h
index c610a435e0..65664d853d 100644
--- a/src/mesa/pipe/i965simple/brw_context.h
+++ b/src/mesa/pipe/i965simple/brw_context.h
@@ -260,7 +260,7 @@ struct brw_texture {
/* The data is held here:
*/
- struct pipe_buffer_handle *buffer;
+ struct pipe_buffer *buffer;
};
/* Data about a particular attempt to compile a program. Note that
@@ -350,7 +350,7 @@ struct brw_surface_binding_table {
struct brw_cache;
struct brw_mem_pool {
- struct pipe_buffer_handle *buffer;
+ struct pipe_buffer *buffer;
unsigned size;
unsigned offset; /* offset of first free byte */
@@ -615,7 +615,7 @@ struct brw_context
unsigned nr_surfaces;
unsigned max_threads;
- struct pipe_buffer_handle *scratch_buffer;
+ struct pipe_buffer *scratch_buffer;
unsigned scratch_buffer_size;
unsigned sampler_count;
diff --git a/src/mesa/pipe/i965simple/brw_curbe.c b/src/mesa/pipe/i965simple/brw_curbe.c
index 4d79a7abe2..2733eb4e75 100644
--- a/src/mesa/pipe/i965simple/brw_curbe.c
+++ b/src/mesa/pipe/i965simple/brw_curbe.c
@@ -255,15 +255,12 @@ static void upload_constant_buffer(struct brw_context *brw)
/* FIXME: buffer size is num_consts + num_immediates */
if (brw->vs.prog_data->num_consts) {
/* map the vertex constant buffer and copy to curbe: */
- ws->buffer_map(ws, cbuffer->buffer, 0);
+ void *data = ws->buffer_map(ws, cbuffer->buffer, 0);
/* FIXME: this is wrong. the cbuffer->size currently
* represents size of consts + immediates. so if we'll
* have both we'll copy over the end of the buffer
* with the subsequent memcpy */
- ws->buffer_get_subdata(ws, cbuffer->buffer,
- 0,
- cbuffer->size,
- &buf[offset]);
+ memcpy(&buf[offset], data, cbuffer->size);
ws->buffer_unmap(ws, cbuffer->buffer);
offset += cbuffer->size;
}
diff --git a/src/mesa/pipe/i965simple/brw_draw.c b/src/mesa/pipe/i965simple/brw_draw.c
index acfb524a30..7598e3dc8a 100644
--- a/src/mesa/pipe/i965simple/brw_draw.c
+++ b/src/mesa/pipe/i965simple/brw_draw.c
@@ -144,7 +144,7 @@ static boolean brw_emit_prim( struct brw_context *brw,
* fallback conditions.
*/
static boolean brw_try_draw_elements( struct pipe_context *pipe,
- struct pipe_buffer_handle *index_buffer,
+ struct pipe_buffer *index_buffer,
unsigned index_size,
unsigned mode,
unsigned start,
@@ -183,7 +183,7 @@ static boolean brw_try_draw_elements( struct pipe_context *pipe,
static boolean brw_draw_elements( struct pipe_context *pipe,
- struct pipe_buffer_handle *indexBuffer,
+ struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned mode,
unsigned start,
diff --git a/src/mesa/pipe/i965simple/brw_draw.h b/src/mesa/pipe/i965simple/brw_draw.h
index 053f2efb9d..62fe0d5d0e 100644
--- a/src/mesa/pipe/i965simple/brw_draw.h
+++ b/src/mesa/pipe/i965simple/brw_draw.h
@@ -42,7 +42,7 @@ boolean brw_upload_vertices( struct brw_context *brw,
unsigned max_index );
boolean brw_upload_indices(struct brw_context *brw,
- const struct pipe_buffer_handle *index_buffer,
+ const struct pipe_buffer *index_buffer,
int ib_size, int start, int count);
boolean brw_upload_vertex_buffers( struct brw_context *brw );
diff --git a/src/mesa/pipe/i965simple/brw_draw_upload.c b/src/mesa/pipe/i965simple/brw_draw_upload.c
index 88d6c9d111..aa85d93866 100644
--- a/src/mesa/pipe/i965simple/brw_draw_upload.c
+++ b/src/mesa/pipe/i965simple/brw_draw_upload.c
@@ -47,7 +47,7 @@ struct brw_array_state {
unsigned dword;
} vb0;
- struct pipe_buffer_handle *buffer;
+ struct pipe_buffer *buffer;
unsigned offset;
unsigned max_index;
@@ -240,7 +240,7 @@ boolean brw_upload_vertex_buffers( struct brw_context *brw )
for (i = 0; i < nr_enabled; i++) {
OUT_BATCH( vbp.vb[i].vb0.dword );
- OUT_RELOC( vbp.vb[i].buffer, PIPE_BUFFER_FLAG_READ,
+ OUT_RELOC( vbp.vb[i].buffer, PIPE_BUFFER_USAGE_GPU_READ,
vbp.vb[i].offset);
OUT_BATCH( vbp.vb[i].max_index );
OUT_BATCH( vbp.vb[i].instance_data_step_rate );
@@ -272,7 +272,7 @@ boolean brw_upload_vertex_elements( struct brw_context *brw )
}
boolean brw_upload_indices( struct brw_context *brw,
- const struct pipe_buffer_handle *index_buffer,
+ const struct pipe_buffer *index_buffer,
int ib_size, int start, int count)
{
/* Emit the indexbuffer packet:
@@ -290,8 +290,8 @@ boolean brw_upload_indices( struct brw_context *brw,
BEGIN_BATCH(4, 0);
OUT_BATCH( ib.header.dword );
- OUT_RELOC( index_buffer, PIPE_BUFFER_FLAG_READ, start);
- OUT_RELOC( index_buffer, PIPE_BUFFER_FLAG_READ, start + count);
+ OUT_RELOC( index_buffer, PIPE_BUFFER_USAGE_GPU_READ, start);
+ OUT_RELOC( index_buffer, PIPE_BUFFER_USAGE_GPU_READ, start + count);
OUT_BATCH( 0 );
ADVANCE_BATCH();
}
diff --git a/src/mesa/pipe/i965simple/brw_misc_state.c b/src/mesa/pipe/i965simple/brw_misc_state.c
index 13b3b1671d..925049ecc1 100644
--- a/src/mesa/pipe/i965simple/brw_misc_state.c
+++ b/src/mesa/pipe/i965simple/brw_misc_state.c
@@ -211,7 +211,7 @@ const struct brw_tracked_state brw_psp_urb_cbs = {
*/
static void upload_depthbuffer(struct brw_context *brw)
{
- struct pipe_surface *depth_surface = brw->attribs.FrameBuffer.zbuf;
+ struct pipe_surface *depth_surface = brw->attribs.FrameBuffer.zsbuf;
BEGIN_BATCH(5, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (5 - 2));
@@ -245,7 +245,7 @@ static void upload_depthbuffer(struct brw_context *brw)
// (depth_surface->region->tiled << 27) |
(BRW_SURFACE_2D << 29));
OUT_RELOC(depth_surface->buffer,
- PIPE_BUFFER_FLAG_READ | PIPE_BUFFER_FLAG_WRITE, 0);
+ PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE, 0);
OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) |
((depth_surface->pitch - 1) << 6) |
((depth_surface->height - 1) << 19));
@@ -465,10 +465,10 @@ static void upload_state_base_address( struct brw_context *brw )
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2));
OUT_RELOC(brw->pool[BRW_GS_POOL].buffer,
- PIPE_BUFFER_FLAG_READ,
+ PIPE_BUFFER_USAGE_GPU_READ,
1); /* General state base address */
OUT_RELOC(brw->pool[BRW_SS_POOL].buffer,
- PIPE_BUFFER_FLAG_READ,
+ PIPE_BUFFER_USAGE_GPU_READ,
1); /* Surface state base address */
OUT_BATCH(1); /* Indirect object base address */
OUT_BATCH(1); /* General state upper bound */
diff --git a/src/mesa/pipe/i965simple/brw_state.h b/src/mesa/pipe/i965simple/brw_state.h
index 8b4d7aabf0..258e9a556e 100644
--- a/src/mesa/pipe/i965simple/brw_state.h
+++ b/src/mesa/pipe/i965simple/brw_state.h
@@ -106,7 +106,7 @@ boolean brw_search_cache( struct brw_cache *cache,
void brw_init_caches( struct brw_context *brw );
void brw_destroy_caches( struct brw_context *brw );
-static inline struct pipe_buffer_handle *brw_cache_buffer(struct brw_context *brw,
+static inline struct pipe_buffer *brw_cache_buffer(struct brw_context *brw,
enum brw_cache_id id)
{
return brw->cache[id].pool->buffer;
diff --git a/src/mesa/pipe/i965simple/brw_state_pool.c b/src/mesa/pipe/i965simple/brw_state_pool.c
index 78268ed8f2..7c67f0ee25 100644
--- a/src/mesa/pipe/i965simple/brw_state_pool.c
+++ b/src/mesa/pipe/i965simple/brw_state_pool.c
@@ -44,6 +44,7 @@
#include "pipe/p_winsys.h"
#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
#include "brw_context.h"
#include "brw_state.h"
@@ -91,13 +92,9 @@ static void brw_init_pool( struct brw_context *brw,
pool->brw = brw;
pool->buffer = brw->pipe.winsys->buffer_create(brw->pipe.winsys,
- 4096, 0, 0);
-
- brw->pipe.winsys->buffer_data(brw->pipe.winsys,
- pool->buffer,
- size,
- NULL,
- 0 /* DRM_BO_FLAG_MEM_TT */);
+ 4096,
+ 0 /* DRM_BO_FLAG_MEM_TT */,
+ size);
}
static void brw_destroy_pool( struct brw_context *brw,
@@ -105,9 +102,9 @@ static void brw_destroy_pool( struct brw_context *brw,
{
struct brw_mem_pool *pool = &brw->pool[pool_id];
- pool->brw->pipe.winsys->buffer_reference( pool->brw->pipe.winsys,
- &pool->buffer,
- NULL );
+ pipe_buffer_reference( pool->brw->pipe.winsys,
+ &pool->buffer,
+ NULL );
}
diff --git a/src/mesa/pipe/i965simple/brw_surface.c b/src/mesa/pipe/i965simple/brw_surface.c
index 76b8c73d5c..eb7835836e 100644
--- a/src/mesa/pipe/i965simple/brw_surface.c
+++ b/src/mesa/pipe/i965simple/brw_surface.c
@@ -64,7 +64,7 @@ brw_get_tex_surface(struct pipe_context *pipe,
if (ps) {
assert(ps->format);
assert(ps->refcount);
- pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, tex->buffer);
+ pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
ps->width = pt->width[level];
@@ -203,10 +203,6 @@ void
brw_init_surface_functions(struct brw_context *brw)
{
brw->pipe.get_tex_surface = brw_get_tex_surface;
- brw->pipe.get_tile = pipe_get_tile_raw;
- brw->pipe.put_tile = pipe_put_tile_raw;
-
- brw->pipe.surface_data = brw_surface_data;
brw->pipe.surface_copy = brw_surface_copy;
brw->pipe.surface_fill = brw_surface_fill;
}
diff --git a/src/mesa/pipe/i965simple/brw_tex_layout.c b/src/mesa/pipe/i965simple/brw_tex_layout.c
index 2b2bf16f1b..b8b6b579e2 100644
--- a/src/mesa/pipe/i965simple/brw_tex_layout.c
+++ b/src/mesa/pipe/i965simple/brw_tex_layout.c
@@ -39,6 +39,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_winsys.h"
#include "brw_context.h"
@@ -308,15 +309,11 @@ brw_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
memset(&tex->base + 1, 0,
sizeof(struct brw_texture) - sizeof(struct pipe_texture));
- if (brw_miptree_layout(pipe, tex)) {
- tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64, 0, 0);
-
- if (tex->buffer)
- pipe->winsys->buffer_data(pipe->winsys, tex->buffer,
- tex->pitch * tex->base.cpp *
- tex->total_height, NULL,
- PIPE_BUFFER_USAGE_PIXEL);
- }
+ if (brw_miptree_layout(pipe, tex))
+ tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64,
+ PIPE_BUFFER_USAGE_PIXEL,
+ tex->pitch * tex->base.cpp *
+ tex->total_height);
if (!tex->buffer) {
FREE(tex);
@@ -345,7 +342,7 @@ brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
*/
- pipe->winsys->buffer_reference(pipe->winsys, &tex->buffer, NULL);
+ pipe_buffer_reference(pipe->winsys, &tex->buffer, NULL);
for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
if (tex->image_offset[i])
diff --git a/src/mesa/pipe/i965simple/brw_vs_emit.c b/src/mesa/pipe/i965simple/brw_vs_emit.c
index 5f212bd055..b32c233dd2 100644
--- a/src/mesa/pipe/i965simple/brw_vs_emit.c
+++ b/src/mesa/pipe/i965simple/brw_vs_emit.c
@@ -988,33 +988,24 @@ post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst )
static void process_declaration(const struct tgsi_full_declaration *decl,
struct brw_prog_info *info)
{
+ int first = decl->u.DeclarationRange.First;
+ int last = decl->u.DeclarationRange.Last;
+
+ assert (decl->Declaration.Declare != TGSI_DECLARE_MASK);
+
switch(decl->Declaration.File) {
- case TGSI_FILE_CONSTANT: {
- if (decl->Declaration.Declare == TGSI_DECLARE_MASK) {
- printf("DECLARATION MASK = %d\n",
- decl->u.DeclarationMask.Mask);
- assert(0);
- } else { /*range*/
- info->num_consts += decl->u.DeclarationRange.Last - decl->u.DeclarationRange.First + 1;
- }
- }
+ case TGSI_FILE_CONSTANT:
+ info->num_consts += last - first + 1;
break;
case TGSI_FILE_INPUT: {
}
break;
case TGSI_FILE_OUTPUT: {
+ assert(last == first); /* for now */
if (decl->Declaration.Semantic) {
- int idx = 0;
- if (decl->Declaration.Declare == TGSI_DECLARE_MASK) {
- printf("DECLARATION MASK = %d\n",
- decl->u.DeclarationMask.Mask);
- assert(0);
- } else { /*range*/
- idx = decl->u.DeclarationRange.First;
- }
switch (decl->Semantic.SemanticName) {
case TGSI_SEMANTIC_POSITION: {
- info->pos_idx = idx;
+ info->pos_idx = first;
}
break;
case TGSI_SEMANTIC_COLOR:
@@ -1025,7 +1016,7 @@ static void process_declaration(const struct tgsi_full_declaration *decl,
break;
case TGSI_SEMANTIC_PSIZE: {
info->writes_psize = TRUE;
- info->psize_idx = idx;
+ info->psize_idx = first;
}
break;
case TGSI_SEMANTIC_GENERIC:
@@ -1035,14 +1026,14 @@ static void process_declaration(const struct tgsi_full_declaration *decl,
}
break;
case TGSI_FILE_TEMPORARY: {
- info->num_temps++;
+ info->num_temps += (last - first) + 1;
}
break;
case TGSI_FILE_SAMPLER: {
}
break;
case TGSI_FILE_ADDRESS: {
- info->num_addrs++;
+ info->num_addrs += (last - first) + 1;
}
break;
case TGSI_FILE_IMMEDIATE: {
@@ -1303,7 +1294,6 @@ void brw_vs_emit(struct brw_vs_compile *c)
}
break;
case TGSI_TOKEN_TYPE_IMMEDIATE: {
- int i;
struct tgsi_full_immediate *imm = &parse.FullToken.FullImmediate;
/*assert(imm->Immediate.Size == 4);*/
c->prog_data.imm_buf[c->prog_data.num_imm][0] = imm->u.ImmediateFloat32[0].Float;
diff --git a/src/mesa/pipe/i965simple/brw_winsys.h b/src/mesa/pipe/i965simple/brw_winsys.h
index 253599896c..3523a58614 100644
--- a/src/mesa/pipe/i965simple/brw_winsys.h
+++ b/src/mesa/pipe/i965simple/brw_winsys.h
@@ -50,7 +50,7 @@
* etc.
*/
-struct pipe_buffer_handle;
+struct pipe_buffer;
struct pipe_fence_handle;
struct pipe_winsys;
@@ -136,7 +136,7 @@ struct brw_winsys {
* I915_BUFFER_ACCESS_READ macros.
*/
void (*batch_reloc)(struct brw_winsys *sws,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned access_flags,
unsigned delta);
@@ -159,7 +159,7 @@ struct brw_winsys {
* simulator:
*/
void (*buffer_subdata_typed)(struct brw_winsys *sws,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned long offset,
unsigned long size,
const void *data,
@@ -170,7 +170,7 @@ struct brw_winsys {
* of places yet:
*/
unsigned (*get_buffer_offset)( struct brw_winsys *sws,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned flags );
};
@@ -193,9 +193,13 @@ static inline boolean brw_batchbuffer_data(struct brw_winsys *winsys,
uint i;
const unsigned *udata = (const unsigned*)(data);
unsigned size = bytes/incr;
+
+ winsys->batch_start(winsys, size, 0);
for (i = 0; i < size; ++i) {
winsys->batch_dword(winsys, udata[i]);
}
+ winsys->batch_end(winsys);
+
return (i == size);
}
#endif
diff --git a/src/mesa/pipe/i965simple/brw_wm_surface_state.c b/src/mesa/pipe/i965simple/brw_wm_surface_state.c
index fc40e0438c..cbb4f2efd3 100644
--- a/src/mesa/pipe/i965simple/brw_wm_surface_state.c
+++ b/src/mesa/pipe/i965simple/brw_wm_surface_state.c
@@ -127,7 +127,7 @@ static unsigned translate_tex_format( enum pipe_format pipe_format )
}
static unsigned brw_buffer_offset(struct brw_context *brw,
- struct pipe_buffer_handle *buffer)
+ struct pipe_buffer *buffer)
{
return brw->winsys->get_buffer_offset(brw->winsys,
buffer,
diff --git a/src/mesa/pipe/llvm/Makefile b/src/mesa/pipe/llvm/Makefile
index b1463f67cf..f655fb8340 100644
--- a/src/mesa/pipe/llvm/Makefile
+++ b/src/mesa/pipe/llvm/Makefile
@@ -61,7 +61,7 @@ gallivm_builtins.cpp: llvm_builtins.c
clang --emit-llvm $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins
llvm_base_shader.cpp: llvm_entry.c
- clang --emit-llvm $< |llvm-as |opt -std-compile-opts |llvm2cpp -for=Shader -gen-module -o=$@ -funcname=createBaseShader
+ clang --emit-llvm $< |llvm-as |opt -std-compile-opts |llvm2cpp -for=Shader -gen-module -o=$@ -f -funcname=createBaseShader
# Emacs tags
tags:
diff --git a/src/mesa/pipe/llvm/gallivm.cpp b/src/mesa/pipe/llvm/gallivm.cpp
index 49bbf753c4..afa1446890 100644
--- a/src/mesa/pipe/llvm/gallivm.cpp
+++ b/src/mesa/pipe/llvm/gallivm.cpp
@@ -733,7 +733,11 @@ tgsi_to_llvm(struct gallivm_prog *prog, const struct tgsi_token *tokens)
unsigned instno = 0;
Function* shader = mod->getFunction("execute_shader");
std::ostringstream stream;
- stream << "execute_shader";
+ if (prog->type == GALLIVM_VS) {
+ stream << "vs_shader";
+ } else {
+ stream << "fs_shader";
+ }
stream << prog->id;
std::string func_name = stream.str();
shader->setName(func_name.c_str());
@@ -799,6 +803,7 @@ gallivm_from_tgsi(const struct tgsi_token *tokens, enum gallivm_shader_type type
struct gallivm_prog *gallivm =
(struct gallivm_prog *)calloc(1, sizeof(struct gallivm_prog));
gallivm->id = GLOBAL_ID;
+ gallivm->type = type;
tgsi_dump(tokens, 0);
llvm::Module *mod = tgsi_to_llvm(gallivm, tokens);
@@ -812,7 +817,6 @@ gallivm_from_tgsi(const struct tgsi_token *tokens, enum gallivm_shader_type type
passes.run(*mod);
gallivm->module = mod;
- gallivm->type = type;
gallivm_prog_dump(gallivm, 0);
@@ -966,7 +970,8 @@ void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix)
const llvm::Function &func = (*itr);
std::string name = func.getName();
const llvm::Function *found = 0;
- if (name.find("execute_shader") != std::string::npos ||
+ if (name.find("vs_shader") != std::string::npos ||
+ name.find("fs_shader") != std::string::npos ||
name.find("function") != std::string::npos)
found = &func;
if (found) {
diff --git a/src/mesa/pipe/llvm/gallivm.h b/src/mesa/pipe/llvm/gallivm.h
index fd9a11e5b6..4695de3127 100644
--- a/src/mesa/pipe/llvm/gallivm.h
+++ b/src/mesa/pipe/llvm/gallivm.h
@@ -30,8 +30,8 @@
* Zack Rusin zack@tungstengraphics.com
*/
-#ifndef LLVMTGSI_H
-#define LLVMTGSI_H
+#ifndef GALLIVM_H
+#define GALLIVM_H
#if defined __cplusplus
extern "C" {
diff --git a/src/mesa/pipe/llvm/llvm_entry.c b/src/mesa/pipe/llvm/llvm_entry.c
index 909bef340a..c3b34584e1 100644
--- a/src/mesa/pipe/llvm/llvm_entry.c
+++ b/src/mesa/pipe/llvm/llvm_entry.c
@@ -34,95 +34,6 @@
/* clang --emit-llvm llvm_builtins.c |llvm-as |opt -std-compile-opts |llvm-dis */
typedef __attribute__(( ocu_vector_type(4) )) float float4;
-#if 0
-//clang doesn't suppoer "struct->member" notation yet
-struct vertex_header {
- unsigned clipmask:12;
- unsigned edgeflag:1;
- unsigned pad:3;
- unsigned vertex_id:16;
-
- float clip[4];
-
- float data[][4];
-};
-
-inline float
-dot4(float4 a, float4 b)
-{
- float4 c = a*b;
- return c.x + c.y + c.z + c.w;
-}
-
-inline unsigned
-compute_clipmask(float4 clip, float4 (*plane), unsigned nr)
-{
- unsigned mask = 0;
- unsigned i;
-
- for (i = 0; i < nr; i++) {
- if (dot4(clip, plane[i]) < 0)
- mask |= (1<<i);
- }
-
- return mask;
-}
-
-
-inline void collect_results(float4 *results, struct vertex_header *vOut,
- float4 *planes, int nr_planes,
- float4 scale, float4 trans,
- int num_attribs)
-{
- /* store results */
- unsigned slot;
- float x, y, z, w;
- /* Handle attr[0] (position) specially:
- */
- float4 res0 = results[0];
- float *clip = vOut->clip;
- x = clip[0] = res0.x;
- y = clip[1] = res0.y;
- z = clip[2] = res0.z;
- w = clip[3] = res0.w;
- vOut->clipmask = compute_clipmask(res0, planes, nr_planes);
- vOut->edgeflag = 1;
-
- /* divide by w */
- w = 1.0f / w;
- x *= w;
- y *= w;
- z *= w;
- res0.x = x; res0.y = y; res0.z = z; res0.w = 1;
-
- /* Viewport mapping */
- res0 = res0 * scale + trans;
- vOut->data[0][0] = res0.x;
- vOut->data[0][1] = res0.y;
- vOut->data[0][2] = res0.z;
- vOut->data[0][3] = w;
-
- /* Remaining attributes are packed into sequential post-transform
- * vertex attrib slots.
- * Skip 0 since we just did it above.
- * Subtract two because of the VERTEX_HEADER, CLIP_POS attribs.
- */
- for (slot = 1; slot < num_attribs - 2; slot++) {
- float4 vec = results[slot];
- vOut->data[slot][0] = vec.x;
- vOut->data[slot][1] = vec.y;
- vOut->data[slot][2] = vec.z;
- vOut->data[slot][3] = vec.w;
-
- printf("output %d: %f %f %f %f\n", slot,
- vOut->data[slot][0],
- vOut->data[slot][1],
- vOut->data[slot][2],
- vOut->data[slot][3]);
- }
-}
-#endif
-
void from_array(float4 (*res)[16], float (*ainputs)[16][4],
int count, int num_attribs)
{
diff --git a/src/mesa/pipe/p_compiler.h b/src/mesa/pipe/p_compiler.h
index ab9609deab..e939d9cd9b 100644
--- a/src/mesa/pipe/p_compiler.h
+++ b/src/mesa/pipe/p_compiler.h
@@ -52,6 +52,9 @@ typedef unsigned long long uint64;
#if defined(__MSC__)
+typedef char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
typedef unsigned short uint16_t;
typedef long int32_t;
typedef unsigned long uint32_t;
diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h
index 7a18d48865..0dda06c53b 100644
--- a/src/mesa/pipe/p_context.h
+++ b/src/mesa/pipe/p_context.h
@@ -74,13 +74,10 @@ struct pipe_context {
unsigned mode, unsigned start, unsigned count);
boolean (*draw_elements)( struct pipe_context *pipe,
- struct pipe_buffer_handle *indexBuffer,
+ struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count);
- /** Clear a surface to given value (no scissor; clear whole surface) */
- void (*clear)(struct pipe_context *pipe, struct pipe_surface *ps,
- unsigned clearValue);
/**
* Query objects
@@ -176,33 +173,9 @@ struct pipe_context {
const struct pipe_vertex_element * );
- /** Get a surface which is a "view" into a texture */
- struct pipe_surface *(*get_tex_surface)(struct pipe_context *pipe,
- struct pipe_texture *texture,
- unsigned face, unsigned level,
- unsigned zslice);
-
- /** Get a block of raw pixel data from a surface */
- void (*get_tile)(struct pipe_context *pipe,
- struct pipe_surface *ps,
- uint x, uint y, uint w, uint h,
- void *p, int dst_stride);
- /** Put a block of raw pixel data into a surface */
- void (*put_tile)(struct pipe_context *pipe,
- struct pipe_surface *ps,
- uint x, uint y, uint w, uint h,
- const void *p, int src_stride);
-
-
/*
* Surface functions
*/
- void (*surface_data)(struct pipe_context *pipe,
- struct pipe_surface *dest,
- unsigned destx, unsigned desty,
- const void *src, unsigned src_stride,
- unsigned srcx, unsigned srcy,
- unsigned width, unsigned height);
void (*surface_copy)(struct pipe_context *pipe,
struct pipe_surface *dest,
@@ -218,6 +191,10 @@ struct pipe_context {
unsigned width, unsigned height,
unsigned value);
+ void (*clear)(struct pipe_context *pipe,
+ struct pipe_surface *ps,
+ unsigned clearValue);
+
/*
* Texture functions
@@ -228,6 +205,11 @@ struct pipe_context {
void (*texture_release)(struct pipe_context *pipe,
struct pipe_texture **pt);
+ /** Get a surface which is a "view" into a texture */
+ struct pipe_surface *(*get_tex_surface)(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level,
+ unsigned zslice);
/* Flush rendering:
*/
diff --git a/src/mesa/pipe/p_defines.h b/src/mesa/pipe/p_defines.h
index 50bea691e7..85adf2d61d 100644
--- a/src/mesa/pipe/p_defines.h
+++ b/src/mesa/pipe/p_defines.h
@@ -178,25 +178,19 @@ enum pipe_texture_target {
/**
- * Buffer access flags
- */
-#define PIPE_BUFFER_FLAG_READ 0x1
-#define PIPE_BUFFER_FLAG_WRITE 0x2
-#define PIPE_BUFFER_FLAG_MEM_LOCAL 0x4
-#define PIPE_BUFFER_FLAG_CACHED 0x8
-#define PIPE_BUFFER_FLAG_CUSTOM (1<<16)
-
-
-
-/**
* Buffer usage flags
*/
-#define PIPE_BUFFER_USAGE_PIXEL (1 << 0)
-#define PIPE_BUFFER_USAGE_VERTEX (1 << 1)
-#define PIPE_BUFFER_USAGE_INDEX (1 << 2)
-#define PIPE_BUFFER_USAGE_CONSTANT (1 << 3)
+#define PIPE_BUFFER_USAGE_CPU_READ (1 << 0)
+#define PIPE_BUFFER_USAGE_CPU_WRITE (1 << 1)
+#define PIPE_BUFFER_USAGE_GPU_READ (1 << 2)
+#define PIPE_BUFFER_USAGE_GPU_WRITE (1 << 3)
+#define PIPE_BUFFER_USAGE_PIXEL (1 << 4)
+#define PIPE_BUFFER_USAGE_VERTEX (1 << 5)
+#define PIPE_BUFFER_USAGE_INDEX (1 << 6)
+#define PIPE_BUFFER_USAGE_CONSTANT (1 << 7)
/** Pipe driver custam usage flags should be greater or equal to this value */
-#define PIPE_BUFFER_USAGE_CUSTOM (1 << 16)
+#define PIPE_BUFFER_USAGE_CUSTOM (1 << 16)
+
/**
* Flush types:
@@ -204,6 +198,7 @@ enum pipe_texture_target {
#define PIPE_FLUSH_RENDER_CACHE 0x1
#define PIPE_FLUSH_TEXTURE_CACHE 0x2
#define PIPE_FLUSH_WAIT 0x4
+#define PIPE_FLUSH_SWAPBUFFERS 0x8
/**
diff --git a/src/mesa/pipe/p_inlines.h b/src/mesa/pipe/p_inlines.h
index 6976d087f9..ebf6ed86bc 100644
--- a/src/mesa/pipe/p_inlines.h
+++ b/src/mesa/pipe/p_inlines.h
@@ -37,8 +37,8 @@ static INLINE void *
pipe_surface_map(struct pipe_surface *surface)
{
return (char *)surface->winsys->buffer_map( surface->winsys, surface->buffer,
- PIPE_BUFFER_FLAG_WRITE |
- PIPE_BUFFER_FLAG_READ )
+ PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_CPU_READ )
+ surface->offset;
}
@@ -56,20 +56,38 @@ pipe_surface_unmap(struct pipe_surface *surface)
static INLINE void
pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
{
- assert(ptr);
- if (*ptr) {
+ /* bump the refcount first */
+ if (surf)
+ surf->refcount++;
+
+ if (*ptr /* && --(*ptr)->refcount == 0 */) {
struct pipe_winsys *winsys = (*ptr)->winsys;
winsys->surface_release(winsys, ptr);
assert(!*ptr);
}
- if (surf) {
- /* reference the new thing */
- surf->refcount++;
- *ptr = surf;
- }
+
+ *ptr = surf;
+}
+
+
+/* XXX: thread safety issues!
+ */
+static INLINE void
+pipe_buffer_reference(struct pipe_winsys *winsys,
+ struct pipe_buffer **ptr,
+ struct pipe_buffer *buf)
+{
+ if (buf)
+ buf->refcount++;
+
+ if (*ptr && --(*ptr)->refcount == 0)
+ winsys->buffer_destroy( winsys, *ptr );
+
+ *ptr = buf;
}
+
/**
* \sa pipe_surface_reference
*/
@@ -78,15 +96,16 @@ pipe_texture_reference(struct pipe_context *pipe, struct pipe_texture **ptr,
struct pipe_texture *pt)
{
assert(ptr);
+
+ if (pt)
+ pt->refcount++;
+
if (*ptr) {
pipe->texture_release(pipe, ptr);
assert(!*ptr);
}
- if (pt) {
- /* reference the new thing */
- pt->refcount++;
- *ptr = pt;
- }
+
+ *ptr = pt;
}
diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h
index 46328d2a8f..83ca43f678 100644
--- a/src/mesa/pipe/p_state.h
+++ b/src/mesa/pipe/p_state.h
@@ -60,8 +60,21 @@
struct pipe_surface;
struct pipe_winsys;
-/* opaque type */
-struct pipe_buffer_handle;
+
+
+/**
+ * The driver will certainly subclass this to include actual memory
+ * management information.
+ */
+struct pipe_buffer {
+ unsigned alignment;
+ unsigned usage;
+ unsigned size;
+
+ /** Reference count */
+ unsigned refcount;
+};
+
@@ -129,7 +142,7 @@ struct pipe_clip_state {
* Constants for vertex/fragment shaders
*/
struct pipe_constant_buffer {
- struct pipe_buffer_handle *buffer;
+ struct pipe_buffer *buffer;
unsigned size; /** in bytes */
};
@@ -202,8 +215,7 @@ struct pipe_framebuffer_state
unsigned num_cbufs;
struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS];
- struct pipe_surface *zbuf; /**< Z buffer */
- struct pipe_surface *sbuf; /**< Stencil buffer */
+ struct pipe_surface *zsbuf; /**< Z/stencil buffer */
};
@@ -241,7 +253,7 @@ struct pipe_sampler_state
*/
struct pipe_surface
{
- struct pipe_buffer_handle *buffer; /**< driver private buffer handle */
+ struct pipe_buffer *buffer; /**< driver private buffer handle */
enum pipe_format format; /**< PIPE_FORMAT_x */
unsigned status; /**< PIPE_SURFACE_STATUS_x */
unsigned clear_value; /**< may be temporary */
@@ -291,7 +303,7 @@ struct pipe_vertex_buffer
unsigned pitch:11; /**< stride to same attrib in next vertex, in bytes */
unsigned max_index; /**< number of vertices in this buffer */
unsigned buffer_offset; /**< offset to start of data in buffer, in bytes */
- struct pipe_buffer_handle *buffer; /**< the actual buffer */
+ struct pipe_buffer *buffer; /**< the actual buffer */
};
diff --git a/src/mesa/pipe/p_thread.h b/src/mesa/pipe/p_thread.h
new file mode 100644
index 0000000000..cd432c547c
--- /dev/null
+++ b/src/mesa/pipe/p_thread.h
@@ -0,0 +1,54 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef P_THREAD_H
+#define P_THREAD_H
+
+#include "p_compiler.h"
+
+/*
+ * XXX: We should come up with a system-independent thread definitions.
+ * XXX: Patching glthread defs for now.
+ */
+
+#ifndef __MSC__
+
+#include "glapi/glthread.h"
+
+#else /* __MSC__ */
+
+typedef int _glthread_Mutex;
+
+#define _glthread_INIT_MUTEX( M ) ((void) (M))
+#define _glthread_LOCK_MUTEX( M ) ((void) (M))
+#define _glthread_UNLOCK_MUTEX( M ) ((void) (M))
+
+#define sched_yield() ((void) 0)
+
+#endif /* __MSC__ */
+
+#endif /* P_THREAD_H */
diff --git a/src/mesa/pipe/p_util.h b/src/mesa/pipe/p_util.h
index a2bc330424..059528787d 100644
--- a/src/mesa/pipe/p_util.h
+++ b/src/mesa/pipe/p_util.h
@@ -108,6 +108,8 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size )
#endif /* WIN32 */
+#define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T))
+
#define CALLOC_STRUCT(T) (struct T *) CALLOC(1, sizeof(struct T))
diff --git a/src/mesa/pipe/p_winsys.h b/src/mesa/pipe/p_winsys.h
index 75c6dc7e85..95e3684008 100644
--- a/src/mesa/pipe/p_winsys.h
+++ b/src/mesa/pipe/p_winsys.h
@@ -1,4 +1,4 @@
-/**************************************************************************
+ /**************************************************************************
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -39,9 +39,6 @@
*/
-/** Opaque type for a buffer */
-struct pipe_buffer_handle;
-
/** Opaque type */
struct pipe_fence_handle;
@@ -93,20 +90,23 @@ struct pipe_winsys
/**
- * The buffer manager is modeled after the dri_bufmgr interface, which
- * in turn is modeled after the ARB_vertex_buffer_object extension,
- * but this is the subset that gallium cares about. Remember that
- * gallium gets to choose the interface it needs, and the window
- * systems must then implement that interface (rather than the
+ * Buffer management. Buffer attributes are mostly fixed over its lifetime.
+ *
+ * Remember that gallium gets to choose the interface it needs, and the
+ * window systems must then implement that interface (rather than the
* other way around...).
+ *
+ * usage is a bitmask of PIPE_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This
+ * usage argument is only an optimization hint, not a guarantee, therefore
+ * proper behavior must be observed in all circumstances.
*/
- struct pipe_buffer_handle *(*buffer_create)( struct pipe_winsys *sws,
+ struct pipe_buffer *(*buffer_create)( struct pipe_winsys *sws,
unsigned alignment,
- unsigned flags,
- unsigned hint );
+ unsigned usage,
+ unsigned size );
/** Create a buffer that wraps user-space data */
- struct pipe_buffer_handle *(*user_buffer_create)(struct pipe_winsys *sws,
+ struct pipe_buffer *(*user_buffer_create)(struct pipe_winsys *sws,
void *ptr,
unsigned bytes);
@@ -115,55 +115,17 @@ struct pipe_winsys
* flags is bitmask of PIPE_BUFFER_FLAG_READ/WRITE.
*/
void *(*buffer_map)( struct pipe_winsys *sws,
- struct pipe_buffer_handle *buf,
- unsigned flags );
+ struct pipe_buffer *buf,
+ unsigned usage );
void (*buffer_unmap)( struct pipe_winsys *sws,
- struct pipe_buffer_handle *buf );
-
- /** Set ptr = buf, with reference counting */
- void (*buffer_reference)( struct pipe_winsys *sws,
- struct pipe_buffer_handle **ptr,
- struct pipe_buffer_handle *buf );
+ struct pipe_buffer *buf );
- /**
- * Create the data store of a buffer and optionally initialize it.
- *
- * usage is a bitmask of PIPE_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This
- * usage argument is only an optimization hint, not a guarantee, therefore
- * proper behavior must be observed in all circumstances.
- *
- * Returns zero on success.
- */
- int (*buffer_data)(struct pipe_winsys *sws,
- struct pipe_buffer_handle *buf,
- unsigned size, const void *data,
- unsigned usage);
-
- /**
- * Modify some or all of the data contained in a buffer's data store.
- *
- * Returns zero on success.
- */
- int (*buffer_subdata)(struct pipe_winsys *sws,
- struct pipe_buffer_handle *buf,
- unsigned long offset,
- unsigned long size,
- const void *data);
-
- /**
- * Query some or all of the data contained in a buffer's data store.
- *
- * Returns zero on success.
- */
- int (*buffer_get_subdata)(struct pipe_winsys *sws,
- struct pipe_buffer_handle *buf,
- unsigned long offset,
- unsigned long size,
- void *data);
+ void (*buffer_destroy)( struct pipe_winsys *sws,
+ struct pipe_buffer *buf );
- /** Set ptr = buf, with reference counting */
+ /** Set ptr = fence, with reference counting */
void (*fence_reference)( struct pipe_winsys *sws,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence );
diff --git a/src/mesa/pipe/pipebuffer/Makefile b/src/mesa/pipe/pipebuffer/Makefile
index 061d8a060f..ea8c3440c3 100644
--- a/src/mesa/pipe/pipebuffer/Makefile
+++ b/src/mesa/pipe/pipebuffer/Makefile
@@ -4,14 +4,11 @@ include $(TOP)/configs/current
LIBNAME = pipebuffer
-
DRIVER_SOURCES = \
pb_buffer.c \
pb_buffer_client.c \
- pb_buffer_handle.c \
pb_buffer_fenced.c \
pb_buffer_malloc.c \
- pb_buffer_null.c \
pb_bufmgr_fenced.c \
pb_bufmgr_mm.c \
pb_bufmgr_pool.c
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer.c b/src/mesa/pipe/pipebuffer/pb_buffer.c
index 99c960b697..90ab9044ff 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer.c
+++ b/src/mesa/pipe/pipebuffer/pb_buffer.c
@@ -34,19 +34,44 @@
#include "pb_buffer.h"
+#include "pipe/p_winsys.h"
-void
-buffer_reference(struct pipe_buffer **dst,
- struct pipe_buffer *src)
+
+static void *
+pb_winsys_map(struct pipe_winsys *winsys,
+ struct pipe_buffer *ws_buf,
+ unsigned flags)
+{
+ struct pb_buffer *buf = pb_buffer(ws_buf);
+
+ return buf->vtbl->map(buf, flags);
+}
+
+static void
+pb_winsys_unmap(struct pipe_winsys *winsys,
+ struct pipe_buffer *ws_buf)
+{
+ struct pb_buffer *buf = pb_buffer(ws_buf);
+
+ buf->vtbl->unmap(buf);
+}
+
+static void
+pb_winsys_destroy(struct pipe_winsys *winsys,
+ struct pipe_buffer *ws_buf)
+{
+ struct pb_buffer *buf = pb_buffer(ws_buf);
+
+ buf->vtbl->destroy(buf);
+}
+
+
+
+void
+pb_init_winsys(struct pipe_winsys *winsys)
{
- if(*dst != src) {
- if (src)
- src->vtbl->reference(src);
-
- if (*dst)
- (*dst)->vtbl->release(*dst);
-
- *dst = src;
- }
+ winsys->buffer_map = pb_winsys_map;
+ winsys->buffer_unmap = pb_winsys_unmap;
+ winsys->buffer_destroy = pb_winsys_destroy;
}
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer.h b/src/mesa/pipe/pipebuffer/pb_buffer.h
index 0523531395..2f570ef9de 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer.h
+++ b/src/mesa/pipe/pipebuffer/pb_buffer.h
@@ -47,53 +47,57 @@
#include <assert.h>
#include <stdlib.h>
+#include "pipe/p_compiler.h"
-struct pipe_buffer_vtbl;
+#include "pipe/p_state.h"
+struct pb_vtbl;
/**
- * Base class for all pipe buffers.
+ * Buffer description.
+ *
+ * Used when allocating the buffer.
+ */
+struct pb_desc
+{
+ unsigned alignment;
+ unsigned usage;
+};
+
+
+/**
+ * Base class for all pb_* buffers.
*/
-struct pipe_buffer
+struct pb_buffer
{
+ struct pipe_buffer base;
+
/**
* Pointer to the virtual function table.
*
* Avoid accessing this table directly. Use the inline functions below
* instead to avoid mistakes.
*/
- const struct pipe_buffer_vtbl *vtbl;
+ const struct pb_vtbl *vtbl;
};
-
/**
* Virtual function table for the buffer storage operations.
*
* Note that creation is not done through this table.
*/
-struct pipe_buffer_vtbl
+struct pb_vtbl
{
- /**
- * Add a reference to the buffer.
- *
- * This method can be a no-op for buffers that don't need reference
- * counting.
- */
- void (*reference)( struct pipe_buffer *buf );
-
- /**
- * Release a reference to this buffer and destroy it.
- */
- void (*release)( struct pipe_buffer *buf );
+ void (*destroy)( struct pb_buffer *buf );
/**
* Map the entire data store of a buffer object into the client's address.
* flags is bitmask of PIPE_BUFFER_FLAG_READ/WRITE.
*/
- void *(*map)( struct pipe_buffer *buf,
+ void *(*map)( struct pb_buffer *buf,
unsigned flags );
- void (*unmap)( struct pipe_buffer *buf );
+ void (*unmap)( struct pb_buffer *buf );
/**
* Get the base buffer and the offset.
@@ -106,70 +110,87 @@ struct pipe_buffer_vtbl
*
* Note that this will increase the reference count of the base buffer.
*/
- void (*get_base_buffer)( struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+ void (*get_base_buffer)( struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset );
};
-/** *dst = src with reference counting */
-void
-buffer_reference(struct pipe_buffer **dst,
- struct pipe_buffer *src);
-
-
-static inline void
-buffer_release(struct pipe_buffer *buf)
-{
- assert(buf);
- buf->vtbl->release(buf);
-}
-
-
-static inline void *
-buffer_map(struct pipe_buffer *buf,
- unsigned flags)
+/* Accessor functions for pb->vtbl:
+ */
+static INLINE void *
+pb_map(struct pb_buffer *buf,
+ unsigned flags)
{
assert(buf);
return buf->vtbl->map(buf, flags);
}
-static inline void
-buffer_unmap(struct pipe_buffer *buf)
+static INLINE void
+pb_unmap(struct pb_buffer *buf)
{
assert(buf);
buf->vtbl->unmap(buf);
}
-static inline void
-buffer_get_base_buffer( struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
- unsigned *offset )
+static INLINE void
+pb_get_base_buffer( struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
+ unsigned *offset )
{
buf->vtbl->get_base_buffer(buf, base_buf, offset);
}
+static INLINE void
+pb_destroy(struct pb_buffer *buf)
+{
+ assert(buf);
+ buf->vtbl->destroy(buf);
+}
+
-/** Placeholder for empty buffers. */
-extern struct pipe_buffer null_buffer;
/**
- * Client buffers (also designated as user buffers) are just for convenience
- * of the state tracker, so that it can masquerade its own data as a buffer.
+ * User buffers are special buffers that initially reference memory
+ * held by the user but which may if necessary copy that memory into
+ * device memory behind the scenes, for submission to hardware.
+ *
+ * These are particularly useful when the referenced data is never
+ * submitted to hardware at all, in the particular case of software
+ * vertex processing.
*/
-struct pipe_buffer *
-client_buffer_create(void *data);
+struct pb_buffer *
+pb_user_buffer_create(void *data, unsigned bytes);
/**
* Malloc-based buffer to store data that can't be used by the graphics
* hardware.
*/
-struct pipe_buffer *
-malloc_buffer_create(unsigned size);
+struct pb_buffer *
+pb_malloc_buffer_create(size_t size,
+ const struct pb_desc *desc);
+
+
+static INLINE struct pipe_buffer *
+pb_pipe_buffer( struct pb_buffer *pbuf )
+{
+ return &pbuf->base;
+}
+
+static INLINE struct pb_buffer *
+pb_buffer( struct pipe_buffer *buf )
+{
+ /* Could add a magic cookie check on debug builds.
+ */
+ return (struct pb_buffer *)buf;
+}
+
+void
+pb_init_winsys(struct pipe_winsys *winsys);
#endif /*PB_BUFFER_H_*/
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_client.c b/src/mesa/pipe/pipebuffer/pb_buffer_client.c
index bb7f5a9a94..c316aabd32 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer_client.c
+++ b/src/mesa/pipe/pipebuffer/pb_buffer_client.c
@@ -34,61 +34,55 @@
*/
+#include "pipe/p_util.h"
#include "pb_buffer.h"
-struct client_buffer
+struct pb_user_buffer
{
- struct pipe_buffer base;
+ struct pb_buffer base;
void *data;
};
-extern const struct pipe_buffer_vtbl client_buffer_vtbl;
+extern const struct pb_vtbl pb_user_buffer_vtbl;
-static inline struct client_buffer *
-client_buffer(struct pipe_buffer *buf)
+static INLINE struct pb_user_buffer *
+pb_user_buffer(struct pb_buffer *buf)
{
assert(buf);
- assert(buf->vtbl == &client_buffer_vtbl);
- return (struct client_buffer *)buf;
+ assert(buf->vtbl == &pb_user_buffer_vtbl);
+ return (struct pb_user_buffer *)buf;
}
static void
-client_buffer_reference(struct pipe_buffer *buf)
-{
- /* No-op */
-}
-
-
-static void
-client_buffer_release(struct pipe_buffer *buf)
+pb_user_buffer_destroy(struct pb_buffer *buf)
{
assert(buf);
- free(buf);
+ FREE(buf);
}
static void *
-client_buffer_map(struct pipe_buffer *buf,
+pb_user_buffer_map(struct pb_buffer *buf,
unsigned flags)
{
- return client_buffer(buf)->data;
+ return pb_user_buffer(buf)->data;
}
static void
-client_buffer_unmap(struct pipe_buffer *buf)
+pb_user_buffer_unmap(struct pb_buffer *buf)
{
/* No-op */
}
static void
-client_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+pb_user_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset)
{
*base_buf = buf;
@@ -96,27 +90,25 @@ client_buffer_get_base_buffer(struct pipe_buffer *buf,
}
-const struct pipe_buffer_vtbl
-client_buffer_vtbl = {
- client_buffer_reference,
- client_buffer_release,
- client_buffer_map,
- client_buffer_unmap,
- client_buffer_get_base_buffer
+const struct pb_vtbl
+pb_user_buffer_vtbl = {
+ pb_user_buffer_destroy,
+ pb_user_buffer_map,
+ pb_user_buffer_unmap,
+ pb_user_buffer_get_base_buffer
};
-struct pipe_buffer *
-client_buffer_create(void *data)
+struct pb_buffer *
+pb_user_buffer_create(void *data, unsigned bytes)
{
- struct client_buffer *buf;
-
- buf = (struct client_buffer *)malloc(sizeof(struct client_buffer));
+ struct pb_user_buffer *buf = CALLOC_STRUCT(pb_user_buffer);
+
if(!buf)
return NULL;
- buf->base.vtbl = &client_buffer_vtbl;
-
+ buf->base.vtbl = &pb_user_buffer_vtbl;
+ buf->base.base.size = bytes;
buf->data = data;
return &buf->base;
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_fenced.c b/src/mesa/pipe/pipebuffer/pb_buffer_fenced.c
index dfb80b1dcf..b2edc321ef 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer_fenced.c
+++ b/src/mesa/pipe/pipebuffer/pb_buffer_fenced.c
@@ -36,17 +36,21 @@
#include <assert.h>
#include <stdlib.h>
-#include <unistd.h>
-#include "main/imports.h"
-#include "glapi/glthread.h"
#include "linked_list.h"
+#include "p_compiler.h"
#include "p_winsys.h"
+#include "p_thread.h"
+#include "p_util.h"
#include "pb_buffer.h"
#include "pb_buffer_fenced.h"
+#ifndef __MSC__
+#include <unistd.h>
+#endif
+
/**
* Convenience macro (type safe).
@@ -72,9 +76,9 @@ struct fenced_buffer_list
*/
struct fenced_buffer
{
- struct pipe_buffer base;
+ struct pb_buffer base;
- struct pipe_buffer *buffer;
+ struct pb_buffer *buffer;
unsigned refcount;
struct pipe_fence_handle *fence;
@@ -84,8 +88,8 @@ struct fenced_buffer
};
-static inline struct fenced_buffer *
-fenced_buffer(struct pipe_buffer *buf)
+static INLINE struct fenced_buffer *
+fenced_buffer(struct pb_buffer *buf)
{
assert(buf);
assert(buf->vtbl == &fenced_buffer_vtbl);
@@ -93,12 +97,6 @@ fenced_buffer(struct pipe_buffer *buf)
}
-static void
-_fenced_buffer_destroy(struct fenced_buffer *fenced_buf)
-{
- buffer_release(fenced_buf->buffer);
- free(fenced_buf);
-}
static void
@@ -109,11 +107,12 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
struct fenced_buffer *fenced_buf;
struct list_head *list, *prev;
int signaled = -1;
- int i;
list = fenced_list->delayed.next;
if (fenced_list->numDelayed > 3) {
+ unsigned i;
+
for (i = 0; i < fenced_list->numDelayed; i += 3) {
list = list->next;
}
@@ -143,97 +142,81 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
LIST_DEL(list);
fenced_list->numDelayed--;
-
- _fenced_buffer_destroy(fenced_buf);
- }
-}
-
-
-static void
-fenced_buffer_reference(struct pipe_buffer *buf)
-{
- struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- struct fenced_buffer_list *fenced_list = fenced_buf->list;
- _glthread_LOCK_MUTEX(fenced_list->mutex);
- fenced_buf->refcount++;
- _glthread_UNLOCK_MUTEX(fenced_list->mutex);
+ /* Do the delayed destroy:
+ */
+ pb_destroy(fenced_buf->buffer);
+ free(fenced_buf);
+ }
}
static void
-fenced_buffer_release(struct pipe_buffer *buf)
+fenced_buffer_destroy(struct pb_buffer *buf)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
struct fenced_buffer_list *fenced_list = fenced_buf->list;
- _glthread_LOCK_MUTEX(fenced_list->mutex);
-
- fenced_buf->refcount--;
- if(!fenced_buf->refcount) {
- if (fenced_buf->fence) {
- LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed);
- fenced_list->numDelayed++;
- }
- else {
- _fenced_buffer_destroy(fenced_buf);
- }
-
- if ((fenced_list->numDelayed % fenced_list->checkDelayed) == 0)
- _fenced_buffer_list_check_free(fenced_list, 0);
+ if (fenced_buf->fence) {
+ LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed);
+ fenced_list->numDelayed++;
+ }
+ else {
+ pb_destroy(fenced_buf->buffer);
+ free(fenced_buf);
}
- _glthread_UNLOCK_MUTEX(fenced_list->mutex);
+ if ((fenced_list->numDelayed % fenced_list->checkDelayed) == 0)
+ _fenced_buffer_list_check_free(fenced_list, 0);
}
static void *
-fenced_buffer_map(struct pipe_buffer *buf,
+fenced_buffer_map(struct pb_buffer *buf,
unsigned flags)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- return buffer_map(fenced_buf->buffer, flags);
+ return pb_map(fenced_buf->buffer, flags);
}
static void
-fenced_buffer_unmap(struct pipe_buffer *buf)
+fenced_buffer_unmap(struct pb_buffer *buf)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- buffer_unmap(fenced_buf->buffer);
+ pb_unmap(fenced_buf->buffer);
}
static void
-fenced_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+fenced_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- buffer_get_base_buffer(fenced_buf->buffer, base_buf, offset);
+ pb_get_base_buffer(fenced_buf->buffer, base_buf, offset);
}
-const struct pipe_buffer_vtbl
+const struct pb_vtbl
fenced_buffer_vtbl = {
- fenced_buffer_reference,
- fenced_buffer_release,
+ fenced_buffer_destroy,
fenced_buffer_map,
fenced_buffer_unmap,
fenced_buffer_get_base_buffer
};
-struct pipe_buffer *
+struct pb_buffer *
fenced_buffer_create(struct fenced_buffer_list *fenced_list,
- struct pipe_buffer *buffer)
+ struct pb_buffer *buffer)
{
struct fenced_buffer *buf;
if(!buffer)
return NULL;
- buf = (struct fenced_buffer *)calloc(1, sizeof(struct fenced_buffer));
+ buf = CALLOC_STRUCT(fenced_buffer);
if(!buf)
return NULL;
@@ -247,20 +230,16 @@ fenced_buffer_create(struct fenced_buffer_list *fenced_list,
void
-buffer_fence(struct pipe_buffer *buf,
+buffer_fence(struct pb_buffer *buf,
struct pipe_fence_handle *fence)
{
- if(buf->vtbl == &fenced_buffer_vtbl) {
- struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- struct fenced_buffer_list *fenced_list = fenced_buf->list;
- struct pipe_winsys *winsys = fenced_list->winsys;
+ struct fenced_buffer *fenced_buf = fenced_buffer(buf);
+ struct fenced_buffer_list *fenced_list = fenced_buf->list;
+ struct pipe_winsys *winsys = fenced_list->winsys;
- _glthread_LOCK_MUTEX(fenced_list->mutex);
- winsys->fence_reference(winsys, &fenced_buf->fence, fence);
- _glthread_UNLOCK_MUTEX(fenced_list->mutex);
- }
- else
- assert(0);
+ _glthread_LOCK_MUTEX(fenced_list->mutex);
+ winsys->fence_reference(winsys, &fenced_buf->fence, fence);
+ _glthread_UNLOCK_MUTEX(fenced_list->mutex);
}
@@ -269,7 +248,7 @@ fenced_buffer_list_create(struct pipe_winsys *winsys)
{
struct fenced_buffer_list *fenced_list;
- fenced_list = (struct fenced_buffer_list *)calloc(1, sizeof(*fenced_list));
+ fenced_list = (struct fenced_buffer_list *)CALLOC(1, sizeof(*fenced_list));
if (!fenced_list)
return NULL;
@@ -307,13 +286,13 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list)
while (fenced_list->numDelayed) {
_glthread_UNLOCK_MUTEX(fenced_list->mutex);
sched_yield();
- _fenced_buffer_list_check_free(fenced_list, GL_TRUE);
+ _fenced_buffer_list_check_free(fenced_list, 1);
_glthread_LOCK_MUTEX(fenced_list->mutex);
}
_glthread_UNLOCK_MUTEX(fenced_list->mutex);
- free(fenced_list);
+ FREE(fenced_list);
}
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_fenced.h b/src/mesa/pipe/pipebuffer/pb_buffer_fenced.h
index 07e42a67f8..09082a5390 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer_fenced.h
+++ b/src/mesa/pipe/pipebuffer/pb_buffer_fenced.h
@@ -70,7 +70,7 @@ struct fenced_buffer_list;
*
* NOTE: Made public for debugging purposes.
*/
-extern const struct pipe_buffer_vtbl fenced_buffer_vtbl;
+extern const struct pb_vtbl fenced_buffer_vtbl;
/**
@@ -98,19 +98,19 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list);
*
* NOTE: this will not increase the buffer reference count.
*/
-struct pipe_buffer *
+struct pb_buffer *
fenced_buffer_create(struct fenced_buffer_list *fenced,
- struct pipe_buffer *buffer);
+ struct pb_buffer *buffer);
/**
* Set a buffer's fence.
*
- * NOTE: Although it takes a generic pipe buffer argument, it will fail
+ * NOTE: Although it takes a generic pb_buffer argument, it will fail
* on everything but buffers returned by fenced_buffer_create.
*/
void
-buffer_fence(struct pipe_buffer *buf,
+buffer_fence(struct pb_buffer *buf,
struct pipe_fence_handle *fence);
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_handle.c b/src/mesa/pipe/pipebuffer/pb_buffer_handle.c
deleted file mode 100644
index 5a5eaee7ac..0000000000
--- a/src/mesa/pipe/pipebuffer/pb_buffer_handle.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * \file
- * Drop-in implementation of the winsys driver functions for buffer handles.
- *
- * \author José Fonseca <jrfonseca@tungstengraphics.com>
- */
-
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "pipe/p_winsys.h"
-#include "pipe/p_defines.h"
-
-#include "pb_buffer.h"
-#include "pb_buffer_handle.h"
-
-
-static struct pipe_buffer_handle *
-buffer_handle_create(struct pipe_winsys *winsys,
- unsigned alignment,
- unsigned flags,
- unsigned hint)
-{
- struct pipe_buffer_handle *handle;
-
- handle = (struct pipe_buffer_handle *)malloc(sizeof(struct pipe_buffer_handle));
- if(!handle)
- return NULL;
-
- handle->refcount = 1;
- handle->alignment = alignment;
- handle->flags = flags;
- handle->hint = hint;
-
- handle->buf = &null_buffer;
-
- return handle;
-}
-
-
-static struct pipe_buffer_handle *
-buffer_handle_create_user(struct pipe_winsys *winsys,
- void *data, unsigned size)
-{
- struct pipe_buffer_handle *handle;
- struct pipe_buffer *buf;
-
- handle = buffer_handle_create(winsys, 1, 0, 0);
- if(!handle)
- return NULL;
-
- buf = client_buffer_create(data);
- if(!buf) {
- free(handle);
- return NULL;
- }
-
- buffer_handle_data(handle, buf);
-
- return handle;
-}
-
-
-static void *
-buffer_handle_map(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *handle,
- unsigned flags)
-{
- return buffer_map(handle->buf, flags);
-}
-
-
-static void
-buffer_handle_unmap(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *handle)
-{
- buffer_unmap(handle->buf);
-}
-
-
-static void
-buffer_handle_reference(struct pipe_winsys *winsys,
- struct pipe_buffer_handle **dst,
- struct pipe_buffer_handle *src)
-{
- /* XXX: should this be thread safe? */
-
- if (src) {
- src->refcount++;
- }
-
- if (*dst) {
- (*dst)->refcount--;
- if ((*dst)->refcount == 0) {
- buffer_release((*dst)->buf);
- free(*dst);
- }
- }
-
- *dst = src;
-}
-
-
-static int
-buffer_handle_subdata(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *handle,
- unsigned long offset,
- unsigned long size,
- const void *data)
-{
- void *map;
- assert(handle);
- assert(data);
- map = buffer_handle_map(winsys, handle, PIPE_BUFFER_FLAG_WRITE);
- if(map) {
- memcpy((char *)map + offset, data, size);
- buffer_handle_unmap(winsys, handle);
- return 0;
- }
- return -1;
-}
-
-
-static int
-buffer_handle_get_subdata(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *handle,
- unsigned long offset,
- unsigned long size,
- void *data)
-{
- void *map;
- assert(handle);
- assert(data);
- map = buffer_handle_map(winsys, handle, PIPE_BUFFER_FLAG_READ);
- if(map) {
- memcpy(data, (char *)map + offset, size);
- buffer_handle_unmap(winsys, handle);
- return 0;
- }
- return -1;
-}
-
-
-void
-buffer_handle_init_winsys(struct pipe_winsys *winsys)
-{
- winsys->buffer_create = buffer_handle_create;
- winsys->user_buffer_create = buffer_handle_create_user;
- winsys->buffer_map = buffer_handle_map;
- winsys->buffer_unmap = buffer_handle_unmap;
- winsys->buffer_reference = buffer_handle_reference;
- winsys->buffer_subdata = buffer_handle_subdata;
- winsys->buffer_get_subdata = buffer_handle_get_subdata;
-}
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_handle.h b/src/mesa/pipe/pipebuffer/pb_buffer_handle.h
deleted file mode 100644
index 076eec2fdc..0000000000
--- a/src/mesa/pipe/pipebuffer/pb_buffer_handle.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * \file
- * Buffer handle interface.
- *
- * \author José Fonseca <jrfonseca@tungstengraphics.com>
- */
-
-#ifndef PB_BUFFER_HANDLE_H_
-#define PB_BUFFER_HANDLE_H_
-
-
-#include <assert.h>
-
-#include "pb_buffer.h"
-
-
-/**
- * Buffer handle.
- *
- * The buffer handle and the buffer data storage are separate entities. This
- * is modelled after ARB_vertex_buffer_object, which is the interface that
- * Gallium requires. See p_winsys.h for more information.
- */
-struct pipe_buffer_handle
-{
- /** Reference count */
- unsigned refcount;
-
- /** Allocation characteristics */
- unsigned alignment;
- unsigned flags;
- unsigned hint;
-
- /**
- * The actual buffer.
- *
- * It should never be NULL. Use null_buffer instead.
- */
- struct pipe_buffer *buf;
-};
-
-
-/**
- * Set buffer storage.
- *
- * NOTE: this will not increase the buffer reference count.
- */
-static inline void
-buffer_handle_data(struct pipe_buffer_handle *handle,
- struct pipe_buffer *buf)
-{
- assert(handle);
- assert(handle->buf);
- buffer_release(handle->buf);
- assert(buf);
- handle->buf = buf;
-}
-
-
-static inline void
-buffer_handle_clear(struct pipe_buffer_handle *handle)
-{
- buffer_handle_data(handle, &null_buffer);
-}
-
-
-static inline int
-buffer_handle_has_data(struct pipe_buffer_handle *handle) {
- assert(handle);
- assert(handle->buf);
- return handle->buf != &null_buffer;
-}
-
-
-/**
- * Fill in the pipe_winsys' buffer-related callbacks.
- *
- * Specifically, the fullfilled functions are:
- * - buffer_create
- * - user_buffer_create
- * - buffer_map
- * - buffer_unmap
- * - buffer_reference
- * - buffer_subdata
- * - buffer_get_subdata
- *
- * NOTE: buffer_data is left untouched.
- */
-void
-buffer_handle_init_winsys(struct pipe_winsys *winsys);
-
-
-#endif /*PB_BUFFER_HANDLE_H_*/
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_malloc.c b/src/mesa/pipe/pipebuffer/pb_buffer_malloc.c
index 65ad51e1e7..f0ff1d347e 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer_malloc.c
+++ b/src/mesa/pipe/pipebuffer/pb_buffer_malloc.c
@@ -37,20 +37,21 @@
#include <assert.h>
#include <stdlib.h>
+#include "pipe/p_util.h"
#include "pb_buffer.h"
struct malloc_buffer
{
- struct pipe_buffer base;
+ struct pb_buffer base;
void *data;
};
-extern const struct pipe_buffer_vtbl malloc_buffer_vtbl;
+extern const struct pb_vtbl malloc_buffer_vtbl;
-static inline struct malloc_buffer *
-malloc_buffer(struct pipe_buffer *buf)
+static INLINE struct malloc_buffer *
+malloc_buffer(struct pb_buffer *buf)
{
assert(buf);
assert(buf->vtbl == &malloc_buffer_vtbl);
@@ -59,22 +60,15 @@ malloc_buffer(struct pipe_buffer *buf)
static void
-malloc_buffer_reference(struct pipe_buffer *buf)
+malloc_buffer_destroy(struct pb_buffer *buf)
{
- /* no-op */
-}
-
-
-static void
-malloc_buffer_release(struct pipe_buffer *buf)
-{
- free(malloc_buffer(buf)->data);
- free(buf);
+ align_free(malloc_buffer(buf)->data);
+ FREE(buf);
}
static void *
-malloc_buffer_map(struct pipe_buffer *buf,
+malloc_buffer_map(struct pb_buffer *buf,
unsigned flags)
{
return malloc_buffer(buf)->data;
@@ -82,15 +76,15 @@ malloc_buffer_map(struct pipe_buffer *buf,
static void
-malloc_buffer_unmap(struct pipe_buffer *buf)
+malloc_buffer_unmap(struct pb_buffer *buf)
{
/* No-op */
}
static void
-malloc_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+malloc_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset)
{
*base_buf = buf;
@@ -98,33 +92,36 @@ malloc_buffer_get_base_buffer(struct pipe_buffer *buf,
}
-const struct pipe_buffer_vtbl
+const struct pb_vtbl
malloc_buffer_vtbl = {
- malloc_buffer_reference,
- malloc_buffer_release,
+ malloc_buffer_destroy,
malloc_buffer_map,
malloc_buffer_unmap,
malloc_buffer_get_base_buffer
};
-struct pipe_buffer *
-malloc_buffer_create(unsigned size)
+struct pb_buffer *
+pb_malloc_buffer_create(size_t size,
+ const struct pb_desc *desc)
{
struct malloc_buffer *buf;
/* TODO: accept an alignment parameter */
/* TODO: do a single allocation */
- buf = (struct malloc_buffer *)malloc(sizeof(struct malloc_buffer));
+ buf = (struct malloc_buffer *)MALLOC(sizeof(struct malloc_buffer));
if(!buf)
return NULL;
buf->base.vtbl = &malloc_buffer_vtbl;
-
- buf->data = malloc(size);
+ buf->base.base.alignment = desc->alignment;
+ buf->base.base.usage = desc->usage;
+ buf->base.base.size = size;
+
+ buf->data = align_malloc(size, desc->alignment < sizeof(void*) ? sizeof(void*) : desc->alignment);
if(!buf->data) {
- free(buf);
+ FREE(buf);
return NULL;
}
diff --git a/src/mesa/pipe/pipebuffer/pb_bufmgr.h b/src/mesa/pipe/pipebuffer/pb_bufmgr.h
index 12e36323a8..1ddf784c97 100644
--- a/src/mesa/pipe/pipebuffer/pb_bufmgr.h
+++ b/src/mesa/pipe/pipebuffer/pb_bufmgr.h
@@ -53,6 +53,7 @@
#include <stddef.h>
+struct pb_desc;
struct pipe_buffer;
struct pipe_winsys;
@@ -60,15 +61,16 @@ struct pipe_winsys;
/**
* Abstract base class for all buffer managers.
*/
-struct buffer_manager
+struct pb_manager
{
/* XXX: we will likely need more allocation flags */
- struct pipe_buffer *
- (*create_buffer)( struct buffer_manager *mgr,
- size_t size );
+ struct pb_buffer *
+ (*create_buffer)( struct pb_manager *mgr,
+ size_t size,
+ const struct pb_desc *desc);
void
- (*destroy)( struct buffer_manager *mgr );
+ (*destroy)( struct pb_manager *mgr );
};
@@ -80,9 +82,10 @@ struct buffer_manager
*
* It is meant to manage the allocation of batch buffer pools.
*/
-struct buffer_manager *
-pool_bufmgr_create(struct buffer_manager *provider,
- size_t n, size_t size);
+struct pb_manager *
+pool_bufmgr_create(struct pb_manager *provider,
+ size_t n, size_t size,
+ const struct pb_desc *desc);
/**
@@ -92,8 +95,8 @@ pool_bufmgr_create(struct buffer_manager *provider,
* with the size of the heap, and then using the old mm memory manager to manage
* that heap.
*/
-struct buffer_manager *
-mm_bufmgr_create(struct buffer_manager *provider,
+struct pb_manager *
+mm_bufmgr_create(struct pb_manager *provider,
size_t size, size_t align2);
/**
@@ -101,8 +104,8 @@ mm_bufmgr_create(struct buffer_manager *provider,
*
* Buffer will be release when the manager is destroyed.
*/
-struct buffer_manager *
-mm_bufmgr_create_from_buffer(struct pipe_buffer *buffer,
+struct pb_manager *
+mm_bufmgr_create_from_buffer(struct pb_buffer *buffer,
size_t size, size_t align2);
@@ -115,8 +118,8 @@ mm_bufmgr_create_from_buffer(struct pipe_buffer *buffer,
* NOTE: the buffer manager that provides the buffers will be destroyed
* at the same time.
*/
-struct buffer_manager *
-fenced_bufmgr_create(struct buffer_manager *provider,
+struct pb_manager *
+fenced_bufmgr_create(struct pb_manager *provider,
struct pipe_winsys *winsys);
diff --git a/src/mesa/pipe/pipebuffer/pb_bufmgr_fenced.c b/src/mesa/pipe/pipebuffer/pb_bufmgr_fenced.c
index defd8e4df7..6a81cbdae0 100644
--- a/src/mesa/pipe/pipebuffer/pb_bufmgr_fenced.c
+++ b/src/mesa/pipe/pipebuffer/pb_bufmgr_fenced.c
@@ -37,45 +37,49 @@
#include <assert.h>
#include <stdlib.h>
+#include "p_util.h"
+
#include "pb_buffer.h"
#include "pb_buffer_fenced.h"
#include "pb_bufmgr.h"
-struct fenced_buffer_manager
+struct fenced_pb_manager
{
- struct buffer_manager base;
+ struct pb_manager base;
- struct buffer_manager *provider;
+ struct pb_manager *provider;
struct fenced_buffer_list *fenced_list;
};
-static inline struct fenced_buffer_manager *
-fenced_buffer_manager(struct buffer_manager *mgr)
+static INLINE struct fenced_pb_manager *
+fenced_pb_manager(struct pb_manager *mgr)
{
assert(mgr);
- return (struct fenced_buffer_manager *)mgr;
+ return (struct fenced_pb_manager *)mgr;
}
-static struct pipe_buffer *
-fenced_bufmgr_create_buffer(struct buffer_manager *mgr, size_t size)
+static struct pb_buffer *
+fenced_bufmgr_create_buffer(struct pb_manager *mgr,
+ size_t size,
+ const struct pb_desc *desc)
{
- struct fenced_buffer_manager *fenced_mgr = fenced_buffer_manager(mgr);
- struct pipe_buffer *buf;
- struct pipe_buffer *fenced_buf;
+ struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr);
+ struct pb_buffer *buf;
+ struct pb_buffer *fenced_buf;
/* check for free buffers before allocating new ones */
fenced_buffer_list_check_free(fenced_mgr->fenced_list, 0);
- buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size);
+ buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc);
if(!buf) {
/* try harder to get a buffer */
fenced_buffer_list_check_free(fenced_mgr->fenced_list, 1);
- buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size);
+ buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc);
if(!buf) {
/* give up */
return NULL;
@@ -84,7 +88,7 @@ fenced_bufmgr_create_buffer(struct buffer_manager *mgr, size_t size)
fenced_buf = fenced_buffer_create(fenced_mgr->fenced_list, buf);
if(!fenced_buf) {
- buffer_release(buf);
+ pb_destroy(buf);
}
return fenced_buf;
@@ -92,25 +96,25 @@ fenced_bufmgr_create_buffer(struct buffer_manager *mgr, size_t size)
static void
-fenced_bufmgr_destroy(struct buffer_manager *mgr)
+fenced_bufmgr_destroy(struct pb_manager *mgr)
{
- struct fenced_buffer_manager *fenced_mgr = fenced_buffer_manager(mgr);
+ struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr);
fenced_buffer_list_destroy(fenced_mgr->fenced_list);
fenced_mgr->provider->destroy(fenced_mgr->provider);
- free(fenced_mgr);
+ FREE(fenced_mgr);
}
-struct buffer_manager *
-fenced_bufmgr_create(struct buffer_manager *provider,
+struct pb_manager *
+fenced_bufmgr_create(struct pb_manager *provider,
struct pipe_winsys *winsys)
{
- struct fenced_buffer_manager *fenced_mgr;
+ struct fenced_pb_manager *fenced_mgr;
- fenced_mgr = (struct fenced_buffer_manager *)calloc(1, sizeof(*fenced_mgr));
+ fenced_mgr = (struct fenced_pb_manager *)CALLOC(1, sizeof(*fenced_mgr));
if (!fenced_mgr)
return NULL;
@@ -120,7 +124,7 @@ fenced_bufmgr_create(struct buffer_manager *provider,
fenced_mgr->provider = provider;
fenced_mgr->fenced_list = fenced_buffer_list_create(winsys);
if(!fenced_mgr->fenced_list) {
- free(fenced_mgr);
+ FREE(fenced_mgr);
return NULL;
}
diff --git a/src/mesa/pipe/pipebuffer/pb_bufmgr_mm.c b/src/mesa/pipe/pipebuffer/pb_bufmgr_mm.c
index e9bc34b4a4..2a62702c36 100644
--- a/src/mesa/pipe/pipebuffer/pb_bufmgr_mm.c
+++ b/src/mesa/pipe/pipebuffer/pb_bufmgr_mm.c
@@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 1999 Wittawat Yamwong
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -34,15 +35,12 @@
#include <assert.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "main/imports.h"
-#include "glapi/glthread.h"
-#include "main/mm.h"
#include "linked_list.h"
#include "p_defines.h"
+#include "p_thread.h"
+#include "p_util.h"
#include "pb_buffer.h"
#include "pb_bufmgr.h"
@@ -53,9 +51,309 @@
#define SUPER(__derived) (&(__derived)->base)
-struct mm_buffer_manager
+struct mem_block
{
- struct buffer_manager base;
+ struct mem_block *next, *prev;
+ struct mem_block *next_free, *prev_free;
+ struct mem_block *heap;
+ int ofs, size;
+ unsigned int free:1;
+ unsigned int reserved:1;
+};
+
+
+#ifdef DEBUG
+/**
+ * For debugging purposes.
+ */
+static void
+mmDumpMemInfo(const struct mem_block *heap)
+{
+ fprintf(stderr, "Memory heap %p:\n", (void *)heap);
+ if (heap == 0) {
+ fprintf(stderr, " heap == 0\n");
+ } else {
+ const struct mem_block *p;
+
+ for(p = heap->next; p != heap; p = p->next) {
+ fprintf(stderr, " Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
+ p->free ? 'F':'.',
+ p->reserved ? 'R':'.');
+ }
+
+ fprintf(stderr, "\nFree list:\n");
+
+ for(p = heap->next_free; p != heap; p = p->next_free) {
+ fprintf(stderr, " FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
+ p->free ? 'F':'.',
+ p->reserved ? 'R':'.');
+ }
+
+ }
+ fprintf(stderr, "End of memory blocks\n");
+}
+#endif
+
+
+/**
+ * input: total size in bytes
+ * return: a heap pointer if OK, NULL if error
+ */
+static struct mem_block *
+mmInit(int ofs, int size)
+{
+ struct mem_block *heap, *block;
+
+ if (size <= 0)
+ return NULL;
+
+ heap = CALLOC_STRUCT(mem_block);
+ if (!heap)
+ return NULL;
+
+ block = CALLOC_STRUCT(mem_block);
+ if (!block) {
+ FREE(heap);
+ return NULL;
+ }
+
+ heap->next = block;
+ heap->prev = block;
+ heap->next_free = block;
+ heap->prev_free = block;
+
+ block->heap = heap;
+ block->next = heap;
+ block->prev = heap;
+ block->next_free = heap;
+ block->prev_free = heap;
+
+ block->ofs = ofs;
+ block->size = size;
+ block->free = 1;
+
+ return heap;
+}
+
+
+static struct mem_block *
+SliceBlock(struct mem_block *p,
+ int startofs, int size,
+ int reserved, int alignment)
+{
+ struct mem_block *newblock;
+
+ /* break left [p, newblock, p->next], then p = newblock */
+ if (startofs > p->ofs) {
+ newblock = CALLOC_STRUCT(mem_block);
+ if (!newblock)
+ return NULL;
+ newblock->ofs = startofs;
+ newblock->size = p->size - (startofs - p->ofs);
+ newblock->free = 1;
+ newblock->heap = p->heap;
+
+ newblock->next = p->next;
+ newblock->prev = p;
+ p->next->prev = newblock;
+ p->next = newblock;
+
+ newblock->next_free = p->next_free;
+ newblock->prev_free = p;
+ p->next_free->prev_free = newblock;
+ p->next_free = newblock;
+
+ p->size -= newblock->size;
+ p = newblock;
+ }
+
+ /* break right, also [p, newblock, p->next] */
+ if (size < p->size) {
+ newblock = CALLOC_STRUCT(mem_block);
+ if (!newblock)
+ return NULL;
+ newblock->ofs = startofs + size;
+ newblock->size = p->size - size;
+ newblock->free = 1;
+ newblock->heap = p->heap;
+
+ newblock->next = p->next;
+ newblock->prev = p;
+ p->next->prev = newblock;
+ p->next = newblock;
+
+ newblock->next_free = p->next_free;
+ newblock->prev_free = p;
+ p->next_free->prev_free = newblock;
+ p->next_free = newblock;
+
+ p->size = size;
+ }
+
+ /* p = middle block */
+ p->free = 0;
+
+ /* Remove p from the free list:
+ */
+ p->next_free->prev_free = p->prev_free;
+ p->prev_free->next_free = p->next_free;
+
+ p->next_free = 0;
+ p->prev_free = 0;
+
+ p->reserved = reserved;
+ return p;
+}
+
+
+/**
+ * Allocate 'size' bytes with 2^align2 bytes alignment,
+ * restrict the search to free memory after 'startSearch'
+ * depth and back buffers should be in different 4mb banks
+ * to get better page hits if possible
+ * input: size = size of block
+ * align2 = 2^align2 bytes alignment
+ * startSearch = linear offset from start of heap to begin search
+ * return: pointer to the allocated block, 0 if error
+ */
+static struct mem_block *
+mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch)
+{
+ struct mem_block *p;
+ const int mask = (1 << align2)-1;
+ int startofs = 0;
+ int endofs;
+
+ if (!heap || align2 < 0 || size <= 0)
+ return NULL;
+
+ for (p = heap->next_free; p != heap; p = p->next_free) {
+ assert(p->free);
+
+ startofs = (p->ofs + mask) & ~mask;
+ if ( startofs < startSearch ) {
+ startofs = startSearch;
+ }
+ endofs = startofs+size;
+ if (endofs <= (p->ofs+p->size))
+ break;
+ }
+
+ if (p == heap)
+ return NULL;
+
+ assert(p->free);
+ p = SliceBlock(p,startofs,size,0,mask+1);
+
+ return p;
+}
+
+
+#if 0
+/**
+ * Free block starts at offset
+ * input: pointer to a heap, start offset
+ * return: pointer to a block
+ */
+static struct mem_block *
+mmFindBlock(struct mem_block *heap, int start)
+{
+ struct mem_block *p;
+
+ for (p = heap->next; p != heap; p = p->next) {
+ if (p->ofs == start)
+ return p;
+ }
+
+ return NULL;
+}
+#endif
+
+
+static INLINE int
+Join2Blocks(struct mem_block *p)
+{
+ /* XXX there should be some assertions here */
+
+ /* NOTE: heap->free == 0 */
+
+ if (p->free && p->next->free) {
+ struct mem_block *q = p->next;
+
+ assert(p->ofs + p->size == q->ofs);
+ p->size += q->size;
+
+ p->next = q->next;
+ q->next->prev = p;
+
+ q->next_free->prev_free = q->prev_free;
+ q->prev_free->next_free = q->next_free;
+
+ FREE(q);
+ return 1;
+ }
+ return 0;
+}
+
+
+/**
+ * Free block starts at offset
+ * input: pointer to a block
+ * return: 0 if OK, -1 if error
+ */
+static int
+mmFreeMem(struct mem_block *b)
+{
+ if (!b)
+ return 0;
+
+ if (b->free) {
+ fprintf(stderr, "block already free\n");
+ return -1;
+ }
+ if (b->reserved) {
+ fprintf(stderr, "block is reserved\n");
+ return -1;
+ }
+
+ b->free = 1;
+ b->next_free = b->heap->next_free;
+ b->prev_free = b->heap;
+ b->next_free->prev_free = b;
+ b->prev_free->next_free = b;
+
+ Join2Blocks(b);
+ if (b->prev != b->heap)
+ Join2Blocks(b->prev);
+
+ return 0;
+}
+
+
+/**
+ * destroy MM
+ */
+static void
+mmDestroy(struct mem_block *heap)
+{
+ struct mem_block *p;
+
+ if (!heap)
+ return;
+
+ for (p = heap->next; p != heap; ) {
+ struct mem_block *next = p->next;
+ FREE(p);
+ p = next;
+ }
+
+ FREE(heap);
+}
+
+
+struct mm_pb_manager
+{
+ struct pb_manager base;
_glthread_Mutex mutex;
@@ -64,31 +362,31 @@ struct mm_buffer_manager
size_t align2;
- struct pipe_buffer *buffer;
+ struct pb_buffer *buffer;
void *map;
};
-static inline struct mm_buffer_manager *
-mm_buffer_manager(struct buffer_manager *mgr)
+static inline struct mm_pb_manager *
+mm_pb_manager(struct pb_manager *mgr)
{
assert(mgr);
- return (struct mm_buffer_manager *)mgr;
+ return (struct mm_pb_manager *)mgr;
}
struct mm_buffer
{
- struct pipe_buffer base;
+ struct pb_buffer base;
- struct mm_buffer_manager *mgr;
+ struct mm_pb_manager *mgr;
struct mem_block *block;
};
static inline struct mm_buffer *
-mm_buffer(struct pipe_buffer *buf)
+mm_buffer(struct pb_buffer *buf)
{
assert(buf);
return (struct mm_buffer *)buf;
@@ -96,75 +394,73 @@ mm_buffer(struct pipe_buffer *buf)
static void
-mm_buffer_reference(struct pipe_buffer *buf)
-{
- /* No-op */
-}
-
-
-static void
-mm_buffer_release(struct pipe_buffer *buf)
+mm_buffer_destroy(struct pb_buffer *buf)
{
struct mm_buffer *mm_buf = mm_buffer(buf);
- struct mm_buffer_manager *mm = mm_buf->mgr;
+ struct mm_pb_manager *mm = mm_buf->mgr;
_glthread_LOCK_MUTEX(mm->mutex);
mmFreeMem(mm_buf->block);
- free(buf);
+ FREE(buf);
_glthread_UNLOCK_MUTEX(mm->mutex);
}
static void *
-mm_buffer_map(struct pipe_buffer *buf,
+mm_buffer_map(struct pb_buffer *buf,
unsigned flags)
{
struct mm_buffer *mm_buf = mm_buffer(buf);
- struct mm_buffer_manager *mm = mm_buf->mgr;
+ struct mm_pb_manager *mm = mm_buf->mgr;
return (unsigned char *) mm->map + mm_buf->block->ofs;
}
static void
-mm_buffer_unmap(struct pipe_buffer *buf)
+mm_buffer_unmap(struct pb_buffer *buf)
{
/* No-op */
}
static void
-mm_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+mm_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset)
{
struct mm_buffer *mm_buf = mm_buffer(buf);
- struct mm_buffer_manager *mm = mm_buf->mgr;
- buffer_get_base_buffer(mm->buffer, base_buf, offset);
+ struct mm_pb_manager *mm = mm_buf->mgr;
+ pb_get_base_buffer(mm->buffer, base_buf, offset);
*offset += mm_buf->block->ofs;
}
-static const struct pipe_buffer_vtbl
+static const struct pb_vtbl
mm_buffer_vtbl = {
- mm_buffer_reference,
- mm_buffer_release,
+ mm_buffer_destroy,
mm_buffer_map,
mm_buffer_unmap,
mm_buffer_get_base_buffer
};
-static struct pipe_buffer *
-mm_bufmgr_create_buffer(struct buffer_manager *mgr,
- size_t size)
+static struct pb_buffer *
+mm_bufmgr_create_buffer(struct pb_manager *mgr,
+ size_t size,
+ const struct pb_desc *desc)
{
- struct mm_buffer_manager *mm = mm_buffer_manager(mgr);
+ struct mm_pb_manager *mm = mm_pb_manager(mgr);
struct mm_buffer *mm_buf;
+ /* We don't handle alignments larger then the one initially setup */
+ assert(desc->alignment % (1 << mm->align2) == 0);
+ if(desc->alignment % (1 << mm->align2))
+ return NULL;
+
_glthread_LOCK_MUTEX(mm->mutex);
- mm_buf = (struct mm_buffer *)malloc(sizeof(*mm_buf));
+ mm_buf = CALLOC_STRUCT(mm_buffer);
if (!mm_buf) {
_glthread_UNLOCK_MUTEX(mm->mutex);
return NULL;
@@ -184,7 +480,7 @@ mm_bufmgr_create_buffer(struct buffer_manager *mgr,
mm_buf->block = mmAllocMem(mm->heap, size, mm->align2, 0);
if(!mm_buf->block) {
assert(0);
- free(mm_buf);
+ FREE(mm_buf);
_glthread_UNLOCK_MUTEX(mm->mutex);
return NULL;
}
@@ -200,33 +496,33 @@ mm_bufmgr_create_buffer(struct buffer_manager *mgr,
static void
-mm_bufmgr_destroy(struct buffer_manager *mgr)
+mm_bufmgr_destroy(struct pb_manager *mgr)
{
- struct mm_buffer_manager *mm = mm_buffer_manager(mgr);
+ struct mm_pb_manager *mm = mm_pb_manager(mgr);
_glthread_LOCK_MUTEX(mm->mutex);
mmDestroy(mm->heap);
- buffer_unmap(mm->buffer);
- buffer_release(mm->buffer);
+ pb_unmap(mm->buffer);
+ pb_destroy(mm->buffer);
_glthread_UNLOCK_MUTEX(mm->mutex);
- free(mgr);
+ FREE(mgr);
}
-struct buffer_manager *
-mm_bufmgr_create_from_buffer(struct pipe_buffer *buffer,
+struct pb_manager *
+mm_bufmgr_create_from_buffer(struct pb_buffer *buffer,
size_t size, size_t align2)
{
- struct mm_buffer_manager *mm;
+ struct mm_pb_manager *mm;
if(!buffer)
return NULL;
- mm = (struct mm_buffer_manager *)calloc(1, sizeof(*mm));
+ mm = CALLOC_STRUCT(mm_pb_manager);
if (!mm)
return NULL;
@@ -240,8 +536,9 @@ mm_bufmgr_create_from_buffer(struct pipe_buffer *buffer,
mm->buffer = buffer;
- mm->map = buffer_map(mm->buffer,
- PIPE_BUFFER_FLAG_READ | PIPE_BUFFER_FLAG_WRITE );
+ mm->map = pb_map(mm->buffer,
+ PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE);
if(!mm->map)
goto failure;
@@ -255,29 +552,34 @@ failure:
if(mm->heap)
mmDestroy(mm->heap);
if(mm->map)
- buffer_unmap(mm->buffer);
+ pb_unmap(mm->buffer);
if(mm)
- free(mm);
+ FREE(mm);
return NULL;
}
-struct buffer_manager *
-mm_bufmgr_create(struct buffer_manager *provider,
+struct pb_manager *
+mm_bufmgr_create(struct pb_manager *provider,
size_t size, size_t align2)
{
- struct pipe_buffer *buffer;
- struct buffer_manager *mgr;
+ struct pb_buffer *buffer;
+ struct pb_manager *mgr;
+ struct pb_desc desc;
assert(provider);
assert(provider->create_buffer);
- buffer = provider->create_buffer(provider, size);
+
+ memset(&desc, 0, sizeof(desc));
+ desc.alignment = 1 << align2;
+
+ buffer = provider->create_buffer(provider, size, &desc);
if (!buffer)
return NULL;
mgr = mm_bufmgr_create_from_buffer(buffer, size, align2);
if (!mgr) {
- buffer_release(buffer);
+ pb_destroy(buffer);
return NULL;
}
diff --git a/src/mesa/pipe/pipebuffer/pb_bufmgr_pool.c b/src/mesa/pipe/pipebuffer/pb_bufmgr_pool.c
index ee6fa62500..61c06ec824 100644
--- a/src/mesa/pipe/pipebuffer/pb_bufmgr_pool.c
+++ b/src/mesa/pipe/pipebuffer/pb_bufmgr_pool.c
@@ -37,13 +37,13 @@
#include <assert.h>
#include <stdlib.h>
-#include <unistd.h>
-#include "main/imports.h"
-#include "glapi/glthread.h"
#include "linked_list.h"
+#include "p_compiler.h"
+#include "p_thread.h"
#include "p_defines.h"
+#include "p_util.h"
#include "pb_buffer.h"
#include "pb_bufmgr.h"
@@ -55,39 +55,40 @@
#define SUPER(__derived) (&(__derived)->base)
-struct pool_buffer_manager
+struct pool_pb_manager
{
- struct buffer_manager base;
+ struct pb_manager base;
_glthread_Mutex mutex;
size_t bufSize;
+ size_t bufAlign;
size_t numFree;
size_t numTot;
struct list_head free;
- struct pipe_buffer *buffer;
+ struct pb_buffer *buffer;
void *map;
struct pool_buffer *bufs;
};
-static inline struct pool_buffer_manager *
-pool_buffer_manager(struct buffer_manager *mgr)
+static INLINE struct pool_pb_manager *
+pool_pb_manager(struct pb_manager *mgr)
{
assert(mgr);
- return (struct pool_buffer_manager *)mgr;
+ return (struct pool_pb_manager *)mgr;
}
struct pool_buffer
{
- struct pipe_buffer base;
+ struct pb_buffer base;
- struct pool_buffer_manager *mgr;
+ struct pool_pb_manager *mgr;
struct list_head head;
@@ -95,26 +96,20 @@ struct pool_buffer
};
-static inline struct pool_buffer *
-pool_buffer(struct pipe_buffer *buf)
+static INLINE struct pool_buffer *
+pool_buffer(struct pb_buffer *buf)
{
assert(buf);
return (struct pool_buffer *)buf;
}
-static void
-pool_buffer_reference(struct pipe_buffer *buf)
-{
- /* No-op */
-}
-
static void
-pool_buffer_release(struct pipe_buffer *buf)
+pool_buffer_destroy(struct pb_buffer *buf)
{
struct pool_buffer *pool_buf = pool_buffer(buf);
- struct pool_buffer_manager *pool = pool_buf->mgr;
+ struct pool_pb_manager *pool = pool_buf->mgr;
_glthread_LOCK_MUTEX(pool->mutex);
LIST_ADD(&pool_buf->head, &pool->free);
@@ -124,10 +119,10 @@ pool_buffer_release(struct pipe_buffer *buf)
static void *
-pool_buffer_map(struct pipe_buffer *buf, unsigned flags)
+pool_buffer_map(struct pb_buffer *buf, unsigned flags)
{
struct pool_buffer *pool_buf = pool_buffer(buf);
- struct pool_buffer_manager *pool = pool_buf->mgr;
+ struct pool_pb_manager *pool = pool_buf->mgr;
void *map;
_glthread_LOCK_MUTEX(pool->mutex);
@@ -138,42 +133,44 @@ pool_buffer_map(struct pipe_buffer *buf, unsigned flags)
static void
-pool_buffer_unmap(struct pipe_buffer *buf)
+pool_buffer_unmap(struct pb_buffer *buf)
{
/* No-op */
}
static void
-pool_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
+pool_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
unsigned *offset)
{
struct pool_buffer *pool_buf = pool_buffer(buf);
- struct pool_buffer_manager *pool = pool_buf->mgr;
- buffer_get_base_buffer(pool->buffer, base_buf, offset);
+ struct pool_pb_manager *pool = pool_buf->mgr;
+ pb_get_base_buffer(pool->buffer, base_buf, offset);
*offset += pool_buf->start;
}
-static const struct pipe_buffer_vtbl
+static const struct pb_vtbl
pool_buffer_vtbl = {
- pool_buffer_reference,
- pool_buffer_release,
+ pool_buffer_destroy,
pool_buffer_map,
pool_buffer_unmap,
pool_buffer_get_base_buffer
};
-static struct pipe_buffer *
-pool_bufmgr_create_buffer(struct buffer_manager *mgr, size_t size)
+static struct pb_buffer *
+pool_bufmgr_create_buffer(struct pb_manager *mgr,
+ size_t size,
+ const struct pb_desc *desc)
{
- struct pool_buffer_manager *pool = pool_buffer_manager(mgr);
+ struct pool_pb_manager *pool = pool_pb_manager(mgr);
struct pool_buffer *pool_buf;
struct list_head *item;
assert(size == pool->bufSize);
+ assert(desc->alignment % pool->bufAlign == 0);
_glthread_LOCK_MUTEX(pool->mutex);
@@ -201,32 +198,33 @@ pool_bufmgr_create_buffer(struct buffer_manager *mgr, size_t size)
static void
-pool_bufmgr_destroy(struct buffer_manager *mgr)
+pool_bufmgr_destroy(struct pb_manager *mgr)
{
- struct pool_buffer_manager *pool = pool_buffer_manager(mgr);
+ struct pool_pb_manager *pool = pool_pb_manager(mgr);
_glthread_LOCK_MUTEX(pool->mutex);
- free(pool->bufs);
+ FREE(pool->bufs);
- buffer_unmap(pool->buffer);
- buffer_release(pool->buffer);
+ pb_unmap(pool->buffer);
+ pb_destroy(pool->buffer);
_glthread_UNLOCK_MUTEX(pool->mutex);
- free(mgr);
+ FREE(mgr);
}
-struct buffer_manager *
-pool_bufmgr_create(struct buffer_manager *provider,
+struct pb_manager *
+pool_bufmgr_create(struct pb_manager *provider,
size_t numBufs,
- size_t bufSize)
+ size_t bufSize,
+ const struct pb_desc *desc)
{
- struct pool_buffer_manager *pool;
+ struct pool_pb_manager *pool;
struct pool_buffer *pool_buf;
- int i;
+ size_t i;
- pool = (struct pool_buffer_manager *)calloc(1, sizeof(*pool));
+ pool = (struct pool_pb_manager *)CALLOC(1, sizeof(*pool));
if (!pool)
return NULL;
@@ -238,20 +236,21 @@ pool_bufmgr_create(struct buffer_manager *provider,
pool->numTot = numBufs;
pool->numFree = numBufs;
pool->bufSize = bufSize;
+ pool->bufAlign = desc->alignment;
_glthread_INIT_MUTEX(pool->mutex);
- pool->buffer = provider->create_buffer(provider, numBufs*bufSize);
+ pool->buffer = provider->create_buffer(provider, numBufs*bufSize, desc);
if (!pool->buffer)
goto failure;
- pool->map = buffer_map(pool->buffer,
- PIPE_BUFFER_FLAG_READ |
- PIPE_BUFFER_FLAG_WRITE );
+ pool->map = pb_map(pool->buffer,
+ PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE);
if(!pool->map)
goto failure;
- pool->bufs = (struct pool_buffer *) malloc(numBufs * sizeof(*pool->bufs));
+ pool->bufs = (struct pool_buffer *) MALLOC(numBufs * sizeof(*pool->bufs));
if (!pool->bufs)
goto failure;
@@ -268,12 +267,12 @@ pool_bufmgr_create(struct buffer_manager *provider,
failure:
if(pool->bufs)
- free(pool->bufs);
+ FREE(pool->bufs);
if(pool->map)
- buffer_unmap(pool->buffer);
+ pb_unmap(pool->buffer);
if(pool->buffer)
- buffer_release(pool->buffer);
+ pb_destroy(pool->buffer);
if(pool)
- free(pool);
+ FREE(pool);
return NULL;
}
diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c
index 5b3857145d..571f64b38d 100644
--- a/src/mesa/pipe/softpipe/sp_clear.c
+++ b/src/mesa/pipe/softpipe/sp_clear.c
@@ -53,24 +53,19 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
softpipe_update_derived(softpipe); /* not needed?? */
#endif
-#if TILE_CLEAR_OPTIMIZATION
- if (ps == sp_tile_cache_get_surface(softpipe->zbuf_cache)) {
- sp_tile_cache_clear(softpipe->zbuf_cache, clearValue);
+ if (ps == sp_tile_cache_get_surface(softpipe->zsbuf_cache)) {
+ sp_tile_cache_clear(softpipe->zsbuf_cache, clearValue);
return;
}
for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) {
sp_tile_cache_clear(softpipe->cbuf_cache[i], clearValue);
- return;
}
}
-#endif
+#if !TILE_CLEAR_OPTIMIZATION
/* non-cached surface */
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
-
-#if 0
- sp_clear_tile_cache(ps, clearValue);
#endif
}
diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c
index 68c18e2d05..cea6b90104 100644
--- a/src/mesa/pipe/softpipe/sp_context.c
+++ b/src/mesa/pipe/softpipe/sp_context.c
@@ -37,6 +37,7 @@
#include "sp_context.h"
#include "sp_flush.h"
#include "sp_prim_setup.h"
+#include "sp_prim_vbuf.h"
#include "sp_state.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
@@ -81,9 +82,7 @@ softpipe_map_surfaces(struct softpipe_context *sp)
sp_tile_cache_map_surfaces(sp->cbuf_cache[i]);
}
- sp_tile_cache_map_surfaces(sp->zbuf_cache);
-
- sp_tile_cache_map_surfaces(sp->sbuf_cache);
+ sp_tile_cache_map_surfaces(sp->zsbuf_cache);
}
@@ -97,16 +96,12 @@ softpipe_unmap_surfaces(struct softpipe_context *sp)
for (i = 0; i < sp->framebuffer.num_cbufs; i++)
sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
- sp_flush_tile_cache(sp, sp->zbuf_cache);
- sp_flush_tile_cache(sp, sp->sbuf_cache);
+ sp_flush_tile_cache(sp, sp->zsbuf_cache);
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]);
}
-
- sp_tile_cache_unmap_surfaces(sp->zbuf_cache);
-
- sp_tile_cache_unmap_surfaces(sp->sbuf_cache);
+ sp_tile_cache_unmap_surfaces(sp->zsbuf_cache);
}
@@ -133,15 +128,14 @@ static void softpipe_destroy( struct pipe_context *pipe )
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
sp_destroy_tile_cache(softpipe->cbuf_cache[i]);
- sp_destroy_tile_cache(softpipe->zbuf_cache);
- sp_destroy_tile_cache(softpipe->sbuf_cache_sep);
+ sp_destroy_tile_cache(softpipe->zsbuf_cache);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
sp_destroy_tile_cache(softpipe->tex_cache[i]);
for (i = 0; i < Elements(softpipe->constants); i++) {
if (softpipe->constants[i].buffer) {
- ws->buffer_reference(ws, &softpipe->constants[i].buffer, NULL);
+ pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL);
}
}
@@ -297,9 +291,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
*/
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
softpipe->cbuf_cache[i] = sp_create_tile_cache();
- softpipe->zbuf_cache = sp_create_tile_cache();
- softpipe->sbuf_cache_sep = sp_create_tile_cache();
- softpipe->sbuf_cache = softpipe->sbuf_cache_sep; /* initial value */
+ softpipe->zsbuf_cache = sp_create_tile_cache();
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
softpipe->tex_cache[i] = sp_create_tile_cache();
@@ -329,11 +321,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
softpipe->setup = sp_draw_render_stage(softpipe);
if (GETENV( "SP_VBUF" ) != NULL) {
- softpipe->vbuf = sp_draw_vbuf_stage(softpipe->draw,
- &softpipe->pipe,
- sp_vbuf_render);
-
- draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf);
+ sp_init_vbuf(softpipe);
}
else {
draw_set_rasterize_stage(softpipe->draw, softpipe->setup);
diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h
index 3537f86a61..aff8c2cc5d 100644
--- a/src/mesa/pipe/softpipe/sp_context.h
+++ b/src/mesa/pipe/softpipe/sp_context.h
@@ -40,6 +40,7 @@
struct softpipe_winsys;
+struct softpipe_vbuf_render;
struct draw_context;
struct draw_stage;
struct softpipe_tile_cache;
@@ -88,8 +89,8 @@ struct softpipe_context {
/** Vertex format */
struct vertex_info vertex_info;
- unsigned attr_mask;
- unsigned nr_frag_attrs; /**< number of active fragment attribs */
+ struct vertex_info vertex_info_vbuf;
+
int psize_slot;
#if 0
@@ -125,15 +126,12 @@ struct softpipe_context {
struct draw_context *draw;
struct draw_stage *setup;
struct draw_stage *vbuf;
+ struct softpipe_vbuf_render *vbuf_render;
uint current_cbuf; /**< current color buffer being written to */
struct softpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS];
- struct softpipe_tile_cache *zbuf_cache;
- /** Stencil buffer cache, for stencil separate from Z */
- struct softpipe_tile_cache *sbuf_cache_sep;
- /** This either points to zbuf_cache or sbuf_cache_sep */
- struct softpipe_tile_cache *sbuf_cache;
+ struct softpipe_tile_cache *zsbuf_cache;
struct softpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
diff --git a/src/mesa/pipe/softpipe/sp_draw_arrays.c b/src/mesa/pipe/softpipe/sp_draw_arrays.c
index b7626f8a5f..71a303a8b5 100644
--- a/src/mesa/pipe/softpipe/sp_draw_arrays.c
+++ b/src/mesa/pipe/softpipe/sp_draw_arrays.c
@@ -50,7 +50,7 @@ softpipe_map_constant_buffers(struct softpipe_context *sp)
for (i = 0; i < 2; i++) {
if (sp->constants[i].size)
sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer,
- PIPE_BUFFER_FLAG_READ);
+ PIPE_BUFFER_USAGE_CPU_READ);
}
draw_set_mapped_constant_buffer(sp->draw,
@@ -88,7 +88,7 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
*/
boolean
softpipe_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer_handle *indexBuffer,
+ struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
@@ -122,7 +122,7 @@ softpipe_draw_elements(struct pipe_context *pipe,
void *buf
= pipe->winsys->buffer_map(pipe->winsys,
sp->vertex_buffer[i].buffer,
- PIPE_BUFFER_FLAG_READ);
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(draw, i, buf);
}
}
@@ -130,7 +130,7 @@ softpipe_draw_elements(struct pipe_context *pipe,
if (indexBuffer) {
void *mapped_indexes
= pipe->winsys->buffer_map(pipe->winsys, indexBuffer,
- PIPE_BUFFER_FLAG_READ);
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
}
else {
@@ -142,21 +142,18 @@ softpipe_draw_elements(struct pipe_context *pipe,
/* draw! */
draw_arrays(draw, mode, start, count);
- /* always flush for now */
- draw_flush(draw);
-
/*
- * unmap vertex/index buffers
+ * unmap vertex/index buffers - will cause draw module to flush
*/
for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
if (sp->vertex_buffer[i].buffer) {
- pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, NULL);
+ pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
}
}
if (indexBuffer) {
- pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
draw_set_mapped_element_buffer(draw, 0, NULL);
+ pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
}
diff --git a/src/mesa/pipe/softpipe/sp_flush.c b/src/mesa/pipe/softpipe/sp_flush.c
index 47b11803ce..ec6bb4a0dc 100644
--- a/src/mesa/pipe/softpipe/sp_flush.c
+++ b/src/mesa/pipe/softpipe/sp_flush.c
@@ -59,11 +59,8 @@ softpipe_flush( struct pipe_context *pipe,
if (softpipe->cbuf_cache[i])
sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]);
- if (softpipe->zbuf_cache)
- sp_flush_tile_cache(softpipe, softpipe->zbuf_cache);
-
- if (softpipe->sbuf_cache)
- sp_flush_tile_cache(softpipe, softpipe->sbuf_cache);
+ if (softpipe->zsbuf_cache)
+ sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache);
/* Need this call for hardware buffers before swapbuffers.
*
diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c
index cdc385e4db..b17801d13d 100644
--- a/src/mesa/pipe/softpipe/sp_prim_setup.c
+++ b/src/mesa/pipe/softpipe/sp_prim_setup.c
@@ -85,8 +85,6 @@ struct setup_stage {
struct tgsi_interp_coef posCoef; /* For Z, W */
struct quad_header quad;
- uint firstFpInput; /** Semantic type of first frag input */
-
struct {
int left[2]; /**< [0] = row0, [1] = row1 */
int right[2];
@@ -515,11 +513,8 @@ setup_fragcoord_coeff(struct setup_stage *setup)
*/
static void setup_tri_coefficients( struct setup_stage *setup )
{
- const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
-#define USE_INPUT_MAP 01
-#if USE_INPUT_MAP
- const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
-#endif
+ const struct softpipe_context *softpipe = setup->softpipe;
+ const struct pipe_shader_state *fs = &softpipe->fs->shader;
uint fragSlot;
/* z and w are done by linear interpolation:
@@ -529,64 +524,37 @@ static void setup_tri_coefficients( struct setup_stage *setup )
/* setup interpolation for all the remaining attributes:
*/
- for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
- /* which vertex output maps to this fragment input: */
-#if !USE_INPUT_MAP
- uint vertSlot;
- if (setup->firstFpInput == TGSI_SEMANTIC_POSITION) {
- if (fragSlot == 0) {
- setup_fragcoord_coeff(setup);
- continue;
- }
- vertSlot = fragSlot;
- }
- else {
- vertSlot = fragSlot + 1;
- }
-
-#else
- uint vertSlot = fs->input_map[fragSlot];
-
- if (vertSlot == 0) {
- /* special case: shader is reading gl_FragCoord */
- /* XXX with a new INTERP_POSITION token, we could just add a
- * new case to the switch below.
- */
+ for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ uint j;
+
+ switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ case INTERP_CONSTANT:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_LINEAR:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_PERSPECTIVE:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_POS:
+ assert(fragSlot == 0);
setup_fragcoord_coeff(setup);
+ break;
+ default:
+ assert(0);
}
- else {
-#endif
- uint j;
- switch (interp[vertSlot]) {
- case INTERP_CONSTANT:
- for (j = 0; j < NUM_CHANNELS; j++)
- const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_LINEAR:
- for (j = 0; j < NUM_CHANNELS; j++)
- tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_PERSPECTIVE:
- for (j = 0; j < NUM_CHANNELS; j++)
- tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- default:
- /* invalid interp mode */
- /* assert(0); re-enable this and run demos/fogcoord.c ... */
- ;
- }
- if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
- /* FOG.y = front/back facing XXX fix this */
- setup->coef[fragSlot].a0[1] = 1 - setup->quad.facing;
- setup->coef[fragSlot].dadx[1] = 0.0;
- setup->coef[fragSlot].dady[1] = 0.0;
- }
-
-
-#if USE_INPUT_MAP
+ if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ /* FOG.y = front/back facing XXX fix this */
+ setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing;
+ setup->coef[fragSlot].dadx[1] = 0.0;
+ setup->coef[fragSlot].dady[1] = 0.0;
}
-#endif
}
}
@@ -788,9 +756,9 @@ line_persp_coeff(struct setup_stage *setup,
static INLINE void
setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
{
- const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
+ const struct softpipe_context *softpipe = setup->softpipe;
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
- unsigned fragSlot;
+ uint fragSlot;
/* use setup->vmin, vmax to point to vertices */
setup->vprovoke = prim->v[1];
@@ -810,34 +778,37 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
/* setup interpolation for all the remaining attributes:
*/
- for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
- /* which vertex output maps to this fragment input: */
- uint vertSlot = fs->input_map[fragSlot];
-
- if (vertSlot == 0) {
- /* special case: shader is reading gl_FragCoord */
+ for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ uint j;
+
+ switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ case INTERP_CONSTANT:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_LINEAR:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_PERSPECTIVE:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_POS:
+ assert(fragSlot == 0);
+ assert(0); /* XXX fix this: */
setup_fragcoord_coeff(setup);
+ break;
+ default:
+ assert(0);
}
- else {
- uint j;
- switch (interp[vertSlot]) {
- case INTERP_CONSTANT:
- for (j = 0; j < NUM_CHANNELS; j++)
- const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_LINEAR:
- for (j = 0; j < NUM_CHANNELS; j++)
- line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_PERSPECTIVE:
- for (j = 0; j < NUM_CHANNELS; j++)
- line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
-
- default:
- /* invalid interp mode */
- assert(0);
- }
+
+ if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ /* FOG.y = front/back facing XXX fix this */
+ setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing;
+ setup->coef[fragSlot].dadx[1] = 0.0;
+ setup->coef[fragSlot].dady[1] = 0.0;
}
}
}
@@ -996,8 +967,8 @@ static void
setup_point(struct draw_stage *stage, struct prim_header *prim)
{
struct setup_stage *setup = setup_stage( stage );
- const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
- const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
+ struct softpipe_context *softpipe = setup->softpipe;
+ const struct pipe_shader_state *fs = &softpipe->fs->shader;
const struct vertex_header *v0 = prim->v[0];
const int sizeAttr = setup->softpipe->psize_slot;
const float size
@@ -1031,31 +1002,36 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
const_coeff(setup, &setup->posCoef, 0, 2);
const_coeff(setup, &setup->posCoef, 0, 3);
- for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
- /* which vertex output maps to this fragment input: */
- uint vertSlot = fs->input_map[fragSlot];
-
- if (vertSlot == 0) {
- /* special case: shader is reading gl_FragCoord */
+ for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ uint j;
+
+ switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ case INTERP_CONSTANT:
+ /* fall-through */
+ case INTERP_LINEAR:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_PERSPECTIVE:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ point_persp_coeff(setup, setup->vprovoke,
+ &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_POS:
+ assert(fragSlot == 0);
+ assert(0); /* XXX fix this: */
setup_fragcoord_coeff(setup);
+ break;
+ default:
+ assert(0);
}
- else {
- uint j;
- switch (interp[vertSlot]) {
- case INTERP_CONSTANT:
- /* fall-through */
- case INTERP_LINEAR:
- for (j = 0; j < NUM_CHANNELS; j++)
- const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_PERSPECTIVE:
- for (j = 0; j < NUM_CHANNELS; j++)
- point_persp_coeff(setup, setup->vprovoke,
- &setup->coef[fragSlot], vertSlot, j);
- break;
- default:
- assert(0);
- }
+
+ if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ /* FOG.y = front/back facing XXX fix this */
+ setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing;
+ setup->coef[fragSlot].dadx[1] = 0.0;
+ setup->coef[fragSlot].dady[1] = 0.0;
}
}
@@ -1191,16 +1167,46 @@ static void setup_begin( struct draw_stage *stage )
struct softpipe_context *sp = setup->softpipe;
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
- setup->quad.nr_attrs = setup->softpipe->nr_frag_attrs;
-
- setup->firstFpInput = fs->input_semantic_name[0];
+ setup->quad.nr_attrs = fs->num_inputs;
sp->quad.first->begin(sp->quad.first);
+
+ stage->point = setup_point;
+ stage->line = setup_line;
+ stage->tri = setup_tri;
}
-static void setup_end( struct draw_stage *stage )
+static void setup_first_point( struct draw_stage *stage,
+ struct prim_header *header )
{
+ setup_begin(stage);
+ stage->point( stage, header );
+}
+
+static void setup_first_line( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ setup_begin(stage);
+ stage->line( stage, header );
+}
+
+
+static void setup_first_tri( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ setup_begin(stage);
+ stage->tri( stage, header );
+}
+
+
+
+static void setup_flush( struct draw_stage *stage,
+ unsigned flags )
+{
+ stage->point = setup_first_point;
+ stage->line = setup_first_line;
+ stage->tri = setup_first_tri;
}
@@ -1224,11 +1230,10 @@ struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe )
setup->softpipe = softpipe;
setup->stage.draw = softpipe->draw;
- setup->stage.begin = setup_begin;
- setup->stage.point = setup_point;
- setup->stage.line = setup_line;
- setup->stage.tri = setup_tri;
- setup->stage.end = setup_end;
+ setup->stage.point = setup_first_point;
+ setup->stage.line = setup_first_line;
+ setup->stage.tri = setup_first_tri;
+ setup->stage.flush = setup_flush;
setup->stage.reset_stipple_counter = reset_stipple_counter;
setup->stage.destroy = render_destroy;
@@ -1237,87 +1242,3 @@ struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe )
return &setup->stage;
}
-
-
-/* Recalculate det. This is only used in the test harness below:
- */
-static void calc_det( struct prim_header *header )
-{
- /* Window coords: */
- const float *v0 = header->v[0]->data[0];
- const float *v1 = header->v[1]->data[0];
- const float *v2 = header->v[2]->data[0];
-
- /* edge vectors e = v0 - v2, f = v1 - v2 */
- const float ex = v0[0] - v2[0];
- const float ey = v0[1] - v2[1];
- const float fx = v1[0] - v2[0];
- const float fy = v1[1] - v2[1];
-
- /* det = cross(e,f).z */
- header->det = ex * fy - ey * fx;
-}
-
-
-
-/**
- * Render buffer of points/lines/triangles.
- * Called by vbuf code when the vertex or index buffer is filled.
- *
- * The big issue at this point is that reset_stipple doesn't make it
- * through the interface. Probably need to split primitives at reset
- * stipple, perhaps using the ~0 index marker.
- */
-void sp_vbuf_render( struct pipe_context *pipe,
- unsigned primitive,
- const ushort *elements,
- unsigned nr_elements,
- const void *vertex_buffer,
- unsigned nr_vertices )
-{
- struct softpipe_context *softpipe = softpipe_context( pipe );
- struct setup_stage *setup = setup_stage( softpipe->setup );
- struct prim_header prim;
- unsigned vertex_size = setup->stage.draw->vertex_info.size * sizeof(float);
- unsigned i, j;
-
- prim.det = 0;
- prim.reset_line_stipple = 0;
- prim.edgeflags = 0;
- prim.pad = 0;
-
- setup->stage.begin( &setup->stage );
-
- switch (primitive) {
- case PIPE_PRIM_TRIANGLES:
- for (i = 0; i < nr_elements; i += 3) {
- for (j = 0; j < 3; j++)
- prim.v[j] = (struct vertex_header *)((char *)vertex_buffer +
- elements[i+j] * vertex_size);
-
- calc_det(&prim);
- setup->stage.tri( &setup->stage, &prim );
- }
- break;
-
- case PIPE_PRIM_LINES:
- for (i = 0; i < nr_elements; i += 2) {
- for (j = 0; j < 2; j++)
- prim.v[j] = (struct vertex_header *)((char *)vertex_buffer +
- elements[i+j] * vertex_size);
-
- setup->stage.line( &setup->stage, &prim );
- }
- break;
-
- case PIPE_PRIM_POINTS:
- for (i = 0; i < nr_elements; i++) {
- prim.v[0] = (struct vertex_header *)((char *)vertex_buffer +
- elements[i] * vertex_size);
- setup->stage.point( &setup->stage, &prim );
- }
- break;
- }
-
- setup->stage.end( &setup->stage );
-}
diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.h b/src/mesa/pipe/softpipe/sp_prim_setup.h
index c16dc634b0..f3e8a79dd9 100644
--- a/src/mesa/pipe/softpipe/sp_prim_setup.h
+++ b/src/mesa/pipe/softpipe/sp_prim_setup.h
@@ -76,14 +76,4 @@ sp_draw_vbuf_stage( struct draw_context *draw_context,
vbuf_draw_func draw );
-extern void
-sp_vbuf_render( struct pipe_context *pipe,
- unsigned prim,
- const ushort *elements,
- unsigned nr_elements,
- const void *vertex_buffer,
- unsigned nr_vertices );
-
-
-
#endif /* SP_PRIM_SETUP_H */
diff --git a/src/mesa/pipe/softpipe/sp_prim_vbuf.c b/src/mesa/pipe/softpipe/sp_prim_vbuf.c
index 055cb19f9a..c9089e7eb2 100644
--- a/src/mesa/pipe/softpipe/sp_prim_vbuf.c
+++ b/src/mesa/pipe/softpipe/sp_prim_vbuf.c
@@ -2,7 +2,7 @@
*
* 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
@@ -26,299 +26,197 @@
**************************************************************************/
/**
- * Build post-transformation, post-clipping vertex buffers and element
- * lists by hooking into the end of the primitive pipeline and
- * manipulating the vertex_id field in the vertex headers.
- *
- * Keith Whitwell <keith@tungstengraphics.com>
+ * Post-transform vertex buffering. This is an optional part of the
+ * softpipe rendering pipeline.
+ * Probably not desired in general, but useful for testing/debuggin.
+ * Enabled/Disabled with SP_VBUF env var.
+ *
+ * Authors
+ * Brian Paul
*/
#include "sp_context.h"
-#include "sp_headers.h"
-#include "sp_quad.h"
-#include "sp_prim_setup.h"
+#include "sp_prim_vbuf.h"
+#include "pipe/draw/draw_context.h"
#include "pipe/draw/draw_private.h"
-#include "pipe/draw/draw_vertex.h"
-#include "pipe/p_util.h"
-
-static void vbuf_flush_elements( struct draw_stage *stage );
+#include "pipe/draw/draw_vbuf.h"
-#define VBUF_SIZE (64*1024)
-#define IBUF_SIZE (16*1024)
+#define SP_MAX_VBUF_INDEXES 1024
+#define SP_MAX_VBUF_SIZE 4096
/**
- * Vertex buffer emit stage.
+ * Subclass of vbuf_render.
*/
-struct vbuf_stage {
- struct draw_stage stage; /**< This must be first (base class) */
-
- struct draw_context *draw_context;
- struct pipe_context *pipe;
- vbuf_draw_func draw;
-
- /* Vertices are passed in as an array of floats making up each
- * attribute in turn. Will eventually convert to hardware format
- * in this stage.
- */
- char *vertex_map;
- char *vertex_ptr;
- unsigned vertex_size;
- unsigned nr_vertices;
-
- unsigned max_vertices;
-
- ushort *element_map;
- unsigned nr_elements;
-
- unsigned prim;
-
-};
-
-/**
- * Basically a cast wrapper.
- */
-static INLINE struct vbuf_stage *vbuf_stage( struct draw_stage *stage )
+struct softpipe_vbuf_render
{
- return (struct vbuf_stage *)stage;
-}
-
-
+ struct vbuf_render base;
+ struct softpipe_context *softpipe;
+ uint prim;
+ uint vertex_size;
+ void *vertex_buffer;
+};
-static boolean overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz )
+/** cast wrapper */
+static struct softpipe_vbuf_render *
+softpipe_vbuf_render(struct vbuf_render *vbr)
{
- unsigned long used = (unsigned long) ((char *) ptr - (char *) map);
- return (used + bytes) > bufsz;
+ return (struct softpipe_vbuf_render *) vbr;
}
-static boolean check_space( struct vbuf_stage *vbuf )
-{
- if (overflow( vbuf->vertex_map,
- vbuf->vertex_ptr,
- 4 * vbuf->vertex_size,
- VBUF_SIZE ))
- return FALSE;
-
- if (vbuf->nr_elements + 4 > IBUF_SIZE / sizeof(ushort) )
- return FALSE;
-
- return TRUE;
-}
-
-
-static void emit_vertex( struct vbuf_stage *vbuf,
- struct vertex_header *vertex )
+static const struct vertex_info *
+sp_vbuf_get_vertex_info(struct vbuf_render *vbr)
{
-// fprintf(stderr, "emit vertex %d to %p\n",
-// vbuf->nr_vertices, vbuf->vertex_ptr);
-
- vertex->vertex_id = vbuf->nr_vertices++;
-
- //vbuf->emit_vertex( vbuf->vertex_ptr, vertex );
-
- /* Note: for softpipe, the vertex includes the vertex header info
- * such as clip flags and clip coords. In the future when vbuf is
- * always used, we could just copy the vertex attributes/data here.
- * The sp_prim_setup.c code doesn't use any of the vertex header info.
- */
- memcpy(vbuf->vertex_ptr, vertex, vbuf->vertex_size);
-
- vbuf->vertex_ptr += vbuf->vertex_size;
+ struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
+ /* XXX check for state changes? */
+ assert(!cvbr->softpipe->dirty );
+ return &cvbr->softpipe->vertex_info_vbuf;
}
-
-/**
- *
- */
-static void vbuf_tri( struct draw_stage *stage,
- struct prim_header *prim )
+static void *
+sp_vbuf_allocate_vertices(struct vbuf_render *vbr,
+ ushort vertex_size, ushort nr_vertices)
{
- struct vbuf_stage *vbuf = vbuf_stage( stage );
- unsigned i;
-
- if (!check_space( vbuf ))
- vbuf_flush_elements( stage );
-
- for (i = 0; i < 3; i++) {
- if (prim->v[i]->vertex_id == UNDEFINED_VERTEX_ID)
- emit_vertex( vbuf, prim->v[i] );
-
- vbuf->element_map[vbuf->nr_elements++] = (ushort) prim->v[i]->vertex_id;
- }
+ struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
+ assert(!cvbr->vertex_buffer);
+ cvbr->vertex_buffer = align_malloc(vertex_size * nr_vertices, 16);
+ cvbr->vertex_size = vertex_size;
+ return cvbr->vertex_buffer;
}
-static void vbuf_line(struct draw_stage *stage,
- struct prim_header *prim)
+static void
+sp_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices,
+ unsigned vertex_size, unsigned vertices_used)
{
- struct vbuf_stage *vbuf = vbuf_stage( stage );
- unsigned i;
-
- if (!check_space( vbuf ))
- vbuf_flush_elements( stage );
-
- for (i = 0; i < 2; i++) {
- if (prim->v[i]->vertex_id == UNDEFINED_VERTEX_ID)
- emit_vertex( vbuf, prim->v[i] );
-
- vbuf->element_map[vbuf->nr_elements++] = (ushort) prim->v[i]->vertex_id;
- }
+ struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
+ align_free(vertices);
+ assert(vertices == cvbr->vertex_buffer);
+ cvbr->vertex_buffer = NULL;
}
-static void vbuf_point(struct draw_stage *stage,
- struct prim_header *prim)
+static void
+sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
{
- struct vbuf_stage *vbuf = vbuf_stage( stage );
-
- if (!check_space( vbuf ))
- vbuf_flush_elements( stage );
-
- if (prim->v[0]->vertex_id == UNDEFINED_VERTEX_ID)
- emit_vertex( vbuf, prim->v[0] );
-
- vbuf->element_map[vbuf->nr_elements++] = (ushort) prim->v[0]->vertex_id;
-}
-
-
-static void vbuf_first_tri( struct draw_stage *stage,
- struct prim_header *prim )
-{
- struct vbuf_stage *vbuf = vbuf_stage( stage );
-
- vbuf_flush_elements( stage );
- stage->tri = vbuf_tri;
- stage->tri( stage, prim );
- vbuf->prim = PIPE_PRIM_TRIANGLES;
-}
-
-static void vbuf_first_line( struct draw_stage *stage,
- struct prim_header *prim )
-{
- struct vbuf_stage *vbuf = vbuf_stage( stage );
-
- vbuf_flush_elements( stage );
- stage->line = vbuf_line;
- stage->line( stage, prim );
- vbuf->prim = PIPE_PRIM_LINES;
+ struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
+ cvbr->prim = prim;
}
-static void vbuf_first_point( struct draw_stage *stage,
- struct prim_header *prim )
-{
- struct vbuf_stage *vbuf = vbuf_stage( stage );
- vbuf_flush_elements( stage );
- stage->point = vbuf_point;
- stage->point( stage, prim );
- vbuf->prim = PIPE_PRIM_POINTS;
-}
-
-
-
-static void vbuf_flush_elements( struct draw_stage *stage )
-{
- struct vbuf_stage *vbuf = vbuf_stage( stage );
-
- if (vbuf->nr_elements) {
- /*
- fprintf(stderr, "%s (%d elts)\n", __FUNCTION__, vbuf->nr_elements);
- */
-
- /* Draw now or add to list of primitives???
- */
- vbuf->draw( vbuf->pipe,
- vbuf->prim,
- vbuf->element_map,
- vbuf->nr_elements,
- vbuf->vertex_map,
- (unsigned) (vbuf->vertex_ptr - vbuf->vertex_map) / vbuf->vertex_size );
-
- vbuf->nr_elements = 0;
-
- vbuf->vertex_ptr = vbuf->vertex_map;
- vbuf->nr_vertices = 0;
-
- /* Reset vertex ids? Actually, want to not do that unless our
- * vertex buffer is full. Would like separate
- * flush-on-index-full and flush-on-vb-full, but may raise
- * issues uploading vertices if the hardware wants to flush when
- * we flush.
- */
- draw_reset_vertex_ids( vbuf->draw_context );
+/**
+ * Recalculate prim's determinant.
+ * XXX is this needed?
+ */
+static void
+calc_det(struct prim_header *header)
+{
+ /* Window coords: */
+ const float *v0 = header->v[0]->data[0];
+ const float *v1 = header->v[1]->data[0];
+ const float *v2 = header->v[2]->data[0];
+
+ /* edge vectors e = v0 - v2, f = v1 - v2 */
+ const float ex = v0[0] - v2[0];
+ const float ey = v0[1] - v2[1];
+ const float fx = v1[0] - v2[0];
+ const float fy = v1[1] - v2[1];
+
+ /* det = cross(e,f).z */
+ header->det = ex * fy - ey * fx;
+}
+
+
+static void
+sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices)
+{
+ struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
+ struct softpipe_context *softpipe = cvbr->softpipe;
+ struct draw_stage *setup = softpipe->setup;
+ struct prim_header prim;
+ unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float);
+ unsigned i, j;
+ void *vertex_buffer = cvbr->vertex_buffer;
+
+ prim.det = 0;
+ prim.reset_line_stipple = 0;
+ prim.edgeflags = 0;
+ prim.pad = 0;
+
+ switch (cvbr->prim) {
+ case PIPE_PRIM_TRIANGLES:
+ for (i = 0; i < nr_indices; i += 3) {
+ for (j = 0; j < 3; j++)
+ prim.v[j] = (struct vertex_header *)((char *)vertex_buffer +
+ indices[i+j] * vertex_size);
+
+ calc_det(&prim);
+ setup->tri( setup, &prim );
+ }
+ break;
+
+ case PIPE_PRIM_LINES:
+ for (i = 0; i < nr_indices; i += 2) {
+ for (j = 0; j < 2; j++)
+ prim.v[j] = (struct vertex_header *)((char *)vertex_buffer +
+ indices[i+j] * vertex_size);
+
+ setup->line( setup, &prim );
+ }
+ break;
+
+ case PIPE_PRIM_POINTS:
+ for (i = 0; i < nr_indices; i++) {
+ prim.v[0] = (struct vertex_header *)((char *)vertex_buffer +
+ indices[i] * vertex_size);
+ setup->point( setup, &prim );
+ }
+ break;
}
- stage->tri = vbuf_first_tri;
- stage->line = vbuf_first_line;
- stage->point = vbuf_first_point;
+ setup->flush( setup, 0 );
}
-static void vbuf_begin( struct draw_stage *stage )
+static void
+sp_vbuf_destroy(struct vbuf_render *vbr)
{
- struct vbuf_stage *vbuf = vbuf_stage(stage);
-
- vbuf->vertex_size = vbuf->draw_context->vertex_info.size * sizeof(float);
+ struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
+ cvbr->softpipe->vbuf_render = NULL;
+ FREE(cvbr);
}
-static void vbuf_end( struct draw_stage *stage )
-{
- /* Overkill.
- */
- vbuf_flush_elements( stage );
-}
-
-
-static void reset_stipple_counter( struct draw_stage *stage )
+/**
+ * Initialize the post-transform vertex buffer information for the given
+ * context.
+ */
+void
+sp_init_vbuf(struct softpipe_context *sp)
{
- /* XXX: This doesn't work.
- */
-}
+ assert(sp->draw);
+ sp->vbuf_render = CALLOC_STRUCT(softpipe_vbuf_render);
-static void vbuf_destroy( struct draw_stage *stage )
-{
- struct vbuf_stage *vbuf = vbuf_stage( stage );
+ sp->vbuf_render->base.max_indices = SP_MAX_VBUF_INDEXES;
+ sp->vbuf_render->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE;
- FREE( vbuf->element_map );
- FREE( vbuf->vertex_map );
- FREE( stage );
-}
+ sp->vbuf_render->base.get_vertex_info = sp_vbuf_get_vertex_info;
+ sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices;
+ sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive;
+ sp->vbuf_render->base.draw = sp_vbuf_draw;
+ sp->vbuf_render->base.release_vertices = sp_vbuf_release_vertices;
+ sp->vbuf_render->base.destroy = sp_vbuf_destroy;
+ sp->vbuf_render->softpipe = sp;
-/**
- * Create a new primitive vbuf/render stage.
- */
-struct draw_stage *sp_draw_vbuf_stage( struct draw_context *draw_context,
- struct pipe_context *pipe,
- vbuf_draw_func draw )
-{
- struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage);
-
- vbuf->stage.begin = vbuf_begin;
- vbuf->stage.point = vbuf_first_point;
- vbuf->stage.line = vbuf_first_line;
- vbuf->stage.tri = vbuf_first_tri;
- vbuf->stage.end = vbuf_end;
- vbuf->stage.reset_stipple_counter = reset_stipple_counter;
- vbuf->stage.destroy = vbuf_destroy;
-
- vbuf->pipe = pipe;
- vbuf->draw = draw;
- vbuf->draw_context = draw_context;
-
- vbuf->element_map = MALLOC( IBUF_SIZE );
- vbuf->vertex_map = MALLOC( VBUF_SIZE );
-
- vbuf->vertex_ptr = vbuf->vertex_map;
-
+ sp->vbuf = draw_vbuf_stage(sp->draw, &sp->vbuf_render->base);
- return &vbuf->stage;
+ draw_set_rasterize_stage(sp->draw, sp->vbuf);
}
diff --git a/src/mesa/pipe/pipebuffer/pb_buffer_null.c b/src/mesa/pipe/softpipe/sp_prim_vbuf.h
index a356c6b2d5..1de9cc2a89 100644
--- a/src/mesa/pipe/pipebuffer/pb_buffer_null.c
+++ b/src/mesa/pipe/softpipe/sp_prim_vbuf.h
@@ -1,8 +1,8 @@
/**************************************************************************
- *
+ *
* 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
@@ -10,11 +10,11 @@
* 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.
@@ -22,77 +22,17 @@
* 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
- * Null buffer implementation.
- *
- * We have a special null buffer object so that we can safely call buffer
- * operations without having to check whether the buffer pointer is null or not.
*
- * \author José Fonseca <jrfonseca@tungstengraphics.com>
- */
-
-
-#include "pipe/p_winsys.h"
-#include "pipe/p_defines.h"
-
-#include "pb_buffer.h"
-
-
-static void
-null_buffer_reference(struct pipe_buffer *buf)
-{
- /* No-op */
-}
-
-
-static void
-null_buffer_release(struct pipe_buffer *buf)
-{
- /* No-op */
-}
-
-
-static void *
-null_buffer_map(struct pipe_buffer *buf,
- unsigned flags)
-{
- assert(0);
- return NULL;
-}
-
-
-static void
-null_buffer_unmap(struct pipe_buffer *buf)
-{
- assert(0);
-}
+ **************************************************************************/
+#ifndef SP_VBUF_H
+#define SP_VBUF_H
-static void
-null_buffer_get_base_buffer(struct pipe_buffer *buf,
- struct pipe_buffer **base_buf,
- unsigned *offset)
-{
- *base_buf = buf;
- *offset = 0;
-}
+struct softpipe_context;
-const struct pipe_buffer_vtbl
-pipe_buffer_vtbl = {
- null_buffer_reference,
- null_buffer_release,
- null_buffer_map,
- null_buffer_unmap,
- null_buffer_get_base_buffer
-};
+extern void
+sp_init_vbuf(struct softpipe_context *softpipe);
-struct pipe_buffer
-null_buffer = {
- &pipe_buffer_vtbl
-};
+#endif /* SP_VBUF_H */
diff --git a/src/mesa/pipe/softpipe/sp_quad.c b/src/mesa/pipe/softpipe/sp_quad.c
index a10c9c3e02..6bd468a51c 100644
--- a/src/mesa/pipe/softpipe/sp_quad.c
+++ b/src/mesa/pipe/softpipe/sp_quad.c
@@ -48,7 +48,7 @@ sp_build_depth_stencil(
sp_push_quad_first( sp, sp->quad.stencil_test );
}
else if (sp->depth_stencil->depth.enabled &&
- sp->framebuffer.zbuf) {
+ sp->framebuffer.zsbuf) {
sp_push_quad_first( sp, sp->quad.depth_test );
}
}
@@ -58,7 +58,7 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
{
boolean early_depth_test =
sp->depth_stencil->depth.enabled &&
- sp->framebuffer.zbuf &&
+ sp->framebuffer.zsbuf &&
!sp->depth_stencil->alpha.enabled &&
sp->fs->shader.output_semantic_name[0] != TGSI_SEMANTIC_POSITION;
diff --git a/src/mesa/pipe/softpipe/sp_quad_depth_test.c b/src/mesa/pipe/softpipe/sp_quad_depth_test.c
index 1b8a2960af..a9a0754f27 100644
--- a/src/mesa/pipe/softpipe/sp_quad_depth_test.c
+++ b/src/mesa/pipe/softpipe/sp_quad_depth_test.c
@@ -53,14 +53,14 @@ void
sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
- struct pipe_surface *ps = softpipe->framebuffer.zbuf;
+ struct pipe_surface *ps = softpipe->framebuffer.zsbuf;
const enum pipe_format format = ps->format;
unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */
unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */
unsigned zmask = 0;
unsigned j;
struct softpipe_cached_tile *tile
- = sp_get_cached_tile(softpipe, softpipe->zbuf_cache, quad->x0, quad->y0);
+ = sp_get_cached_tile(softpipe, softpipe->zsbuf_cache, quad->x0, quad->y0);
assert(ps); /* shouldn't get here if there's no zbuffer */
diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c
index 0001c76a80..c9cc8afa0c 100644
--- a/src/mesa/pipe/softpipe/sp_quad_fs.c
+++ b/src/mesa/pipe/softpipe/sp_quad_fs.c
@@ -356,7 +356,12 @@ struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
qss->stage.softpipe = softpipe;
qss->stage.begin = shade_begin;
#ifdef MESA_LLVM
+ /* disable until ported to accept
+ * x/y and soa layout
qss->stage.run = shade_quad_llvm;
+ */
+ softpipe->use_sse = FALSE;
+ qss->stage.run = shade_quad;
#else
qss->stage.run = shade_quad;
#endif
diff --git a/src/mesa/pipe/softpipe/sp_quad_stencil.c b/src/mesa/pipe/softpipe/sp_quad_stencil.c
index 33740883d3..92a0da0083 100644
--- a/src/mesa/pipe/softpipe/sp_quad_stencil.c
+++ b/src/mesa/pipe/softpipe/sp_quad_stencil.c
@@ -201,12 +201,12 @@ static void
stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
- struct pipe_surface *ps = softpipe->framebuffer.sbuf;
+ struct pipe_surface *ps = softpipe->framebuffer.zsbuf;
unsigned func, zFailOp, zPassOp, failOp;
ubyte ref, wrtMask, valMask;
ubyte stencilVals[QUAD_SIZE];
struct softpipe_cached_tile *tile
- = sp_get_cached_tile(softpipe, softpipe->sbuf_cache, quad->x0, quad->y0);
+ = sp_get_cached_tile(softpipe, softpipe->zsbuf_cache, quad->x0, quad->y0);
uint j;
uint face = quad->facing;
diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h
index bac7b0876f..af955c1e17 100644
--- a/src/mesa/pipe/softpipe/sp_state.h
+++ b/src/mesa/pipe/softpipe/sp_state.h
@@ -157,7 +157,7 @@ boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
unsigned start, unsigned count);
boolean softpipe_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer_handle *indexBuffer,
+ struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count);
diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c
index 0f1410e5de..39c3e1afe1 100644
--- a/src/mesa/pipe/softpipe/sp_state_derived.c
+++ b/src/mesa/pipe/softpipe/sp_state_derived.c
@@ -29,14 +29,31 @@
#include "pipe/p_shader_tokens.h"
#include "pipe/draw/draw_context.h"
#include "pipe/draw/draw_vertex.h"
+#include "pipe/draw/draw_private.h"
#include "sp_context.h"
#include "sp_state.h"
+static int
+find_vs_output(const struct pipe_shader_state *vs,
+ uint semantic_name,
+ uint semantic_index)
+{
+ uint i;
+ for (i = 0; i < vs->num_outputs; i++) {
+ if (vs->output_semantic_name[i] == semantic_name &&
+ vs->output_semantic_index[i] == semantic_index)
+ return i;
+ }
+ return -1;
+}
+
+
+
/**
- * Determine which post-transform / pre-rasterization vertex attributes
- * we need.
- * Derived from: fs, setup states.
+ * Determine how to map vertex program outputs to fragment program inputs.
+ * Basically, this will be used when computing the triangle interpolation
+ * coefficients from the post-transform vertex attributes.
*/
static void calculate_vertex_layout( struct softpipe_context *softpipe )
{
@@ -45,76 +62,55 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
const enum interp_mode colorInterp
= softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
struct vertex_info *vinfo = &softpipe->vertex_info;
- boolean emitBack0 = FALSE, emitBack1 = FALSE, emitPsize = FALSE;
- uint front0 = 0, back0 = 0, front1 = 0, back1 = 0;
uint i;
- int src = 0;
-
- memset(vinfo, 0, sizeof(*vinfo));
-
- if (fs->input_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
- /* Need Z if depth test is enabled or the fragment program uses the
- * fragment position (XYZW).
+ if (softpipe->vbuf) {
+ /* if using the post-transform vertex buffer, tell draw_vbuf to
+ * simply emit the whole post-xform vertex as-is:
*/
+ struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
+ vinfo_vbuf->num_attribs = 0;
+ draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0);
+ vinfo_vbuf->size = 4 * vs->num_outputs + sizeof(struct vertex_header)/4;
}
- softpipe->psize_slot = -1;
-
- /* always emit vertex pos */
- draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR, src++);
-
/*
- * XXX I think we need to reconcile the vertex shader outputs with
- * the fragment shader inputs here to make sure the slots line up.
- * Might just be getting lucky so far.
- * Or maybe do that in the state tracker?
+ * Loop over fragment shader inputs, searching for the matching output
+ * from the vertex shader.
*/
-
- for (i = 0; i < vs->num_outputs; i++) {
- switch (vs->output_semantic_name[i]) {
-
+ vinfo->num_attribs = 0;
+ for (i = 0; i < fs->num_inputs; i++) {
+ int src;
+ switch (fs->input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
- /* vertex programs always emit position, but might not be
- * needed for fragment progs.
- */
- /* no-op */
+ src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
break;
case TGSI_SEMANTIC_COLOR:
- if (vs->output_semantic_index[i] == 0) {
- front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++);
- }
- else {
- assert(vs->output_semantic_index[i] == 1);
- front1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++);
- }
- break;
-
- case TGSI_SEMANTIC_BCOLOR:
- if (vs->output_semantic_index[i] == 0) {
- emitBack0 = TRUE;
- }
- else {
- assert(vs->output_semantic_index[i] == 1);
- emitBack1 = TRUE;
- }
+ src = find_vs_output(vs, TGSI_SEMANTIC_COLOR,
+ fs->input_semantic_index[i]);
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
break;
case TGSI_SEMANTIC_FOG:
- draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_PERSPECTIVE, src++);
- break;
-
- case TGSI_SEMANTIC_PSIZE:
- /* XXX only emit if drawing points or front/back polygon mode
- * is point mode
- */
- emitPsize = TRUE;
+ src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0);
+#if 1
+ if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
+ src = 0;
+#endif
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
break;
case TGSI_SEMANTIC_GENERIC:
/* this includes texcoords and varying vars */
- draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE, src++);
+ src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
+ fs->input_semantic_index[i]);
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
break;
default:
@@ -122,35 +118,13 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
}
}
- softpipe->nr_frag_attrs = fs->num_inputs;
-
- /* We want these after all other attribs since they won't get passed
- * to the fragment shader. All prior vertex output attribs should match
- * up 1:1 with the fragment shader inputs.
- */
- if (emitBack0) {
- back0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++);
+ softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
+ if (softpipe->psize_slot >= 0) {
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
+ softpipe->psize_slot);
}
- if (emitBack1) {
- back1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++);
- }
- if (emitPsize) {
- softpipe->psize_slot
- = draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_CONSTANT, src++);
- }
-
- /* If the attributes have changed, tell the draw module about
- * the new vertex layout.
- */
- /* XXX we also need to do this when the shading mode (interp modes) change: */
- if (1/*vinfo->attr_mask != softpipe->attr_mask*/) {
- /*softpipe->attr_mask = vinfo->attr_mask;*/
-
- draw_set_vertex_info( softpipe->draw, vinfo);
- draw_set_twoside_attributes(softpipe->draw,
- front0, back0, front1, back1);
- }
+ draw_compute_vertex_size(vinfo);
}
@@ -194,7 +168,9 @@ compute_cliprect(struct softpipe_context *sp)
*/
void softpipe_update_derived( struct softpipe_context *softpipe )
{
- if (softpipe->dirty & (SP_NEW_RASTERIZER | SP_NEW_FS))
+ if (softpipe->dirty & (SP_NEW_RASTERIZER |
+ SP_NEW_FS |
+ SP_NEW_VS))
calculate_vertex_layout( softpipe );
if (softpipe->dirty & (SP_NEW_SCISSOR |
diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c
index 945c93411f..1430be7869 100644
--- a/src/mesa/pipe/softpipe/sp_state_fs.c
+++ b/src/mesa/pipe/softpipe/sp_state_fs.c
@@ -30,6 +30,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_winsys.h"
#include "pipe/draw/draw_context.h"
#include "pipe/p_shader_tokens.h"
@@ -165,9 +166,9 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
assert(index == 0);
/* note: reference counting */
- ws->buffer_reference(ws,
- &softpipe->constants[shader].buffer,
- buf->buffer);
+ pipe_buffer_reference(ws,
+ &softpipe->constants[shader].buffer,
+ buf->buffer);
softpipe->constants[shader].size = buf->size;
softpipe->dirty |= SP_NEW_CONSTANTS;
diff --git a/src/mesa/pipe/softpipe/sp_state_surface.c b/src/mesa/pipe/softpipe/sp_state_surface.c
index 4a9a28cc4d..e2c6893e9f 100644
--- a/src/mesa/pipe/softpipe/sp_state_surface.c
+++ b/src/mesa/pipe/softpipe/sp_state_surface.c
@@ -65,17 +65,18 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
sp->framebuffer.num_cbufs = fb->num_cbufs;
/* zbuf changing? */
- if (sp->framebuffer.zbuf != fb->zbuf) {
+ if (sp->framebuffer.zsbuf != fb->zsbuf) {
/* flush old */
- sp_flush_tile_cache(sp, sp->zbuf_cache);
+ sp_flush_tile_cache(sp, sp->zsbuf_cache);
/* assign new */
- sp->framebuffer.zbuf = fb->zbuf;
+ sp->framebuffer.zsbuf = fb->zsbuf;
/* update cache */
- sp_tile_cache_set_surface(sp->zbuf_cache, fb->zbuf);
+ sp_tile_cache_set_surface(sp->zsbuf_cache, fb->zsbuf);
}
+#if 0
/* XXX combined depth/stencil here */
/* sbuf changing? */
@@ -98,6 +99,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf);
}
}
+#endif
sp->dirty |= SP_NEW_FRAMEBUFFER;
}
diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c
index e115705507..5978ee48bd 100644
--- a/src/mesa/pipe/softpipe/sp_surface.c
+++ b/src/mesa/pipe/softpipe/sp_surface.c
@@ -34,27 +34,6 @@
#include "sp_surface.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
-sp_surface_data(struct pipe_context *pipe,
- struct pipe_surface *dst,
- unsigned dstx, unsigned dsty,
- const void *src, unsigned src_pitch,
- unsigned srcx, unsigned srcy, unsigned width, unsigned height)
-{
- pipe_copy_rect(pipe_surface_map(dst),
- dst->cpp,
- dst->pitch,
- dstx, dsty, width, height, src, src_pitch, srcx, srcy);
-
- pipe_surface_unmap(dst);
-}
/* Assumes all values are within bounds -- no checking at this level -
* do it higher up if required.
@@ -174,10 +153,6 @@ sp_surface_fill(struct pipe_context *pipe,
void
sp_init_surface_functions(struct softpipe_context *sp)
{
- sp->pipe.get_tile = pipe_get_tile_raw;
- sp->pipe.put_tile = pipe_put_tile_raw;
-
- sp->pipe.surface_data = sp_surface_data;
sp->pipe.surface_copy = sp_surface_copy;
sp->pipe.surface_fill = sp_surface_fill;
}
diff --git a/src/mesa/pipe/softpipe/sp_texture.c b/src/mesa/pipe/softpipe/sp_texture.c
index d43a6996e9..172234843d 100644
--- a/src/mesa/pipe/softpipe/sp_texture.c
+++ b/src/mesa/pipe/softpipe/sp_texture.c
@@ -91,12 +91,9 @@ softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
softpipe_texture_layout(spt);
- spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32, 0, 0);
-
- if (spt->buffer) {
- pipe->winsys->buffer_data(pipe->winsys, spt->buffer, spt->buffer_size,
- NULL, PIPE_BUFFER_USAGE_PIXEL);
- }
+ spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32,
+ PIPE_BUFFER_USAGE_PIXEL,
+ spt->buffer_size);
if (!spt->buffer) {
FREE(spt);
@@ -124,7 +121,7 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
*/
- pipe->winsys->buffer_reference(pipe->winsys, &spt->buffer, NULL);
+ pipe_buffer_reference(pipe->winsys, &spt->buffer, NULL);
FREE(spt);
}
@@ -147,7 +144,7 @@ softpipe_get_tex_surface(struct pipe_context *pipe,
if (ps) {
assert(ps->refcount);
assert(ps->winsys);
- pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, spt->buffer);
+ pipe_buffer_reference(pipe->winsys, &ps->buffer, spt->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
ps->width = pt->width[level];
diff --git a/src/mesa/pipe/softpipe/sp_texture.h b/src/mesa/pipe/softpipe/sp_texture.h
index 0494bf365b..c6cf370351 100644
--- a/src/mesa/pipe/softpipe/sp_texture.h
+++ b/src/mesa/pipe/softpipe/sp_texture.h
@@ -41,7 +41,7 @@ struct softpipe_texture
/* The data is held here:
*/
- struct pipe_buffer_handle *buffer;
+ struct pipe_buffer *buffer;
unsigned long buffer_size;
};
diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c
index 1974f77459..451e157abf 100644
--- a/src/mesa/pipe/softpipe/sp_tile_cache.c
+++ b/src/mesa/pipe/softpipe/sp_tile_cache.c
@@ -329,7 +329,7 @@ sp_tile_cache_flush_clear(struct pipe_context *pipe,
for (y = 0; y < h; y += TILE_SIZE) {
for (x = 0; x < w; x += TILE_SIZE) {
if (is_clear_flag_set(tc->clear_flags, x, y)) {
- pipe->put_tile(pipe, ps,
+ pipe_put_tile_raw(pipe, ps,
x, y, TILE_SIZE, TILE_SIZE,
tc->tile.data.color32, 0/*STRIDE*/);
@@ -365,7 +365,7 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,
struct softpipe_cached_tile *tile = tc->entries + pos;
if (tile->x >= 0) {
if (tc->depth_stencil) {
- pipe->put_tile(pipe, ps,
+ pipe_put_tile_raw(pipe, ps,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
@@ -414,7 +414,7 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
if (tile->x != -1) {
/* put dirty tile back in framebuffer */
if (tc->depth_stencil) {
- pipe->put_tile(pipe, ps,
+ pipe_put_tile_raw(pipe, ps,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
@@ -441,7 +441,7 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
else {
/* get new tile data from surface */
if (tc->depth_stencil) {
- pipe->get_tile(pipe, ps,
+ pipe_put_tile_raw(pipe, ps,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
@@ -538,6 +538,7 @@ void
sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue)
{
uint r, g, b, a;
+ uint pos;
tc->clear_val = clearValue;
@@ -576,4 +577,9 @@ sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue)
/* disable the optimization */
memset(tc->clear_flags, 0, sizeof(tc->clear_flags));
#endif
+
+ for (pos = 0; pos < NUM_ENTRIES; pos++) {
+ struct softpipe_cached_tile *tile = tc->entries + pos;
+ tile->x = tile->y = -1;
+ }
}
diff --git a/src/mesa/pipe/util/p_tile.c b/src/mesa/pipe/util/p_tile.c
index 85a863db8a..3f795a3898 100644
--- a/src/mesa/pipe/util/p_tile.c
+++ b/src/mesa/pipe/util/p_tile.c
@@ -577,7 +577,7 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
if (!packed)
return;
- pipe->get_tile(pipe, ps, x, y, w, h, packed, w * ps->cpp);
+ pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp);
switch (ps->format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
@@ -693,7 +693,7 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
assert(0);
}
- pipe->put_tile(pipe, ps, x, y, w, h, packed, w * ps->cpp);
+ pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp);
FREE(packed);
}
diff --git a/src/mesa/pipe/xlib/fakeglx.c b/src/mesa/pipe/xlib/fakeglx.c
index 6965ee0794..902a755075 100644
--- a/src/mesa/pipe/xlib/fakeglx.c
+++ b/src/mesa/pipe/xlib/fakeglx.c
@@ -419,7 +419,7 @@ static XMesaVisual
create_glx_visual( Display *dpy, XVisualInfo *visinfo )
{
int vislevel;
- GLint zBits = default_depth_bits();
+ GLint zBits = 24; /*default_depth_bits();*/
GLint accBits = default_accum_bits();
GLboolean alphaFlag = default_alpha_bits() > 0;
@@ -1289,7 +1289,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
double_flag = GL_TRUE;
if (vis->depth > 8)
rgb_flag = GL_TRUE;
- depth_size = default_depth_bits();
+ depth_size = 24; /*default_depth_bits();*/
stencil_size = STENCIL_BITS;
/* XXX accum??? */
}
@@ -1336,7 +1336,9 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
* largest depth buffer size, which is 32bits/value. Instead, we
* return 16 to maintain performance with earlier versions of Mesa.
*/
- if (depth_size > 24)
+ if (stencil_size > 0)
+ depth_size = 24; /* if Z and stencil, always use 24+8 format */
+ else if (depth_size > 24)
depth_size = 32;
else if (depth_size > 16)
depth_size = 24;
diff --git a/src/mesa/pipe/xlib/xm_winsys.c b/src/mesa/pipe/xlib/xm_winsys.c
index 10dc09b13c..c3cd22eea3 100644
--- a/src/mesa/pipe/xlib/xm_winsys.c
+++ b/src/mesa/pipe/xlib/xm_winsys.c
@@ -40,6 +40,7 @@
#include "pipe/p_format.h"
#include "pipe/p_context.h"
#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
#include "pipe/softpipe/sp_winsys.h"
#ifdef GALLIUM_CELL
@@ -57,9 +58,8 @@
*/
struct xm_buffer
{
+ struct pipe_buffer base;
boolean userBuffer; /** Is this a user-space buffer? */
- int refcount;
- unsigned size;
void *data;
void *mapped;
};
@@ -106,105 +106,44 @@ xmesa_softpipe_winsys(struct softpipe_winsys *spws)
* buffer pointer...
*/
static INLINE struct xm_buffer *
-xm_bo( struct pipe_buffer_handle *bo )
+xm_buffer( struct pipe_buffer *buf )
{
- return (struct xm_buffer *) bo;
+ return (struct xm_buffer *)buf;
}
-static INLINE struct pipe_buffer_handle *
-pipe_bo( struct xm_buffer *bo )
-{
- return (struct pipe_buffer_handle *) bo;
-}
/* Most callbacks map direcly onto dri_bufmgr operations:
*/
static void *
-xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
+xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
unsigned flags)
{
- struct xm_buffer *xm_buf = xm_bo(buf);
+ struct xm_buffer *xm_buf = xm_buffer(buf);
xm_buf->mapped = xm_buf->data;
return xm_buf->mapped;
}
static void
-xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer_handle *buf)
+xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
{
- struct xm_buffer *xm_buf = xm_bo(buf);
+ struct xm_buffer *xm_buf = xm_buffer(buf);
xm_buf->mapped = NULL;
}
static void
-xm_buffer_reference(struct pipe_winsys *pws,
- struct pipe_buffer_handle **ptr,
- struct pipe_buffer_handle *buf)
+xm_buffer_destroy(struct pipe_winsys *pws,
+ struct pipe_buffer *buf)
{
- if (*ptr) {
- struct xm_buffer *oldBuf = xm_bo(*ptr);
- oldBuf->refcount--;
- assert(oldBuf->refcount >= 0);
- if (oldBuf->refcount == 0) {
- if (oldBuf->data) {
- if (!oldBuf->userBuffer)
- align_free(oldBuf->data);
- oldBuf->data = NULL;
- }
- free(oldBuf);
- }
- *ptr = NULL;
- }
+ struct xm_buffer *oldBuf = xm_buffer(buf);
- assert(!(*ptr));
-
- if (buf) {
- struct xm_buffer *newBuf = xm_bo(buf);
- newBuf->refcount++;
- *ptr = buf;
+ if (oldBuf->data) {
+ if (!oldBuf->userBuffer)
+ align_free(oldBuf->data);
+ oldBuf->data = NULL;
}
-}
-static int
-xm_buffer_data(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
- unsigned size, const void *data, unsigned usage )
-{
- struct xm_buffer *xm_buf = xm_bo(buf);
- assert(!xm_buf->userBuffer);
- if (xm_buf->size != size) {
- if (xm_buf->data)
- align_free(xm_buf->data);
- /* align to 16-byte multiple for Cell */
- xm_buf->data = align_malloc(size, 16);
- xm_buf->size = size;
- }
- if (data)
- memcpy(xm_buf->data, data, size);
- return 0;
-}
-
-static int
-xm_buffer_subdata(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
- unsigned long offset, unsigned long size, const void *data)
-{
- struct xm_buffer *xm_buf = xm_bo(buf);
- GLubyte *b = (GLubyte *) xm_buf->data;
- assert(!xm_buf->userBuffer);
- assert(b);
- memcpy(b + offset, data, size);
- return 0;
-}
-
-static int
-xm_buffer_get_subdata(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
- unsigned long offset, unsigned long size, void *data)
-{
- const struct xm_buffer *xm_buf = xm_bo(buf);
- const GLubyte *b = (GLubyte *) xm_buf->data;
- assert(!xm_buf->userBuffer);
- assert(b);
- memcpy(data, b + offset, size);
- return 0;
+ free(oldBuf);
}
@@ -216,7 +155,7 @@ static void
xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf)
{
XImage *ximage = b->tempImage;
- struct xm_buffer *xm_buf = xm_bo(surf->buffer);
+ struct xm_buffer *xm_buf = xm_buffer(surf->buffer);
const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE;
uint x, y;
@@ -256,7 +195,7 @@ void
xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf)
{
XImage *ximage = b->tempImage;
- struct xm_buffer *xm_buf = xm_bo(surf->buffer);
+ struct xm_buffer *xm_buf = xm_buffer(surf->buffer);
const struct xmesa_surface *xm_surf
= xmesa_surface((struct pipe_surface *) surf);
@@ -314,30 +253,38 @@ xm_get_name(struct pipe_winsys *pws)
}
-static struct pipe_buffer_handle *
+static struct pipe_buffer *
xm_buffer_create(struct pipe_winsys *pws,
unsigned alignment,
- unsigned flags,
- unsigned hints)
+ unsigned usage,
+ unsigned size)
{
struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
- buffer->refcount = 1;
- return pipe_bo(buffer);
+ buffer->base.refcount = 1;
+ buffer->base.alignment = alignment;
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ /* align to 16-byte multiple for Cell */
+ buffer->data = align_malloc(size, max(alignment, 16));
+
+ return &buffer->base;
}
/**
* Create buffer which wraps user-space data.
*/
-static struct pipe_buffer_handle *
+static struct pipe_buffer *
xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
{
struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
+ buffer->base.refcount = 1;
+ buffer->base.size = bytes;
buffer->userBuffer = TRUE;
- buffer->refcount = 1;
buffer->data = ptr;
- buffer->size = bytes;
- return pipe_bo(buffer);
+
+ return &buffer->base;
}
@@ -359,7 +306,6 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys,
unsigned flags)
{
const unsigned alignment = 64;
- int ret;
surf->width = width;
surf->height = height;
@@ -372,19 +318,11 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys,
#endif
assert(!surf->buffer);
- surf->buffer = winsys->buffer_create(winsys, alignment, 0, 0);
+ surf->buffer = winsys->buffer_create(winsys, alignment,
+ PIPE_BUFFER_USAGE_PIXEL,
+ surf->pitch * surf->cpp * height);
if(!surf->buffer)
return -1;
-
- ret = winsys->buffer_data(winsys,
- surf->buffer,
- surf->pitch * surf->cpp * height,
- NULL,
- 0);
- if(ret) {
- winsys->buffer_reference(winsys, &surf->buffer, NULL);
- return ret;
- }
return 0;
}
@@ -405,7 +343,7 @@ xm_surface_alloc(struct pipe_winsys *ws)
xms->surface.winsys = ws;
#ifdef GALLIUM_CELL
- if (getenv("GALLIUM_CELL")) {
+ if (!getenv("GALLIUM_NOCELL")) {
xms->tileSize = 32; /** probably temporary */
}
#endif
@@ -422,7 +360,7 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
surf->refcount--;
if (surf->refcount == 0) {
if (surf->buffer)
- winsys->buffer_reference(winsys, &surf->buffer, NULL);
+ pipe_buffer_reference(winsys, &surf->buffer, NULL);
free(surf);
}
*s = NULL;
@@ -453,10 +391,7 @@ xmesa_get_pipe_winsys_aub(void)
ws->user_buffer_create = xm_user_buffer_create;
ws->buffer_map = xm_buffer_map;
ws->buffer_unmap = xm_buffer_unmap;
- ws->buffer_reference = xm_buffer_reference;
- ws->buffer_data = xm_buffer_data;
- ws->buffer_subdata = xm_buffer_subdata;
- ws->buffer_get_subdata = xm_buffer_get_subdata;
+ ws->buffer_destroy = xm_buffer_destroy;
ws->surface_alloc = xm_surface_alloc;
ws->surface_alloc_storage = xm_surface_alloc_storage;
@@ -511,7 +446,7 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat)
struct pipe_context *pipe;
#ifdef GALLIUM_CELL
- if (getenv("GALLIUM_CELL")) {
+ if (!getenv("GALLIUM_NOCELL")) {
struct cell_winsys *cws = cell_get_winsys(pixelformat);
pipe = cell_create_context(pws, cws);
if (pipe)
diff --git a/src/mesa/pipe/xlib/xm_winsys_aub.c b/src/mesa/pipe/xlib/xm_winsys_aub.c
index 2be8f8793d..bf41570257 100644
--- a/src/mesa/pipe/xlib/xm_winsys_aub.c
+++ b/src/mesa/pipe/xlib/xm_winsys_aub.c
@@ -38,6 +38,7 @@
#include "pipe/p_winsys.h"
#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
#include "pipe/i965simple/brw_winsys.h"
#include "brw_aub.h"
#include "xm_winsys_aub.h"
@@ -79,29 +80,29 @@ aub_pipe_winsys( struct pipe_winsys *winsys )
static INLINE struct aub_buffer *
-aub_bo( struct pipe_buffer_handle *bo )
+aub_bo( struct pipe_buffer *bo )
{
return (struct aub_buffer *)bo;
}
-static INLINE struct pipe_buffer_handle *
+static INLINE struct pipe_buffer *
pipe_bo( struct aub_buffer *bo )
{
- return (struct pipe_buffer_handle *)bo;
+ return (struct pipe_buffer *)bo;
}
static void *aub_buffer_map(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned flags )
{
struct aub_buffer *sbo = aub_bo(buf);
assert(sbo->data);
- if (flags & PIPE_BUFFER_FLAG_WRITE)
+ if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
sbo->dump_on_unmap = 1;
sbo->map_count++;
@@ -109,7 +110,7 @@ static void *aub_buffer_map(struct pipe_winsys *winsys,
}
static void aub_buffer_unmap(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf)
+ struct pipe_buffer *buf)
{
struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys);
struct aub_buffer *sbo = aub_bo(buf);
@@ -132,81 +133,15 @@ static void aub_buffer_unmap(struct pipe_winsys *winsys,
static void
-aub_buffer_reference(struct pipe_winsys *winsys,
- struct pipe_buffer_handle **ptr,
- struct pipe_buffer_handle *buf)
+aub_buffer_destroy(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf)
{
- if (*ptr) {
- assert(aub_bo(*ptr)->refcount != 0);
- if (--(aub_bo(*ptr)->refcount) == 0)
- free(*ptr);
- *ptr = NULL;
- }
-
- if (buf) {
- aub_bo(buf)->refcount++;
- *ptr = buf;
- }
-}
-
-
-static int aub_buffer_data(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf,
- unsigned size, const void *data,
- unsigned usage )
-{
- struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys);
- struct aub_buffer *sbo = aub_bo(buf);
-
- /* Could reuse buffers that are not referenced in current
- * batchbuffer. Can't do that atm, so always reallocate:
- */
- if (1 || sbo->size < size) {
- assert(iws->used + size < iws->size);
- sbo->data = iws->pool + iws->used;
- sbo->offset = AUB_BUF_START + iws->used;
- iws->used += align(size, 4096);
- }
-
- sbo->size = size;
-
- if (data != NULL) {
- memcpy(sbo->data, data, size);
-
- brw_aub_gtt_data( iws->aubfile,
- sbo->offset,
- sbo->data,
- sbo->size,
- 0,
- 0 );
- }
- return 0;
-}
-
-static int aub_buffer_subdata(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf,
- unsigned long offset,
- unsigned long size,
- const void *data)
-{
- struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys);
- struct aub_buffer *sbo = aub_bo(buf);
-
- assert(sbo->size > offset + size);
- memcpy(sbo->data + offset, data, size);
-
- brw_aub_gtt_data( iws->aubfile,
- sbo->offset + offset,
- sbo->data + offset,
- size,
- 0,
- 0 );
- return 0;
+ free(buf);
}
void xmesa_buffer_subdata_aub(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned long offset,
unsigned long size,
const void *data,
@@ -258,47 +193,45 @@ void xmesa_display_aub( /* struct pipe_winsys *winsys, */
-static int aub_buffer_get_subdata(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf,
- unsigned long offset,
- unsigned long size,
- void *data)
-{
- struct aub_buffer *sbo = aub_bo(buf);
- assert(sbo->size >= offset + size);
- memcpy(data, sbo->data + offset, size);
- return 0;
-}
-
/* Pipe has no concept of pools. We choose the tex/region pool
* for all buffers.
*/
-static struct pipe_buffer_handle *
+static struct pipe_buffer *
aub_buffer_create(struct pipe_winsys *winsys,
- unsigned alignment,
- unsigned flags,
- unsigned hint)
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
{
+ struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys);
struct aub_buffer *sbo = CALLOC_STRUCT(aub_buffer);
+
sbo->refcount = 1;
+
+ /* Could reuse buffers that are not referenced in current
+ * batchbuffer. Can't do that atm, so always reallocate:
+ */
+ assert(iws->used + size < iws->size);
+ sbo->data = iws->pool + iws->used;
+ sbo->offset = AUB_BUF_START + iws->used;
+ iws->used += align(size, 4096);
+
+ sbo->size = size;
+
return pipe_bo(sbo);
}
-static struct pipe_buffer_handle *
+static struct pipe_buffer *
aub_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
{
- struct aub_buffer *sbo = CALLOC_STRUCT(aub_buffer);
-
- sbo->refcount = 1;
+ struct aub_buffer *sbo;
/* Lets hope this is meant for upload, not as a result!
*/
- aub_buffer_data( winsys,
- pipe_bo(sbo),
- bytes,
- ptr,
- 0 );
+ sbo = aub_bo(aub_buffer_create( winsys, 0, 0, 0 ));
+
+ sbo->data = ptr;
+ sbo->size = bytes;
return pipe_bo(sbo);
}
@@ -345,7 +278,6 @@ aub_i915_surface_alloc_storage(struct pipe_winsys *winsys,
unsigned flags)
{
const unsigned alignment = 64;
- int ret;
surf->width = width;
surf->height = height;
@@ -354,20 +286,12 @@ aub_i915_surface_alloc_storage(struct pipe_winsys *winsys,
surf->pitch = round_up(width, alignment / surf->cpp);
assert(!surf->buffer);
- surf->buffer = winsys->buffer_create(winsys, alignment, 0, 0);
+ surf->buffer = winsys->buffer_create(winsys, alignment,
+ PIPE_BUFFER_USAGE_PIXEL,
+ surf->pitch * surf->cpp * height);
if(!surf->buffer)
return -1;
- ret = winsys->buffer_data(winsys,
- surf->buffer,
- surf->pitch * surf->cpp * height,
- NULL,
- 0);
- if(ret) {
- winsys->buffer_reference(winsys, &surf->buffer, NULL);
- return ret;
- }
-
return 0;
}
@@ -378,7 +302,7 @@ aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
surf->refcount--;
if (surf->refcount == 0) {
if (surf->buffer)
- winsys->buffer_reference(winsys, &surf->buffer, NULL);
+ pipe_buffer_reference(winsys, &surf->buffer, NULL);
free(surf);
}
*s = NULL;
@@ -417,10 +341,7 @@ xmesa_create_pipe_winsys_aub( void )
iws->winsys.user_buffer_create = aub_user_buffer_create;
iws->winsys.buffer_map = aub_buffer_map;
iws->winsys.buffer_unmap = aub_buffer_unmap;
- iws->winsys.buffer_reference = aub_buffer_reference;
- iws->winsys.buffer_data = aub_buffer_data;
- iws->winsys.buffer_subdata = aub_buffer_subdata;
- iws->winsys.buffer_get_subdata = aub_buffer_get_subdata;
+ iws->winsys.buffer_destroy = aub_buffer_destroy;
iws->winsys.flush_frontbuffer = aub_flush_frontbuffer;
iws->winsys.printf = aub_printf;
iws->winsys.get_name = aub_get_name;
@@ -466,9 +387,10 @@ struct aub_brw_winsys {
struct pipe_winsys *pipe_winsys;
- unsigned data[IWS_BATCHBUFFER_SIZE];
- unsigned nr;
- unsigned size;
+ unsigned batch_data[IWS_BATCHBUFFER_SIZE];
+ unsigned batch_nr;
+ unsigned batch_size;
+ unsigned batch_alloc;
};
@@ -490,9 +412,10 @@ static unsigned *aub_i965_batch_start( struct brw_winsys *sws,
{
struct aub_brw_winsys *iws = aub_brw_winsys(sws);
- if (iws->size < iws->nr + dwords)
+ if (iws->batch_size < iws->batch_nr + dwords)
return NULL;
+ iws->batch_alloc = iws->batch_nr + dwords;
return (void *)1; /* not a valid pointer! */
}
@@ -501,45 +424,55 @@ static void aub_i965_batch_dword( struct brw_winsys *sws,
{
struct aub_brw_winsys *iws = aub_brw_winsys(sws);
- iws->data[iws->nr++] = dword;
+ assert(iws->batch_nr < iws->batch_alloc);
+ iws->batch_data[iws->batch_nr++] = dword;
}
static void aub_i965_batch_reloc( struct brw_winsys *sws,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned access_flags,
unsigned delta )
{
struct aub_brw_winsys *iws = aub_brw_winsys(sws);
- iws->data[iws->nr++] = aub_bo(buf)->offset + delta;
+ assert(iws->batch_nr < iws->batch_alloc);
+ iws->batch_data[iws->batch_nr++] = aub_bo(buf)->offset + delta;
}
static unsigned aub_i965_get_buffer_offset( struct brw_winsys *sws,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned access_flags )
{
return aub_bo(buf)->offset;
}
+static void aub_i965_batch_end( struct brw_winsys *sws )
+{
+ struct aub_brw_winsys *iws = aub_brw_winsys(sws);
+ assert(iws->batch_nr <= iws->batch_alloc);
+ iws->batch_alloc = 0;
+}
static void aub_i965_batch_flush( struct brw_winsys *sws,
struct pipe_fence_handle **fence )
{
struct aub_brw_winsys *iws = aub_brw_winsys(sws);
- assert(iws->nr <= iws->size);
+ assert(iws->batch_nr <= iws->batch_size);
- if (iws->nr)
+ if (iws->batch_nr) {
xmesa_commands_aub( iws->pipe_winsys,
- iws->data,
- iws->nr );
- iws->nr = 0;
+ iws->batch_data,
+ iws->batch_nr );
+ }
+
+ iws->batch_nr = 0;
}
static void aub_i965_buffer_subdata_typed(struct brw_winsys *winsys,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned long offset,
unsigned long size,
const void *data,
@@ -639,13 +572,14 @@ xmesa_create_i965simple( struct pipe_winsys *winsys )
iws->winsys.batch_start = aub_i965_batch_start;
iws->winsys.batch_dword = aub_i965_batch_dword;
iws->winsys.batch_reloc = aub_i965_batch_reloc;
+ iws->winsys.batch_end = aub_i965_batch_end;
iws->winsys.batch_flush = aub_i965_batch_flush;
iws->winsys.buffer_subdata_typed = aub_i965_buffer_subdata_typed;
iws->winsys.get_buffer_offset = aub_i965_get_buffer_offset;
iws->pipe_winsys = winsys;
- iws->size = IWS_BATCHBUFFER_SIZE;
+ iws->batch_size = IWS_BATCHBUFFER_SIZE;
/* Create the i965simple context:
*/
diff --git a/src/mesa/pipe/xlib/xm_winsys_aub.h b/src/mesa/pipe/xlib/xm_winsys_aub.h
index c0fe449107..7bee199116 100644
--- a/src/mesa/pipe/xlib/xm_winsys_aub.h
+++ b/src/mesa/pipe/xlib/xm_winsys_aub.h
@@ -30,7 +30,7 @@
struct pipe_context;
struct pipe_winsys;
-struct pipe_buffer_handle;
+struct pipe_buffer;
struct pipe_surface;
struct pipe_winsys *
@@ -47,7 +47,7 @@ xmesa_create_i965simple( struct pipe_winsys *winsys );
void xmesa_buffer_subdata_aub(struct pipe_winsys *winsys,
- struct pipe_buffer_handle *buf,
+ struct pipe_buffer *buf,
unsigned long offset,
unsigned long size,
const void *data,
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index 57f5ec68d2..21416da2e0 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -37,6 +37,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_winsys.h"
+#include "pipe/p_inlines.h"
#include "st_context.h"
#include "st_atom.h"
@@ -69,8 +70,13 @@ void st_upload_constants( struct st_context *st,
_mesa_load_state_parameters(st->ctx, params);
- if (!cbuf->buffer)
- cbuf->buffer = ws->buffer_create(ws, 1, 0, 0);
+ if (cbuf->buffer && cbuf->size != paramBytes)
+ pipe_buffer_reference( ws, &cbuf->buffer, NULL );
+
+ if (!cbuf->buffer) {
+ cbuf->buffer = ws->buffer_create(ws, 1, PIPE_BUFFER_USAGE_CONSTANT,
+ paramBytes);
+ }
if (0)
{
@@ -80,8 +86,11 @@ void st_upload_constants( struct st_context *st,
}
/* load Mesa constants into the constant buffer */
- ws->buffer_data(ws, cbuf->buffer, paramBytes, params->ParameterValues,
- PIPE_BUFFER_USAGE_CONSTANT);
+ if (cbuf->buffer) {
+ memcpy(ws->buffer_map(ws, cbuf->buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
+ params->ParameterValues, paramBytes);
+ ws->buffer_unmap(ws, cbuf->buffer);
+ }
cbuf->size = paramBytes;
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index aec51f5eed..3e58d49f1f 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -65,14 +65,15 @@ update_framebuffer_state( struct st_context *st )
if (strb) {
strb = st_renderbuffer(strb->Base.Wrapped);
assert(strb->surface);
- framebuffer.zbuf = strb->surface;
+ framebuffer.zsbuf = strb->surface;
}
-
- strb = st_renderbuffer(fb->Attachment[BUFFER_STENCIL].Renderbuffer);
- if (strb) {
- strb = st_renderbuffer(strb->Base.Wrapped);
- assert(strb->surface);
- framebuffer.sbuf = strb->surface;
+ else {
+ strb = st_renderbuffer(fb->Attachment[BUFFER_STENCIL].Renderbuffer);
+ if (strb) {
+ strb = st_renderbuffer(strb->Base.Wrapped);
+ assert(strb->surface);
+ framebuffer.zsbuf = strb->surface;
+ }
}
/* XXX: The memcmp is insufficient for eliminating redundant state changes,
diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c
index beae36bca0..435d604af7 100644
--- a/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -74,6 +74,7 @@ static void update_raster_state( struct st_context *st )
GLcontext *ctx = st->ctx;
struct pipe_rasterizer_state raster;
const struct cso_rasterizer *cso;
+ const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current;
uint i;
memset(&raster, 0, sizeof(raster));
@@ -210,7 +211,19 @@ static void update_raster_state( struct st_context *st )
raster.sprite_coord_mode[i] = PIPE_SPRITE_COORD_NONE;
}
}
- raster.point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled;
+ if (vertProg) {
+ if (vertProg->Base.Id == 0) {
+ if (vertProg->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ)) {
+ /* generated program which emits point size */
+ raster.point_size_per_vertex = TRUE;
+ }
+ }
+ else if (ctx->VertexProgram.PointSizeEnabled) {
+ /* user-defined program and GL_VERTEX_PROGRAM_POINT_SIZE set */
+ raster.point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled;
+ }
+ }
+
/* _NEW_LINE
*/
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
index 872248cdb5..fa1254ff7c 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -36,6 +36,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_winsys.h"
+#include "pipe/p_inlines.h"
@@ -55,7 +56,6 @@
static struct gl_buffer_object *
st_bufferobj_alloc(GLcontext *ctx, GLuint name, GLenum target)
{
- struct st_context *st = st_context(ctx);
struct st_buffer_object *st_obj = CALLOC_STRUCT(st_buffer_object);
if (!st_obj)
@@ -63,8 +63,6 @@ st_bufferobj_alloc(GLcontext *ctx, GLuint name, GLenum target)
_mesa_initialize_buffer_object(&st_obj->Base, name, target);
- st_obj->buffer = st->pipe->winsys->buffer_create( st->pipe->winsys, 32, 0, 0 );
-
return &st_obj->Base;
}
@@ -81,7 +79,7 @@ st_bufferobj_free(GLcontext *ctx, struct gl_buffer_object *obj)
struct st_buffer_object *st_obj = st_buffer_object(obj);
if (st_obj->buffer)
- pipe->winsys->buffer_reference(pipe->winsys, &st_obj->buffer, NULL);
+ pipe_buffer_reference(pipe->winsys, &st_obj->buffer, NULL);
free(st_obj);
}
@@ -89,6 +87,57 @@ st_bufferobj_free(GLcontext *ctx, struct gl_buffer_object *obj)
/**
+ * Replace data in a subrange of buffer object. If the data range
+ * specified by size + offset extends beyond the end of the buffer or
+ * if data is NULL, no copy is performed.
+ * Called via glBufferSubDataARB().
+ */
+static void
+st_bufferobj_subdata(GLcontext *ctx,
+ GLenum target,
+ GLintptrARB offset,
+ GLsizeiptrARB size,
+ const GLvoid * data, struct gl_buffer_object *obj)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+ struct st_buffer_object *st_obj = st_buffer_object(obj);
+ char *map;
+
+ if (offset >= st_obj->size || size > (st_obj->size - offset))
+ return;
+
+ map = pipe->winsys->buffer_map(pipe->winsys, st_obj->buffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ memcpy(map + offset, data, size);
+ pipe->winsys->buffer_unmap(pipe->winsys, st_obj->buffer);
+}
+
+
+/**
+ * Called via glGetBufferSubDataARB().
+ */
+static void
+st_bufferobj_get_subdata(GLcontext *ctx,
+ GLenum target,
+ GLintptrARB offset,
+ GLsizeiptrARB size,
+ GLvoid * data, struct gl_buffer_object *obj)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+ struct st_buffer_object *st_obj = st_buffer_object(obj);
+ char *map;
+
+ if (offset >= st_obj->size || size > (st_obj->size - offset))
+ return;
+
+ map = pipe->winsys->buffer_map(pipe->winsys, st_obj->buffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ memcpy(data, map + offset, size);
+ pipe->winsys->buffer_unmap(pipe->winsys, st_obj->buffer);
+}
+
+
+/**
* Allocate space for and store data in a buffer object. Any data that was
* previously stored in the buffer object is lost. If data is NULL,
* memory will be allocated, but no copy will occur.
@@ -102,7 +151,8 @@ st_bufferobj_data(GLcontext *ctx,
GLenum usage,
struct gl_buffer_object *obj)
{
- struct pipe_context *pipe = st_context(ctx)->pipe;
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
struct st_buffer_object *st_obj = st_buffer_object(obj);
unsigned buffer_usage;
@@ -124,46 +174,15 @@ st_bufferobj_data(GLcontext *ctx,
buffer_usage = 0;
}
- pipe->winsys->buffer_data( pipe->winsys, st_obj->buffer,
- size, data,
- buffer_usage );
-}
+ pipe_buffer_reference( pipe->winsys, &st_obj->buffer, NULL );
+ st_obj->buffer = pipe->winsys->buffer_create( pipe->winsys, 32, buffer_usage,
+ size );
-/**
- * Replace data in a subrange of buffer object. If the data range
- * specified by size + offset extends beyond the end of the buffer or
- * if data is NULL, no copy is performed.
- * Called via glBufferSubDataARB().
- */
-static void
-st_bufferobj_subdata(GLcontext *ctx,
- GLenum target,
- GLintptrARB offset,
- GLsizeiptrARB size,
- const GLvoid * data, struct gl_buffer_object *obj)
-{
- struct pipe_context *pipe = st_context(ctx)->pipe;
- struct st_buffer_object *st_obj = st_buffer_object(obj);
-
- pipe->winsys->buffer_subdata(pipe->winsys, st_obj->buffer, offset, size, data);
-}
-
-
-/**
- * Called via glGetBufferSubDataARB().
- */
-static void
-st_bufferobj_get_subdata(GLcontext *ctx,
- GLenum target,
- GLintptrARB offset,
- GLsizeiptrARB size,
- GLvoid * data, struct gl_buffer_object *obj)
-{
- struct pipe_context *pipe = st_context(ctx)->pipe;
- struct st_buffer_object *st_obj = st_buffer_object(obj);
+ st_obj->size = size;
- pipe->winsys->buffer_get_subdata(pipe->winsys, st_obj->buffer, offset, size, data);
+ if (data)
+ st_bufferobj_subdata(ctx, target, 0, size, data, obj);
}
@@ -180,15 +199,15 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,
switch (access) {
case GL_WRITE_ONLY:
- flags = PIPE_BUFFER_FLAG_WRITE;
+ flags = PIPE_BUFFER_USAGE_CPU_WRITE;
break;
case GL_READ_ONLY:
- flags = PIPE_BUFFER_FLAG_READ;
+ flags = PIPE_BUFFER_USAGE_CPU_READ;
break;
case GL_READ_WRITE:
/* fall-through */
default:
- flags = PIPE_BUFFER_FLAG_READ | PIPE_BUFFER_FLAG_WRITE;
+ flags = PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE;
break;
}
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.h b/src/mesa/state_tracker/st_cb_bufferobjects.h
index 2090a743e0..dcbb5a5233 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.h
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.h
@@ -30,7 +30,7 @@
struct st_context;
struct gl_buffer_object;
-struct pipe_buffer_handle;
+struct pipe_buffer;
/**
* State_tracker vertex/pixel buffer object, derived from Mesa's
@@ -39,7 +39,8 @@ struct pipe_buffer_handle;
struct st_buffer_object
{
struct gl_buffer_object Base;
- struct pipe_buffer_handle *buffer;
+ struct pipe_buffer *buffer;
+ GLsizeiptrARB size;
};
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index eaa88d3c6c..6b44cba2e4 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -848,7 +848,7 @@ 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.sbuf;
+ struct pipe_surface *ps = st->state.framebuffer.zsbuf;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
GLint skipPixels;
ubyte *stmap;
@@ -940,13 +940,13 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
st_validate_state(st);
if (format == GL_DEPTH_COMPONENT) {
- ps = st->state.framebuffer.zbuf;
+ ps = st->state.framebuffer.zsbuf;
stfp = make_fragment_shader_z(ctx->st);
stvp = make_vertex_shader(ctx->st, GL_TRUE);
color = ctx->Current.RasterColor;
}
else if (format == GL_STENCIL_INDEX) {
- ps = st->state.framebuffer.sbuf;
+ ps = st->state.framebuffer.zsbuf;
/* XXX special case - can't use texture map */
color = NULL;
}
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index f02cb3d133..4341623267 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -100,8 +100,8 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
}
if (strb->surface->buffer)
- pipe->winsys->buffer_reference(pipe->winsys, &strb->surface->buffer,
- NULL);
+ pipe_buffer_reference(pipe->winsys, &strb->surface->buffer,
+ NULL);
/* Determine surface format here */
if (strb->format != PIPE_FORMAT_NONE) {
diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c
index 43543df1a8..31744151f1 100644
--- a/src/mesa/state_tracker/st_cb_feedback.c
+++ b/src/mesa/state_tracker/st_cb_feedback.c
@@ -159,14 +159,7 @@ feedback_point( struct draw_stage *stage, struct prim_header *prim )
static void
-feedback_end( struct draw_stage *stage )
-{
- /* no-op */
-}
-
-
-static void
-feedback_begin( struct draw_stage *stage )
+feedback_flush( struct draw_stage *stage, unsigned flags )
{
/* no-op */
}
@@ -190,11 +183,10 @@ draw_glfeedback_stage(GLcontext *ctx, struct draw_context *draw)
fs->stage.draw = draw;
fs->stage.next = NULL;
- fs->stage.begin = feedback_begin;
fs->stage.point = feedback_point;
fs->stage.line = feedback_line;
fs->stage.tri = feedback_tri;
- fs->stage.end = feedback_end;
+ fs->stage.flush = feedback_flush;
fs->stage.reset_stipple_counter = feedback_reset_stipple_counter;
fs->ctx = ctx;
@@ -234,14 +226,7 @@ select_point( struct draw_stage *stage, struct prim_header *prim )
static void
-select_begin( struct draw_stage *stage )
-{
- /* no-op */
-}
-
-
-static void
-select_end( struct draw_stage *stage )
+select_flush( struct draw_stage *stage, unsigned flags )
{
/* no-op */
}
@@ -264,11 +249,10 @@ draw_glselect_stage(GLcontext *ctx, struct draw_context *draw)
fs->stage.draw = draw;
fs->stage.next = NULL;
- fs->stage.begin = select_begin;
fs->stage.point = select_point;
fs->stage.line = select_line;
fs->stage.tri = select_tri;
- fs->stage.end = select_end;
+ fs->stage.flush = select_flush;
fs->stage.reset_stipple_counter = select_reset_stipple_counter;
fs->ctx = ctx;
diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c
index 9808b1f8f6..dbec993f1b 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -45,21 +45,32 @@
void st_flush( struct st_context *st, uint pipeFlushFlags )
{
- GLframebuffer *fb = st->ctx->DrawBuffer;
-
FLUSH_VERTICES(st->ctx, 0);
- /* If there has been no rendering to the frontbuffer, consider
- * short-circuiting this, or perhaps pass an "optional" flag down
- * to the driver so that it can make the decision.
- */
st->pipe->flush( st->pipe, pipeFlushFlags );
+}
+
+
+static void st_gl_flush( struct st_context *st, uint pipeFlushFlags )
+{
+ GLframebuffer *fb = st->ctx->DrawBuffer;
+
+ FLUSH_VERTICES(st->ctx, 0);
if (!fb)
return;
/* XXX: temporary hack. This flag should only be set if we do any
* rendering to the front buffer.
+ *
+ * Further more, the scissor rectangle could be tracked to
+ * construct a dirty region of the front buffer, to avoid
+ * situations where it must be copied repeatedly.
+ *
+ * In the extreme case, some kind of timer could be set up to allow
+ * coalescing of multiple flushes to the frontbuffer, which can be
+ * quite a performance drain if there are a sufficient number of
+ * them.
*/
st->flags.frontbuffer_dirty
= (fb->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT);
@@ -69,6 +80,15 @@ void st_flush( struct st_context *st, uint pipeFlushFlags )
= st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
struct pipe_surface *front_surf = strb->surface;
+ /* If we aren't rendering to the frontbuffer, this is a noop.
+ * This should be uncontroversial for glFlush, though people may
+ * feel more strongly about glFinish.
+ *
+ * Additionally, need to make sure that the frontbuffer_dirty
+ * flag really gets set on frontbuffer rendering.
+ */
+ st->pipe->flush( st->pipe, pipeFlushFlags );
+
/* Hook for copying "fake" frontbuffer if necessary:
*/
st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf,
@@ -81,23 +101,23 @@ void st_flush( struct st_context *st, uint pipeFlushFlags )
/**
* Called via ctx->Driver.Flush()
*/
-static void st_Flush(GLcontext *ctx)
+static void st_glFlush(GLcontext *ctx)
{
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE);
+ st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE);
}
/**
* Called via ctx->Driver.Finish()
*/
-static void st_Finish(GLcontext *ctx)
+static void st_glFinish(GLcontext *ctx)
{
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT);
+ st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT);
}
void st_init_flush_functions(struct dd_function_table *functions)
{
- functions->Flush = st_Flush;
- functions->Finish = st_Finish;
+ functions->Flush = st_glFlush;
+ functions->Finish = st_glFinish;
}
diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c
index f1c2d2d7c3..7e347c4893 100644
--- a/src/mesa/state_tracker/st_cb_rasterpos.c
+++ b/src/mesa/state_tracker/st_cb_rasterpos.c
@@ -73,13 +73,7 @@ rastpos_stage( struct draw_stage *stage )
}
static void
-rastpos_begin( struct draw_stage *stage )
-{
- /* no-op */
-}
-
-static void
-rastpos_end( struct draw_stage *stage )
+rastpos_flush( struct draw_stage *stage, unsigned flags )
{
/* no-op */
}
@@ -104,6 +98,12 @@ rastpos_line( struct draw_stage *stage, struct prim_header *prim )
assert(0);
}
+static void
+rastpos_destroy(struct draw_stage *stage)
+{
+ free(stage);
+}
+
/**
* Update a raster pos attribute from the vertex result if it's present,
@@ -177,12 +177,13 @@ new_draw_rastpos_stage(GLcontext *ctx, struct draw_context *draw)
rs->stage.draw = draw;
rs->stage.next = NULL;
- rs->stage.begin = rastpos_begin;
rs->stage.point = rastpos_point;
rs->stage.line = rastpos_line;
rs->stage.tri = rastpos_tri;
- rs->stage.end = rastpos_end;
+ rs->stage.flush = rastpos_flush;
+ rs->stage.destroy = rastpos_destroy;
rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter;
+ rs->stage.destroy = rastpos_destroy;
rs->ctx = ctx;
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 668ac139f7..9c206c057a 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -52,6 +52,7 @@
#include "st_program.h"
#include "pipe/p_context.h"
#include "pipe/p_winsys.h"
+#include "pipe/p_inlines.h"
#include "pipe/draw/draw_context.h"
#include "pipe/cso_cache/cso_cache.h"
@@ -152,7 +153,7 @@ static void st_destroy_context_priv( struct st_context *st )
for (i = 0; i < Elements(st->state.constants); i++) {
if (st->state.constants[i].buffer) {
- ws->buffer_reference(ws, &st->state.constants[i].buffer, NULL);
+ pipe_buffer_reference(ws, &st->state.constants[i].buffer, NULL);
}
}
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 5ae21c93f9..2b6f8743f3 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -164,13 +164,6 @@ struct st_context
struct st_fragment_program *combined_prog;
} bitmap;
- /**
- * Buffer object which stores the ctx->Current.Attrib[] values.
- * Used for vertex array drawing when we we need an attribute for
- * which there's no enabled array.
- */
- struct pipe_buffer_handle *default_attrib_buffer;
-
struct cso_cache *cache;
};
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 94b3a9531a..8ef50ee768 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -45,6 +45,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_winsys.h"
+#include "pipe/p_inlines.h"
#include "pipe/draw/draw_private.h"
#include "pipe/draw/draw_context.h"
@@ -191,29 +192,6 @@ pipe_vertex_format(GLenum type, GLuint size, GLboolean normalized)
/**
- * The default attribute buffer is basically a copy of the
- * ctx->Current.Attrib[] array. It's used when the vertex program
- * references an attribute for which we don't have a VBO/array.
- */
-static void
-create_default_attribs_buffer(struct st_context *st)
-{
- struct pipe_context *pipe = st->pipe;
- /* XXX don't hardcode magic 32 here */
- st->default_attrib_buffer = pipe->winsys->buffer_create( pipe->winsys, 32, 0, 0 );
-}
-
-
-static void
-destroy_default_attribs_buffer(struct st_context *st)
-{
- struct pipe_context *pipe = st->pipe;
- pipe->winsys->buffer_reference(pipe->winsys,
- &st->default_attrib_buffer, NULL);
-}
-
-
-/**
* This function gets plugged into the VBO module and is called when
* we have something to render.
* Basically, translate the information into the format expected by pipe.
@@ -260,7 +238,7 @@ st_draw_vbo(GLcontext *ctx,
assert(stobj->buffer);
vbuffer[attr].buffer = NULL;
- winsys->buffer_reference(winsys, &vbuffer[attr].buffer, stobj->buffer);
+ pipe_buffer_reference(winsys, &vbuffer[attr].buffer, stobj->buffer);
vbuffer[attr].buffer_offset = (unsigned) arrays[0]->Ptr;/* in bytes */
velement.src_offset = arrays[mesaAttr]->Ptr - arrays[0]->Ptr;
assert(velement.src_offset <= 2048); /* 11-bit field */
@@ -305,7 +283,7 @@ st_draw_vbo(GLcontext *ctx,
if (ib) {
/* indexed primitive */
struct gl_buffer_object *bufobj = ib->obj;
- struct pipe_buffer_handle *indexBuf = NULL;
+ struct pipe_buffer *indexBuf = NULL;
unsigned indexSize, indexOffset, i;
switch (ib->type) {
@@ -326,7 +304,7 @@ st_draw_vbo(GLcontext *ctx,
if (bufobj && bufobj->Name) {
/* elements/indexes are in a real VBO */
struct st_buffer_object *stobj = st_buffer_object(bufobj);
- winsys->buffer_reference(winsys, &indexBuf, stobj->buffer);
+ pipe_buffer_reference(winsys, &indexBuf, stobj->buffer);
indexOffset = (unsigned) ib->ptr / indexSize;
}
else {
@@ -344,7 +322,7 @@ st_draw_vbo(GLcontext *ctx,
prims[i].start + indexOffset, prims[i].count);
}
- winsys->buffer_reference(winsys, &indexBuf, NULL);
+ pipe_buffer_reference(winsys, &indexBuf, NULL);
}
else {
/* non-indexed */
@@ -356,7 +334,7 @@ st_draw_vbo(GLcontext *ctx,
/* unreference buffers (frees wrapped user-space buffer objects) */
for (attr = 0; attr < vs->num_inputs; attr++) {
- winsys->buffer_reference(winsys, &vbuffer[attr].buffer, NULL);
+ pipe_buffer_reference(winsys, &vbuffer[attr].buffer, NULL);
assert(!vbuffer[attr].buffer);
pipe->set_vertex_buffer(pipe, attr, &vbuffer[attr]);
}
@@ -381,7 +359,7 @@ st_draw_vertices(GLcontext *ctx, unsigned prim,
const float height = ctx->DrawBuffer->Height;
const unsigned vertex_bytes = numVertex * numAttribs * 4 * sizeof(float);
struct pipe_context *pipe = ctx->st->pipe;
- struct pipe_buffer_handle *vbuf;
+ struct pipe_buffer *vbuf;
struct pipe_vertex_buffer vbuffer;
struct pipe_vertex_element velement;
unsigned i;
@@ -399,10 +377,14 @@ st_draw_vertices(GLcontext *ctx, unsigned prim,
}
/* XXX create one-time */
- vbuf = pipe->winsys->buffer_create(pipe->winsys, 32, 0, 0);
- pipe->winsys->buffer_data(pipe->winsys, vbuf,
- vertex_bytes, verts,
- PIPE_BUFFER_USAGE_VERTEX);
+ vbuf = pipe->winsys->buffer_create(pipe->winsys, 32,
+ PIPE_BUFFER_USAGE_VERTEX, vertex_bytes);
+ assert(vbuf);
+
+ memcpy(pipe->winsys->buffer_map(pipe->winsys, vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE),
+ verts, vertex_bytes);
+ pipe->winsys->buffer_unmap(pipe->winsys, vbuf);
/* tell pipe about the vertex buffer */
vbuffer.buffer = vbuf;
@@ -423,7 +405,7 @@ st_draw_vertices(GLcontext *ctx, unsigned prim,
pipe->draw_arrays(pipe, prim, 0, numVertex);
/* XXX: do one-time */
- pipe->winsys->buffer_reference(pipe->winsys, &vbuf, NULL);
+ pipe_buffer_reference(pipe->winsys, &vbuf, NULL);
}
@@ -434,15 +416,18 @@ st_draw_vertices(GLcontext *ctx, unsigned prim,
static void
set_feedback_vertex_format(GLcontext *ctx)
{
+#if 0
struct st_context *st = ctx->st;
struct vertex_info vinfo;
GLuint i;
+ memset(&vinfo, 0, sizeof(vinfo));
+
if (ctx->RenderMode == GL_SELECT) {
assert(ctx->RenderMode == GL_SELECT);
vinfo.num_attribs = 1;
vinfo.format[0] = FORMAT_4F;
- vinfo.interp_mode[0] = INTERP_NONE;
+ vinfo.interp_mode[0] = INTERP_LINEAR;
}
else {
/* GL_FEEDBACK, or glRasterPos */
@@ -455,6 +440,7 @@ set_feedback_vertex_format(GLcontext *ctx)
}
draw_set_vertex_info(st->draw, &vinfo);
+#endif
}
@@ -480,7 +466,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
struct pipe_winsys *winsys = pipe->winsys;
const struct st_vertex_program *vp;
const struct pipe_shader_state *vs;
- struct pipe_buffer_handle *index_buffer_handle = 0;
+ struct pipe_buffer *index_buffer_handle = 0;
struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
GLuint attr, i;
ubyte *mapped_constants;
@@ -528,7 +514,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
assert(stobj->buffer);
vbuffer[attr].buffer = NULL;
- winsys->buffer_reference(winsys, &vbuffer[attr].buffer, stobj->buffer);
+ pipe_buffer_reference(winsys, &vbuffer[attr].buffer, stobj->buffer);
vbuffer[attr].buffer_offset = (unsigned) arrays[0]->Ptr;/* in bytes */
velement.src_offset = arrays[mesaAttr]->Ptr - arrays[0]->Ptr;
}
@@ -564,7 +550,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
/* map the attrib buffer */
map = pipe->winsys->buffer_map(pipe->winsys,
vbuffer[attr].buffer,
- PIPE_BUFFER_FLAG_READ);
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(draw, attr, map);
}
@@ -588,7 +574,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
map = pipe->winsys->buffer_map(pipe->winsys,
index_buffer_handle,
- PIPE_BUFFER_FLAG_READ);
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer(draw, indexSize, map);
}
else {
@@ -600,7 +586,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
/* map constant buffers */
mapped_constants = winsys->buffer_map(winsys,
st->state.constants[PIPE_SHADER_VERTEX].buffer,
- PIPE_BUFFER_FLAG_READ);
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_constant_buffer(st->draw, mapped_constants);
@@ -620,7 +606,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
if (draw->vertex_buffer[i].buffer) {
pipe->winsys->buffer_unmap(pipe->winsys,
draw->vertex_buffer[i].buffer);
- winsys->buffer_reference(winsys, &draw->vertex_buffer[i].buffer, NULL);
+ pipe_buffer_reference(winsys, &draw->vertex_buffer[i].buffer, NULL);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
}
@@ -636,16 +622,12 @@ void st_init_draw( struct st_context *st )
{
GLcontext *ctx = st->ctx;
- /* actually, not used here, but elsewhere */
- create_default_attribs_buffer(st);
-
vbo_set_draw_func(ctx, st_draw_vbo);
}
void st_destroy_draw( struct st_context *st )
{
- destroy_default_attribs_buffer(st);
}
diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c
index 7ddc74e355..bca3fa5c38 100644
--- a/src/mesa/state_tracker/st_framebuffer.c
+++ b/src/mesa/state_tracker/st_framebuffer.c
@@ -34,6 +34,7 @@
#include "st_context.h"
#include "st_cb_fbo.h"
#include "pipe/p_defines.h"
+#include "pipe/p_context.h"
struct st_framebuffer *
@@ -171,7 +172,31 @@ st_notify_swapbuffers(struct st_framebuffer *stfb)
GET_CURRENT_CONTEXT(ctx);
if (ctx && ctx->DrawBuffer == &stfb->Base) {
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE);
+ st_flush( ctx->st,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS);
+ }
+}
+
+
+/**
+ * Quick hack - allows the winsys to inform the driver that surface
+ * states are now undefined after a glXSwapBuffers or similar.
+ */
+void
+st_notify_swapbuffers_complete(struct st_framebuffer *stfb)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (ctx && ctx->DrawBuffer == &stfb->Base) {
+ struct st_renderbuffer *strb;
+ int i;
+
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ if (stfb->Base.Attachment[i].Renderbuffer) {
+ strb = st_renderbuffer(stfb->Base.Attachment[i].Renderbuffer);
+ strb->surface->status = PIPE_SURFACE_STATUS_UNDEFINED;
+ }
+ }
}
}
diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h
index 78a8fde82b..3c397b126a 100644
--- a/src/mesa/state_tracker/st_public.h
+++ b/src/mesa/state_tracker/st_public.h
@@ -81,5 +81,6 @@ void st_make_current(struct st_context *st,
void st_flush( struct st_context *st, uint pipeFlushFlags );
void st_notify_swapbuffers(struct st_framebuffer *stfb);
+void st_notify_swapbuffers_complete(struct st_framebuffer *stfb);
#endif
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index a2bdf846ca..15cc458be8 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -201,6 +201,29 @@ st_texture_image_unmap(struct st_texture_image *stImage)
+/* 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
+st_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->cpp,
+ dst->pitch,
+ dstx, dsty, width, height, src, src_pitch, srcx, srcy);
+
+ pipe_surface_unmap(dst);
+}
+
+
/* Upload data for a particular image.
*/
void
@@ -225,12 +248,12 @@ st_texture_image_data(struct pipe_context *pipe,
dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
- pipe->surface_data(pipe, dst_surface,
- 0, 0, /* dstx, dsty */
- srcUB,
- src_row_pitch,
- 0, 0, /* source x, y */
- dst->width[level], height); /* width, height */
+ st_surface_data(pipe, dst_surface,
+ 0, 0, /* dstx, dsty */
+ srcUB,
+ src_row_pitch,
+ 0, 0, /* source x, y */
+ dst->width[level], height); /* width, height */
pipe_surface_reference(&dst_surface, NULL);
diff --git a/src/mesa/x86/Makefile b/src/mesa/x86/Makefile
index 3c6a6b11c0..09481dc509 100644
--- a/src/mesa/x86/Makefile
+++ b/src/mesa/x86/Makefile
@@ -21,7 +21,7 @@ clean:
gen_matypes: gen_matypes.c
- $(CC) $(INCLUDE_DIRS) $(CFLAGS) gen_matypes.c -o gen_matypes
+ $(HOST_CC) $(INCLUDE_DIRS) $(HOST_CFLAGS) gen_matypes.c -o gen_matypes
# need some special rules here, unfortunately
matypes.h: ../main/mtypes.h ../tnl/t_context.h gen_matypes