blob: d8141a3f5b91a227d2d4a4257eeb6fae9a163256 [file] [log] [blame]
#include "util/u_memory.h"
#include "util/u_math.h"
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
#include "brw_screen.h"
#include "brw_winsys.h"
static void *
brw_buffer_map_range( struct pipe_screen *screen,
struct pipe_buffer *buffer,
unsigned offset,
unsigned length,
unsigned usage )
{
struct brw_screen *bscreen = brw_screen(screen);
struct brw_winsys_screen *sws = bscreen->sws;
struct brw_buffer *buf = brw_buffer( buffer );
if (buf->user_buffer)
return buf->user_buffer;
return sws->bo_map( buf->bo,
BRW_DATA_OTHER,
offset,
length,
(usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE,
(usage & PIPE_BUFFER_USAGE_DISCARD) ? TRUE : FALSE,
(usage & PIPE_BUFFER_USAGE_FLUSH_EXPLICIT) ? TRUE : FALSE);
}
static void *
brw_buffer_map( struct pipe_screen *screen,
struct pipe_buffer *buffer,
unsigned usage )
{
struct brw_screen *bscreen = brw_screen(screen);
struct brw_winsys_screen *sws = bscreen->sws;
struct brw_buffer *buf = brw_buffer( buffer );
if (buf->user_buffer)
return buf->user_buffer;
return sws->bo_map( buf->bo,
BRW_DATA_OTHER,
0,
buf->base.size,
(usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE,
FALSE,
FALSE);
}
static void
brw_buffer_flush_mapped_range( struct pipe_screen *screen,
struct pipe_buffer *buffer,
unsigned offset,
unsigned length )
{
struct brw_screen *bscreen = brw_screen(screen);
struct brw_winsys_screen *sws = bscreen->sws;
struct brw_buffer *buf = brw_buffer( buffer );
if (buf->user_buffer)
return;
sws->bo_flush_range( buf->bo,
offset,
length );
}
static void
brw_buffer_unmap( struct pipe_screen *screen,
struct pipe_buffer *buffer )
{
struct brw_screen *bscreen = brw_screen(screen);
struct brw_winsys_screen *sws = bscreen->sws;
struct brw_buffer *buf = brw_buffer( buffer );
if (buf->bo)
sws->bo_unmap(buf->bo);
}
static void
brw_buffer_destroy( struct pipe_buffer *buffer )
{
struct brw_buffer *buf = brw_buffer( buffer );
assert(!p_atomic_read(&buffer->reference.count));
bo_reference(&buf->bo, NULL);
FREE(buf);
}
static struct pipe_buffer *
brw_buffer_create(struct pipe_screen *screen,
unsigned alignment,
unsigned usage,
unsigned size)
{
struct brw_screen *bscreen = brw_screen(screen);
struct brw_winsys_screen *sws = bscreen->sws;
struct brw_buffer *buf;
unsigned buffer_type;
enum pipe_error ret;
buf = CALLOC_STRUCT(brw_buffer);
if (!buf)
return NULL;
pipe_reference_init(&buf->base.reference, 1);
buf->base.screen = screen;
buf->base.alignment = alignment;
buf->base.usage = usage;
buf->base.size = size;
switch (usage & (PIPE_BUFFER_USAGE_VERTEX |
PIPE_BUFFER_USAGE_INDEX |
PIPE_BUFFER_USAGE_PIXEL |
PIPE_BUFFER_USAGE_CONSTANT))
{
case PIPE_BUFFER_USAGE_VERTEX:
case PIPE_BUFFER_USAGE_INDEX:
case (PIPE_BUFFER_USAGE_VERTEX|PIPE_BUFFER_USAGE_INDEX):
buffer_type = BRW_BUFFER_TYPE_VERTEX;
break;
case PIPE_BUFFER_USAGE_PIXEL:
buffer_type = BRW_BUFFER_TYPE_PIXEL;
break;
case PIPE_BUFFER_USAGE_CONSTANT:
buffer_type = BRW_BUFFER_TYPE_SHADER_CONSTANTS;
break;
default:
buffer_type = BRW_BUFFER_TYPE_GENERIC;
break;
}
ret = sws->bo_alloc( sws, buffer_type,
size, alignment,
&buf->bo );
if (ret != PIPE_OK)
return NULL;
return &buf->base;
}
static struct pipe_buffer *
brw_user_buffer_create(struct pipe_screen *screen,
void *ptr,
unsigned bytes)
{
struct brw_buffer *buf;
buf = CALLOC_STRUCT(brw_buffer);
if (!buf)
return NULL;
buf->user_buffer = ptr;
pipe_reference_init(&buf->base.reference, 1);
buf->base.screen = screen;
buf->base.alignment = 1;
buf->base.usage = 0;
buf->base.size = bytes;
return &buf->base;
}
boolean brw_is_buffer_referenced_by_bo( struct brw_screen *brw_screen,
struct pipe_buffer *buffer,
struct brw_winsys_buffer *bo )
{
struct brw_buffer *buf = brw_buffer(buffer);
if (buf->bo == NULL)
return FALSE;
return brw_screen->sws->bo_references( bo, buf->bo );
}
void brw_screen_buffer_init(struct brw_screen *brw_screen)
{
brw_screen->base.buffer_create = brw_buffer_create;
brw_screen->base.user_buffer_create = brw_user_buffer_create;
brw_screen->base.buffer_map = brw_buffer_map;
brw_screen->base.buffer_map_range = brw_buffer_map_range;
brw_screen->base.buffer_flush_mapped_range = brw_buffer_flush_mapped_range;
brw_screen->base.buffer_unmap = brw_buffer_unmap;
brw_screen->base.buffer_destroy = brw_buffer_destroy;
}