#define PIPE_TEX_FACE_NEG_Y 3
#define PIPE_TEX_FACE_POS_Z 4
#define PIPE_TEX_FACE_NEG_Z 5
+#define PIPE_TEX_FACE_MAX 6
#define PIPE_TEX_WRAP_REPEAT 0
#define PIPE_TEX_WRAP_CLAMP 1
#define PIPE_TEX_COMPARE_NONE 0
#define PIPE_TEX_COMPARE_R_TO_TEXTURE 1
-#define PIPE_TEX_FACE_POS_X 0
-#define PIPE_TEX_FACE_NEG_X 1
-#define PIPE_TEX_FACE_POS_Y 2
-#define PIPE_TEX_FACE_NEG_Y 3
-#define PIPE_TEX_FACE_POS_Z 4
-#define PIPE_TEX_FACE_NEG_Z 5
-#define PIPE_TEX_FACE_MAX 6
-
#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1
#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */
#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */
#define PIPE_BUFFER_USAGE_CONSTANT (1 << 7)
#define PIPE_BUFFER_USAGE_DISCARD (1 << 8)
#define PIPE_BUFFER_USAGE_DONTBLOCK (1 << 9)
+ #define PIPE_BUFFER_USAGE_FLUSH_EXPLICIT (1 << 10) /**< See pipe_screen::buffer_flush_mapped_range */
/** Pipe driver custom usage flags should be greater or equal to this value */
#define PIPE_BUFFER_USAGE_CUSTOM (1 << 16)
/**
- * Implementation capabilities/limits
- * Passed to pipe->get_param()
- * XXX this will need some fine tuning...
+ * Implementation capabilities/limits which are queried through
+ * pipe_screen::get_param() and pipe_screen::get_paramf().
*/
#define PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS 1
#define PIPE_CAP_NPOT_TEXTURES 2
**************************************************************************/
+/**
+ * Functions for pixel buffer objects and vertex/element buffer objects.
+ */
+
+
#include "main/imports.h"
#include "main/mtypes.h"
+#include "main/arrayobj.h"
#include "main/bufferobj.h"
#include "st_inlines.h"
#include "pipe/p_inlines.h"
-
-/* Pixel buffers and Vertex/index buffers are handled through these
- * mesa callbacks. Framebuffer/Renderbuffer objects are
- * created/managed elsewhere.
- */
-
-
-
/**
* There is some duplication between mesa's bufferobjects and our
* bufmgr buffers. Both have an integer handle and a hashtable to
{
struct st_buffer_object *st_obj = st_buffer_object(obj);
- if (offset >= st_obj->size || size > (st_obj->size - offset))
- return;
+ /* we may be called from VBO code, so double-check params here */
+ ASSERT(offset >= 0);
+ ASSERT(size >= 0);
+ ASSERT(offset + size <= obj->Size);
st_cond_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer,
offset, size, data);
{
struct st_buffer_object *st_obj = st_buffer_object(obj);
- if (offset >= st_obj->size || size > (st_obj->size - offset))
- return;
+ /* we may be called from VBO code, so double-check params here */
+ ASSERT(offset >= 0);
+ ASSERT(size >= 0);
+ ASSERT(offset + size <= obj->Size);
st_cond_flush_pipe_buffer_read(st_context(ctx), st_obj->buffer,
offset, size, data);
return;
}
- st_obj->size = size;
-
if (data)
st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0,
size, data);
struct gl_buffer_object *obj)
{
struct st_buffer_object *st_obj = st_buffer_object(obj);
- GLuint flags;
+ uint flags;
switch (access) {
case GL_WRITE_ONLY:
obj->Pointer = st_cond_flush_pipe_buffer_map(st_context(ctx),
st_obj->buffer,
flags);
- if(obj->Pointer) {
+ if (obj->Pointer) {
obj->Offset = 0;
obj->Length = obj->Size;
}
}
-
/**
* Called via glMapBufferRange().
*/
{
struct pipe_context *pipe = st_context(ctx)->pipe;
struct st_buffer_object *st_obj = st_buffer_object(obj);
- GLuint flags = 0;
+ uint flags = 0x0;
char *map;
if (access & GL_MAP_WRITE_BIT)
if (access & GL_MAP_READ_BIT)
flags |= PIPE_BUFFER_USAGE_CPU_READ;
+ if (access & GL_MAP_FLUSH_EXPLICIT_BIT)
+ flags |= PIPE_BUFFER_USAGE_FLUSH_EXPLICIT;
+
/* ... other flags ...
*/
}
+/**
+ * Called via glCopyBufferSubData().
+ */
+static void
+st_copy_buffer_subdata(GLcontext *ctx,
+ struct gl_buffer_object *src,
+ struct gl_buffer_object *dst,
+ GLintptr readOffset, GLintptr writeOffset,
+ GLsizeiptr size)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+ struct st_buffer_object *srcObj = st_buffer_object(src);
+ struct st_buffer_object *dstObj = st_buffer_object(dst);
+ ubyte *srcPtr, *dstPtr;
+
+ /* buffer should not already be mapped */
+ assert(!src->Pointer);
+ assert(!dst->Pointer);
+
+ srcPtr = (ubyte *) pipe_buffer_map_range(pipe->screen,
+ srcObj->buffer,
+ readOffset, size,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
+ dstPtr = (ubyte *) pipe_buffer_map_range(pipe->screen,
+ dstObj->buffer,
+ writeOffset, size,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ if (srcPtr && dstPtr)
+ _mesa_memcpy(dstPtr + writeOffset, srcPtr + readOffset, size);
+
+ pipe_buffer_unmap(pipe->screen, srcObj->buffer);
+ pipe_buffer_unmap(pipe->screen, dstObj->buffer);
+}
+
+
void
st_init_bufferobject_functions(struct dd_function_table *functions)
{
functions->MapBufferRange = st_bufferobj_map_range;
functions->FlushMappedBufferRange = st_bufferobj_flush_mapped_range;
functions->UnmapBuffer = st_bufferobj_unmap;
+ functions->CopyBufferSubData = st_copy_buffer_subdata;
+
+ /* For GL_APPLE_vertex_array_object */
+ functions->NewArrayObject = _mesa_new_array_object;
+ functions->DeleteArrayObject = _mesa_delete_array_object;
}
#include "vbo_context.h"
-static void vbo_exec_debug_verts( struct vbo_exec_context *exec )
+static void
+vbo_exec_debug_verts( struct vbo_exec_context *exec )
{
GLuint count = exec->vtx.vert_count;
GLuint i;
* NOTE: Need to have calculated primitives by this point -- do it on the fly.
* NOTE: Old 'parity' issue is gone.
*/
-static GLuint vbo_copy_vertices( struct vbo_exec_context *exec )
+static GLuint
+vbo_copy_vertices( struct vbo_exec_context *exec )
{
GLuint nr = exec->vtx.prim[exec->vtx.prim_count-1].count;
GLuint ovf, i;
GLuint sz = exec->vtx.vertex_size;
GLfloat *dst = exec->vtx.copied.buffer;
- GLfloat *src = (exec->vtx.buffer_map +
- exec->vtx.prim[exec->vtx.prim_count-1].start *
- exec->vtx.vertex_size);
+ const GLfloat *src = (exec->vtx.buffer_map +
+ exec->vtx.prim[exec->vtx.prim_count-1].start *
+ exec->vtx.vertex_size);
- switch( exec->ctx->Driver.CurrentExecPrimitive )
- {
+ switch (exec->ctx->Driver.CurrentExecPrimitive) {
case GL_POINTS:
return 0;
case GL_LINES:
_mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
return i;
case GL_LINE_STRIP:
- if (nr == 0)
+ if (nr == 0) {
return 0;
+ }
else {
_mesa_memcpy( dst, src+(nr-1)*sz, sz * sizeof(GLfloat) );
return 1;
case GL_LINE_LOOP:
case GL_TRIANGLE_FAN:
case GL_POLYGON:
- if (nr == 0)
+ if (nr == 0) {
return 0;
+ }
else if (nr == 1) {
_mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) );
return 1;
- } else {
+ }
+ else {
_mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) );
_mesa_memcpy( dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat) );
return 2;
/* fallthrough */
case GL_QUAD_STRIP:
switch (nr) {
- case 0: ovf = 0; break;
- case 1: ovf = 1; break;
- default: ovf = 2 + (nr&1); break;
+ case 0:
+ ovf = 0;
+ break;
+ case 1:
+ ovf = 1;
+ break;
+ default:
+ ovf = 2 + (nr & 1);
+ break;
}
for (i = 0 ; i < ovf ; i++)
_mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
/* TODO: populate these as the vertex is defined:
*/
-static void vbo_exec_bind_arrays( GLcontext *ctx )
+static void
+vbo_exec_bind_arrays( GLcontext *ctx )
{
struct vbo_context *vbo = vbo_context(ctx);
struct vbo_exec_context *exec = &vbo->exec;
struct gl_client_array *arrays = exec->vtx.arrays;
- GLuint count = exec->vtx.vert_count;
- GLubyte *data = (GLubyte *)exec->vtx.buffer_map;
+ const GLuint count = exec->vtx.vert_count;
+ const GLubyte *data = (GLubyte *) exec->vtx.buffer_map;
const GLuint *map;
GLuint attr;
GLbitfield varying_inputs = 0x0;
arrays[attr]._MaxElement = count; /* ??? */
data += exec->vtx.attrsz[src] * sizeof(GLfloat);
- varying_inputs |= 1<<attr;
+ varying_inputs |= 1 << attr;
}
}
}
-static void vbo_exec_vtx_unmap( struct vbo_exec_context *exec )
+static void
+vbo_exec_vtx_unmap( struct vbo_exec_context *exec )
{
GLenum target = GL_ARRAY_BUFFER_ARB;
if (exec->vtx.bufferobj->Name) {
GLcontext *ctx = exec->ctx;
- if(ctx->Driver.FlushMappedBufferRange) {
+ if (ctx->Driver.FlushMappedBufferRange) {
GLintptr offset = exec->vtx.buffer_used - exec->vtx.bufferobj->Offset;
GLsizeiptr length = (exec->vtx.buffer_ptr - exec->vtx.buffer_map) * sizeof(float);
- if(length)
+ if (length)
ctx->Driver.FlushMappedBufferRange(ctx, target,
offset, length,
exec->vtx.bufferobj);
}
}
-void vbo_exec_vtx_map( struct vbo_exec_context *exec )
+
+void
+vbo_exec_vtx_map( struct vbo_exec_context *exec )
{
GLcontext *ctx = exec->ctx;
- GLenum target = GL_ARRAY_BUFFER_ARB;
- GLenum access = GL_READ_WRITE_ARB;
- GLenum usage = GL_STREAM_DRAW_ARB;
+ const GLenum target = GL_ARRAY_BUFFER_ARB;
+ const GLenum access = GL_READ_WRITE_ARB; /* for MapBuffer */
+ const GLenum accessRange = GL_MAP_WRITE_BIT | /* for MapBufferRange */
+ GL_MAP_INVALIDATE_RANGE_BIT |
+ GL_MAP_UNSYNCHRONIZED_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT |
+ MESA_MAP_NOWAIT_BIT;
+ const GLenum usage = GL_STREAM_DRAW_ARB;
if (exec->vtx.bufferobj->Name == 0)
return;
}
if (VBO_VERT_BUFFER_SIZE > exec->vtx.buffer_used + 1024 &&
- ctx->Driver.MapBufferRange)
- {
+ ctx->Driver.MapBufferRange) {
exec->vtx.buffer_map =
(GLfloat *)ctx->Driver.MapBufferRange(ctx,
target,
exec->vtx.buffer_used,
(VBO_VERT_BUFFER_SIZE -
exec->vtx.buffer_used),
- (GL_MAP_WRITE_BIT |
- GL_MAP_INVALIDATE_RANGE_BIT |
- GL_MAP_UNSYNCHRONIZED_BIT |
- MESA_MAP_NOWAIT_BIT),
+ accessRange,
exec->vtx.bufferobj);
exec->vtx.buffer_ptr = exec->vtx.buffer_map;
}
VBO_VERT_BUFFER_SIZE,
NULL, usage, exec->vtx.bufferobj);
- exec->vtx.buffer_map = (GLfloat *)
- ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
+
+ if (ctx->Driver.MapBufferRange)
+ exec->vtx.buffer_map =
+ (GLfloat *)ctx->Driver.MapBufferRange(ctx, target,
+ 0, VBO_VERT_BUFFER_SIZE,
+ accessRange,
+ exec->vtx.bufferobj);
+ else
+ exec->vtx.buffer_map =
+ (GLfloat *)ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
exec->vtx.buffer_ptr = exec->vtx.buffer_map;
}
- if (0) _mesa_printf("map %d..\n", exec->vtx.buffer_used);
+ if (0)
+ _mesa_printf("map %d..\n", exec->vtx.buffer_used);
}
/**
* Execute the buffer and save copied verts.
*/
-void vbo_exec_vtx_flush( struct vbo_exec_context *exec,
- GLboolean unmap )
+void
+vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap )
{
if (0)
vbo_exec_debug_verts( exec );
-
if (exec->vtx.prim_count &&
exec->vtx.vert_count) {
vbo_exec_vtx_unmap( exec );
}
- if (0) _mesa_printf("%s %d %d\n", __FUNCTION__, exec->vtx.prim_count,
- exec->vtx.vert_count);
+ if (0)
+ _mesa_printf("%s %d %d\n", __FUNCTION__, exec->vtx.prim_count,
+ exec->vtx.vert_count);
vbo_context(ctx)->draw_prims( ctx,
exec->vtx.inputs,
*/
if (exec->vtx.bufferobj->Name && !unmap) {
vbo_exec_vtx_map( exec );
- }
+ }
}
}
vbo_exec_vtx_unmap( exec );
}
-
if (unmap)
exec->vtx.max_vert = 0;
else
exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) /
(exec->vtx.vertex_size * sizeof(GLfloat)));
-
exec->vtx.buffer_ptr = exec->vtx.buffer_map;
exec->vtx.prim_count = 0;
exec->vtx.vert_count = 0;