state_bufferobject.c revision ebc248f21b276416f76e20da3add001aff9fc30a
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include "state.h"
#include "state/cr_statetypes.h"
#include "state/cr_statefuncs.h"
#include "state_internals.h"
#include "cr_mem.h"
#include "cr_string.h"
{
if (b) {
b->refCount = 1;
b->usage = GL_STATIC_DRAW_ARB;
b->access = GL_READ_WRITE_ARB;
b->bResyncOnRead = GL_FALSE;
#ifndef IN_GUEST
#endif
}
return b;
}
{
CRContext *g = GetCurrentContext();
}
{
CRContext *g = GetCurrentContext();
}
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &(g->bufferobject);
switch (target)
{
case GL_ARRAY_BUFFER_ARB:
return b->arrayBuffer->id!=0;
return b->elementsBuffer->id!=0;
#ifdef CR_ARB_pixel_buffer_object
case GL_PIXEL_PACK_BUFFER_ARB:
return b->packBuffer->id!=0;
return b->unpackBuffer->id!=0;
#endif
default:
return GL_FALSE;
}
}
{
switch (target)
{
case GL_ARRAY_BUFFER_ARB:
return b->arrayBuffer;
return b->elementsBuffer;
#ifdef CR_ARB_pixel_buffer_object
case GL_PIXEL_PACK_BUFFER_ARB:
return b->packBuffer;
return b->unpackBuffer;
#endif
default:
return NULL;
}
}
{
CRContext *g = GetCurrentContext();
FLUSH();
if (g->current.inBeginEnd) {
return GL_FALSE;
}
}
{
#ifdef CR_ARB_pixel_buffer_object
#endif
#ifdef IN_GUEST
b->retainBufferData = GL_TRUE;
#else
b->retainBufferData = GL_FALSE;
#endif
b->nullBuffer = AllocBufferObject(0);
b->arrayBuffer = b->nullBuffer;
b->elementsBuffer = b->nullBuffer;
#ifdef CR_ARB_pixel_buffer_object
b->packBuffer = b->nullBuffer;
b->unpackBuffer = b->nullBuffer;
#endif
}
void crStateFreeBufferObject(void *data)
{
#ifndef IN_GUEST
if (diff_api.DeleteBuffersARB)
{
}
#endif
}
{
crFree(b->nullBuffer);
}
{
(void) key;
}
{
CRContext *g = GetCurrentContext();
}
{
CRContext *g = GetCurrentContext();
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &(g->bufferobject);
if (g->current.inBeginEnd) {
return;
}
FLUSH();
if (!oldObj)
{
return;
}
if (buffer == 0) {
newObj = b->nullBuffer;
}
else {
if (!newObj) {
CRSTATE_CHECKERR(!crHashtableIsKeyUsed(g->shared->buffersTable, buffer), GL_INVALID_OPERATION, "name is not a buffer object");
#ifndef IN_GUEST
{
crWarning("GenBuffersARB failed!");
return;
}
#endif
}
#ifndef IN_GUEST
#endif
}
switch (target)
{
case GL_ARRAY_BUFFER_ARB:
b->arrayBuffer = newObj;
break;
b->elementsBuffer = newObj;
break;
#ifdef CR_ARB_pixel_buffer_object
case GL_PIXEL_PACK_BUFFER_ARB:
b->packBuffer = newObj;
break;
b->unpackBuffer = newObj;
break;
#endif
default: /*can't get here*/
CRASSERT(false);
return;
}
/*we shouldn't reach this point*/
CRASSERT(false);
}
#ifdef IN_GUEST
if (target == GL_PIXEL_PACK_BUFFER_ARB)
{
}
#endif
}
{
int j, k;
if (obj == b->arrayBuffer)
{
b->arrayBuffer = b->nullBuffer;
b->arrayBuffer->refCount++;
}
if (obj == b->elementsBuffer)
{
b->elementsBuffer = b->nullBuffer;
b->elementsBuffer->refCount++;
}
#ifdef CR_ARB_pixel_buffer_object
if (obj == b->packBuffer)
{
b->packBuffer = b->nullBuffer;
b->packBuffer->refCount++;
}
if (obj == b->unpackBuffer)
{
b->unpackBuffer = b->nullBuffer;
b->unpackBuffer->refCount++;
}
#endif
#ifdef CR_ARB_vertex_buffer_object
for (j=0; j<CRSTATECLIENT_MAX_VERTEXARRAYS; ++j)
{
{
++b->nullBuffer->refCount;
}
}
{
for (j=0; j<CRSTATECLIENT_MAX_VERTEXARRAYS; ++j)
{
{
++b->nullBuffer->refCount;
}
}
}
#endif
#ifndef IN_GUEST
#endif
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
int i;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (n < 0) {
"glDeleteBuffersARB(n < 0)");
return;
}
for (i = 0; i < n; i++) {
if (buffers[i]) {
if (obj) {
int j;
{
/* saved state version <= SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS does not have usage bits info,
* so on restore, we set mark bits as used.
* This is why g_pAvailableContexts[j] could be NULL
* also g_pAvailableContexts[0] will hold default context, which we should discard */
if (j && ctx)
{
ctStateBuffersRefsCleanup(ctx, obj, g->neg_bitid); /* <- yes, use g->neg_bitid, i.e. neg_bitid of the current context to ensure others bits get dirtified,
* but not the current context ones*/
}
else
}
}
}
}
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (size < 0) {
"glBufferDataARB(size < 0)");
return;
}
switch (usage) {
case GL_STREAM_DRAW_ARB:
case GL_STREAM_READ_ARB:
case GL_STREAM_COPY_ARB:
case GL_STATIC_DRAW_ARB:
case GL_STATIC_READ_ARB:
case GL_STATIC_COPY_ARB:
case GL_DYNAMIC_DRAW_ARB:
case GL_DYNAMIC_READ_ARB:
case GL_DYNAMIC_COPY_ARB:
/* OK */
break;
default:
"glBufferDataARB(usage)");
return;
}
if (!obj)
{
return;
}
return;
}
"glBufferDataARB(buffer is mapped)");
return;
}
/* The user of the state tracker should set the retainBufferData field
* during context initialization, if needed.
*/
if (b->retainBufferData) {
}
return;
}
if (data)
}
obj->dirtyStart = 0;
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (!obj)
{
return;
}
"glBufferSubDataARB");
return;
}
"glBufferSubDataARB(buffer is mapped)");
return;
}
return;
}
}
/* grow dirty region */
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (!obj)
{
return;
}
"glGetBufferSubDataARB");
return;
}
"glGetBufferSubDataARB(buffer is mapped)");
return;
}
return;
}
}
}
void * STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return NULL;
}
if (!obj)
{
return NULL;
}
return GL_FALSE;
}
switch (access) {
case GL_READ_ONLY_ARB:
case GL_WRITE_ONLY_ARB:
case GL_READ_WRITE_ARB:
break;
default:
"glMapBufferARB(access)");
return NULL;
}
}
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return GL_FALSE;
}
if (!obj)
{
return GL_FALSE;
}
return GL_FALSE;
}
return GL_FALSE;
}
/* the data was most likely modified */
obj->dirtyStart = 0;
}
return GL_TRUE;
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (!obj)
{
return;
}
switch (pname) {
case GL_BUFFER_SIZE_ARB:
break;
case GL_BUFFER_USAGE_ARB:
break;
case GL_BUFFER_ACCESS_ARB:
break;
case GL_BUFFER_MAPPED_ARB:
break;
default:
"glGetBufferParameterivARB(pname)");
return;
}
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (!obj)
{
return;
}
if (pname != GL_BUFFER_MAP_POINTER_ARB) {
return;
}
}
/**
* We need to check if the GL_EXT_vertex/pixel_buffer_object extensions
* are supported before calling any of the diff_api functions.
* This flag indicates if the extensions is available (1), not available (0)
* or needs to be tested for (-1).
* If we don't do this, we can segfault inside OpenGL.
* Ideally, the render SPU should no-op unsupported GL functions, but
* that's a bit complicated.
*/
static GLboolean
{
if (haveBufferObjectExt == -1) {
const char *ext;
/* XXX this check is temporary. We need to make the tilesort SPU plug
* GetString into the diff'ing table in order for this to really work.
*/
haveBufferObjectExt = 0;
return 0;
}
haveBufferObjectExt = 1;
}
else {
haveBufferObjectExt = 0;
}
}
return haveBufferObjectExt;
}
{
/* ARRAY_BUFFER */
{
{
if (bSwitch)
{
}
else
{
}
}
}
{
/* update array buffer data */
{
/* update whole buffer */
}
else
{
/* update sub buffer */
}
}
/* ELEMENTS_BUFFER */
{
{
if (bSwitch)
{
}
else
{
}
}
}
{
/* update array buffer data */
{
/* update whole buffer */
}
else
{
/* update sub buffer */
}
}
#ifdef CR_ARB_pixel_buffer_object
/* PIXEL_PACK_BUFFER */
{
{
if (bSwitch)
{
}
else
{
}
}
}
{
/* update array buffer data */
{
/* update whole buffer */
}
else
{
/* update sub buffer */
}
}
/* PIXEL_UNPACK_BUFFER */
{
{
if (bSwitch)
{
}
else
{
}
}
}
{
/* update array buffer data */
{
/* update whole buffer */
}
else
{
/* update sub buffer */
}
}
#endif /*ifdef CR_ARB_pixel_buffer_object*/
}
{
if (!HaveBufferObjectExtension())
return;
}
{
{
}
if (pBufferObj->data)
{
"While it is entirely legal to create a buffer object by binding
it to GL_ARRAY_BUFFER and loading it with data, then using it
with the GL_PIXEL_UNPACK_BUFFER_ARB or GL_PIXEL_PACK_BUFFER_ARB
binding, such behavior is liable to confuse the driver and may
hurt performance."
*/
if (!pState->retainBufferData)
{
}
}
}
/*
*/
{
int i;
if (!HaveBufferObjectExtension())
return;
{
/*@todo, move to state_client.c*/
{
}
{
}
{
}
{
}
{
}
{
}
{
}
for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
{
{
if (diff_api.ActiveTextureARB)
}
}
if (diff_api.ActiveTextureARB)
#ifdef CR_NV_vertex_program
for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
{
{
}
}
#endif
#ifdef CR_ARB_pixel_buffer_object
#endif
}
else
{
}
}