if (st_obj->buffer)
pipe_resource_reference(&st_obj->buffer, NULL);
- free(st_obj->Base.Label);
- free(st_obj);
+ _mesa_delete_buffer_object(ctx, obj);
}
struct st_buffer_object *st_obj = st_buffer_object(obj);
/* we may be called from VBO code, so double-check params here */
- ASSERT(offset >= 0);
- ASSERT(size >= 0);
- ASSERT(offset + size <= obj->Size);
+ assert(offset >= 0);
+ assert(size >= 0);
+ assert(offset + size <= obj->Size);
if (!size)
return;
struct st_buffer_object *st_obj = st_buffer_object(obj);
/* we may be called from VBO code, so double-check params here */
- ASSERT(offset >= 0);
- ASSERT(size >= 0);
- ASSERT(offset + size <= obj->Size);
+ assert(offset >= 0);
+ assert(size >= 0);
+ assert(offset + size <= obj->Size);
if (!size)
return;
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
struct st_buffer_object *st_obj = st_buffer_object(obj);
unsigned bind, pipe_usage, pipe_flags = 0;
- if (size && data && st_obj->buffer &&
+ if (target != GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD &&
+ size && st_obj->buffer &&
st_obj->Base.Size == size &&
st_obj->Base.Usage == usage &&
st_obj->Base.StorageFlags == storageFlags) {
- /* Just discard the old contents and write new data.
- * This should be the same as creating a new buffer, but we avoid
- * a lot of validation in Mesa.
- */
- struct pipe_box box;
-
- u_box_1d(0, size, &box);
- pipe->transfer_inline_write(pipe, st_obj->buffer, 0,
- PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE,
- &box, data, 0, 0);
- return GL_TRUE;
+ if (data) {
+ /* Just discard the old contents and write new data.
+ * This should be the same as creating a new buffer, but we avoid
+ * a lot of validation in Mesa.
+ */
+ struct pipe_box box;
+
+ u_box_1d(0, size, &box);
+ pipe->transfer_inline_write(pipe, st_obj->buffer, 0,
+ PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE,
+ &box, data, 0, 0);
+ return GL_TRUE;
+ } else if (screen->get_param(screen, PIPE_CAP_INVALIDATE_BUFFER)) {
+ pipe->invalidate_resource(pipe, st_obj->buffer);
+ return GL_TRUE;
+ }
}
st_obj->Base.Size = size;
bind = PIPE_BIND_CONSTANT_BUFFER;
break;
case GL_DRAW_INDIRECT_BUFFER:
+ case GL_PARAMETER_BUFFER_ARB:
bind = PIPE_BIND_COMMAND_ARGS_BUFFER;
break;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ case GL_SHADER_STORAGE_BUFFER:
+ bind = PIPE_BIND_SHADER_BUFFER;
+ break;
+ case GL_QUERY_BUFFER:
+ bind = PIPE_BIND_QUERY_BUFFER;
+ break;
default:
bind = 0;
}
break;
case GL_STREAM_DRAW:
case GL_STREAM_COPY:
- pipe_usage = PIPE_USAGE_STREAM;
- break;
+ /* XXX: Remove this test and fall-through when we have PBO unpacking
+ * acceleration. Right now, PBO unpacking is done by the CPU, so we
+ * have to make sure CPU reads are fast.
+ */
+ if (target != GL_PIXEL_UNPACK_BUFFER_ARB) {
+ pipe_usage = PIPE_USAGE_STREAM;
+ break;
+ }
+ /* fall through */
case GL_STATIC_READ:
case GL_DYNAMIC_READ:
case GL_STREAM_READ:
buffer.depth0 = 1;
buffer.array_size = 1;
- st_obj->buffer = pipe->screen->resource_create(pipe->screen, &buffer);
+ if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
+ st_obj->buffer =
+ screen->resource_from_user_memory(screen, &buffer, (void*)data);
+ }
+ else {
+ st_obj->buffer = screen->resource_create(screen, &buffer);
+
+ if (st_obj->buffer && data)
+ pipe_buffer_write(pipe, st_obj->buffer, 0, size, data);
+ }
if (!st_obj->buffer) {
/* out of memory */
st_obj->Base.Size = 0;
return GL_FALSE;
}
-
- if (data)
- pipe_buffer_write(pipe, st_obj->buffer, 0, size, data);
}
/* BufferData may change an array or uniform buffer, need to update it */
}
+/**
+ * Called via glInvalidateBuffer(Sub)Data.
+ */
+static void
+st_bufferobj_invalidate(struct gl_context *ctx,
+ struct gl_buffer_object *obj,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
+ struct st_buffer_object *st_obj = st_buffer_object(obj);
+
+ /* We ignore partial invalidates. */
+ if (offset != 0 || size != obj->Size)
+ return;
+
+ /* Nothing to invalidate. */
+ if (!st_obj->buffer)
+ return;
+
+ pipe->invalidate_resource(pipe, st_obj->buffer);
+}
+
+
/**
* Called via glMapBufferRange().
*/
static const char zeros[16] = {0};
if (!pipe->clear_buffer) {
- _mesa_buffer_clear_subdata(ctx, offset, size,
- clearValue, clearValueSize, bufObj);
+ _mesa_ClearBufferSubData_sw(ctx, offset, size,
+ clearValue, clearValueSize, bufObj);
return;
}
void
-st_init_bufferobject_functions(struct dd_function_table *functions)
+st_init_bufferobject_functions(struct pipe_screen *screen,
+ struct dd_function_table *functions)
{
/* plug in default driver fallbacks (such as for ClearBufferSubData) */
_mesa_init_buffer_object_functions(functions);
functions->CopyBufferSubData = st_copy_buffer_subdata;
functions->ClearBufferSubData = st_clear_buffer_subdata;
- /* For GL_APPLE_vertex_array_object */
- functions->NewArrayObject = _mesa_new_vao;
- functions->DeleteArrayObject = _mesa_delete_vao;
+ if (screen->get_param(screen, PIPE_CAP_INVALIDATE_BUFFER))
+ functions->InvalidateBufferSubData = st_bufferobj_invalidate;
}