diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2008-01-27 12:35:33 +1100 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2008-01-27 12:35:33 +1100 |
commit | a556034514582dc8e1b8b65f56020031d513331b (patch) | |
tree | 182aaf4be24733e2943f9e39cfb86bc22f942efb /src/mesa | |
parent | 9043323f1437f9c6791845b3ddbb9af912b45110 (diff) | |
parent | b717de3238a028a3fdfbaf13eb02dbde262f03e7 (diff) |
Merge branch 'upstream-gallium-0.1' into darktama-gallium-0.1
Diffstat (limited to 'src/mesa')
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 |