aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe/lp_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_texture.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c229
1 files changed, 131 insertions, 98 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 8137f29af52..972c7ae7c30 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -37,11 +37,13 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_transfer.h"
#include "lp_context.h"
#include "lp_screen.h"
#include "lp_flush.h"
#include "lp_texture.h"
+#include "lp_setup.h"
#include "lp_tile_size.h"
#include "state_tracker/sw_winsys.h"
@@ -51,10 +53,10 @@
* Simple, maximally packed layout.
*/
static boolean
-llvmpipe_texture_layout(struct llvmpipe_screen *screen,
- struct llvmpipe_texture *lpt)
+llvmpipe_resource_layout(struct llvmpipe_screen *screen,
+ struct llvmpipe_resource *lpt)
{
- struct pipe_texture *pt = &lpt->base;
+ struct pipe_resource *pt = &lpt->base;
unsigned level;
unsigned width = pt->width0;
unsigned height = pt->height0;
@@ -92,7 +94,7 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
static boolean
llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
- struct llvmpipe_texture *lpt)
+ struct llvmpipe_resource *lpt)
{
struct sw_winsys *winsys = screen->winsys;
@@ -103,7 +105,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
unsigned height = align(lpt->base.height0, TILE_SIZE);
lpt->dt = winsys->displaytarget_create(winsys,
- lpt->base.tex_usage,
+ lpt->base.bind,
lpt->base.format,
width, height,
16,
@@ -113,12 +115,12 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
}
-static struct pipe_texture *
-llvmpipe_texture_create(struct pipe_screen *_screen,
- const struct pipe_texture *templat)
+static struct pipe_resource *
+llvmpipe_resource_create(struct pipe_screen *_screen,
+ const struct pipe_resource *templat)
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
- struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture);
+ struct llvmpipe_resource *lpt = CALLOC_STRUCT(llvmpipe_resource);
if (!lpt)
return NULL;
@@ -126,17 +128,17 @@ llvmpipe_texture_create(struct pipe_screen *_screen,
pipe_reference_init(&lpt->base.reference, 1);
lpt->base.screen = &screen->base;
- if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_SCANOUT |
- PIPE_TEXTURE_USAGE_SHARED)) {
+ if (lpt->base.bind & (PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT |
+ PIPE_BIND_SHARED)) {
if (!llvmpipe_displaytarget_layout(screen, lpt))
goto fail;
}
else {
- if (!llvmpipe_texture_layout(screen, lpt))
+ if (!llvmpipe_resource_layout(screen, lpt))
goto fail;
}
-
+
return &lpt->base;
fail:
@@ -146,17 +148,18 @@ llvmpipe_texture_create(struct pipe_screen *_screen,
static void
-llvmpipe_texture_destroy(struct pipe_texture *pt)
+llvmpipe_resource_destroy(struct pipe_screen *pscreen,
+ struct pipe_resource *pt)
{
- struct llvmpipe_screen *screen = llvmpipe_screen(pt->screen);
- struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
+ struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
+ struct llvmpipe_resource *lpt = llvmpipe_resource(pt);
if (lpt->dt) {
/* display target */
struct sw_winsys *winsys = screen->winsys;
winsys->displaytarget_destroy(winsys, lpt->dt);
}
- else {
+ else if (!lpt->userBuffer) {
/* regular texture */
align_free(lpt->data);
}
@@ -169,19 +172,19 @@ llvmpipe_texture_destroy(struct pipe_texture *pt)
* Map a texture. Without any synchronization.
*/
void *
-llvmpipe_texture_map(struct pipe_texture *texture,
- unsigned face,
- unsigned level,
- unsigned zslice)
+llvmpipe_resource_map(struct pipe_resource *texture,
+ unsigned usage,
+ unsigned face,
+ unsigned level,
+ unsigned zslice)
{
- struct llvmpipe_texture *lpt = llvmpipe_texture(texture);
+ struct llvmpipe_resource *lpt = llvmpipe_resource(texture);
uint8_t *map;
if (lpt->dt) {
/* display target */
struct llvmpipe_screen *screen = llvmpipe_screen(texture->screen);
struct sw_winsys *winsys = screen->winsys;
- const unsigned usage = PIPE_BUFFER_USAGE_CPU_READ_WRITE;
assert(face == 0);
assert(level == 0);
@@ -204,7 +207,7 @@ llvmpipe_texture_map(struct pipe_texture *texture,
/* XXX shouldn't that rather be
tex_height = align(u_minify(texture->height0, level), 2)
- to account for alignment done in llvmpipe_texture_layout ?
+ to account for alignment done in llvmpipe_resource_layout ?
*/
if (texture->target == PIPE_TEXTURE_CUBE) {
unsigned tex_height = u_minify(texture->height0, level);
@@ -230,12 +233,12 @@ llvmpipe_texture_map(struct pipe_texture *texture,
* Unmap a texture. Without any synchronization.
*/
void
-llvmpipe_texture_unmap(struct pipe_texture *texture,
+llvmpipe_resource_unmap(struct pipe_resource *texture,
unsigned face,
unsigned level,
unsigned zslice)
{
- struct llvmpipe_texture *lpt = llvmpipe_texture(texture);
+ struct llvmpipe_resource *lpt = llvmpipe_resource(texture);
if (lpt->dt) {
/* display target */
@@ -251,13 +254,13 @@ llvmpipe_texture_unmap(struct pipe_texture *texture,
}
-static struct pipe_texture *
-llvmpipe_texture_from_handle(struct pipe_screen *screen,
- const struct pipe_texture *template,
- struct winsys_handle *whandle)
+static struct pipe_resource *
+llvmpipe_resource_from_handle(struct pipe_screen *screen,
+ const struct pipe_resource *template,
+ struct winsys_handle *whandle)
{
struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
- struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture);
+ struct llvmpipe_resource *lpt = CALLOC_STRUCT(llvmpipe_resource);
if (!lpt)
return NULL;
@@ -281,12 +284,12 @@ llvmpipe_texture_from_handle(struct pipe_screen *screen,
static boolean
-llvmpipe_texture_get_handle(struct pipe_screen *screen,
- struct pipe_texture *pt,
+llvmpipe_resource_get_handle(struct pipe_screen *screen,
+ struct pipe_resource *pt,
struct winsys_handle *whandle)
{
struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
- struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
+ struct llvmpipe_resource *lpt = llvmpipe_resource(pt);
assert(lpt->dt);
if (!lpt->dt)
@@ -298,11 +301,10 @@ llvmpipe_texture_get_handle(struct pipe_screen *screen,
static struct pipe_surface *
llvmpipe_get_tex_surface(struct pipe_screen *screen,
- struct pipe_texture *pt,
+ struct pipe_resource *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned usage)
{
- struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
struct pipe_surface *ps;
assert(level <= pt->last_level);
@@ -310,32 +312,12 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
ps = CALLOC_STRUCT(pipe_surface);
if (ps) {
pipe_reference_init(&ps->reference, 1);
- pipe_texture_reference(&ps->texture, pt);
+ pipe_resource_reference(&ps->texture, pt);
ps->format = pt->format;
ps->width = u_minify(pt->width0, level);
ps->height = u_minify(pt->height0, level);
ps->usage = usage;
- /* Because we are llvmpipe, anything that the state tracker
- * thought was going to be done with the GPU will actually get
- * done with the CPU. Let's adjust the flags to take that into
- * account.
- */
- if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) {
- /* GPU_WRITE means "render" and that can involve reads (blending) */
- ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ;
- }
-
- if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ)
- ps->usage |= PIPE_BUFFER_USAGE_CPU_READ;
-
- if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_GPU_WRITE)) {
- /* Mark the surface as dirty. */
- lpt->timestamp++;
- llvmpipe_screen(screen)->timestamp++;
- }
-
ps->face = face;
ps->level = level;
ps->zslice = zslice;
@@ -352,37 +334,31 @@ llvmpipe_tex_surface_destroy(struct pipe_surface *surf)
* where it would happen. For llvmpipe, nothing to do.
*/
assert(surf->texture);
- pipe_texture_reference(&surf->texture, NULL);
+ pipe_resource_reference(&surf->texture, NULL);
FREE(surf);
}
static struct pipe_transfer *
-llvmpipe_get_tex_transfer(struct pipe_context *pipe,
- struct pipe_texture *texture,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x, unsigned y, unsigned w, unsigned h)
+llvmpipe_get_transfer(struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ struct pipe_subresource sr,
+ unsigned usage,
+ const struct pipe_box *box)
{
- struct llvmpipe_texture *lptex = llvmpipe_texture(texture);
+ struct llvmpipe_resource *lptex = llvmpipe_resource(resource);
struct llvmpipe_transfer *lpt;
- assert(texture);
- assert(level <= texture->last_level);
+ assert(resource);
+ assert(sr.level <= resource->last_level);
lpt = CALLOC_STRUCT(llvmpipe_transfer);
if (lpt) {
struct pipe_transfer *pt = &lpt->base;
- pipe_texture_reference(&pt->texture, texture);
- pt->x = x;
- pt->y = y;
- pt->width = align(w, TILE_SIZE);
- pt->height = align(h, TILE_SIZE);
- pt->stride = lptex->stride[level];
+ pipe_resource_reference(&pt->resource, resource);
+ pt->box = *box;
+ pt->stride = lptex->stride[sr.level];
pt->usage = usage;
- pt->face = face;
- pt->level = level;
- pt->zslice = zslice;
return pt;
}
@@ -391,15 +367,15 @@ llvmpipe_get_tex_transfer(struct pipe_context *pipe,
static void
-llvmpipe_tex_transfer_destroy(struct pipe_context *pipe,
+llvmpipe_transfer_destroy(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
/* Effectively do the texture_update work here - if texture images
* needed post-processing to put them into hardware layout, this is
* where it would happen. For llvmpipe, nothing to do.
*/
- assert (transfer->texture);
- pipe_texture_reference(&transfer->texture, NULL);
+ assert (transfer->resource);
+ pipe_resource_reference(&transfer->resource, NULL);
FREE(transfer);
}
@@ -410,11 +386,11 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
{
struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
ubyte *map;
- struct llvmpipe_texture *lpt;
+ struct llvmpipe_resource *lpt;
enum pipe_format format;
- assert(transfer->texture);
- lpt = llvmpipe_texture(transfer->texture);
+ assert(transfer->resource);
+ lpt = llvmpipe_resource(transfer->resource);
format = lpt->base.format;
/*
@@ -422,14 +398,19 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
* context if necessary.
*/
llvmpipe_flush_texture(pipe,
- transfer->texture, transfer->face, transfer->level,
+ transfer->resource,
+ transfer->sr.face,
+ transfer->sr.level,
0, /* flush_flags */
!(transfer->usage & PIPE_TRANSFER_WRITE), /* read_only */
TRUE, /* cpu_access */
FALSE); /* do_not_flush */
- map = llvmpipe_texture_map(transfer->texture,
- transfer->face, transfer->level, transfer->zslice);
+ map = llvmpipe_resource_map(transfer->resource,
+ transfer->usage,
+ transfer->sr.face,
+ transfer->sr.level,
+ transfer->box.z);
/* May want to different things here depending on read/write nature
* of the map:
@@ -441,8 +422,8 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
}
map +=
- transfer->y / util_format_get_blockheight(format) * transfer->stride +
- transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
+ transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
+ transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
return map;
}
@@ -452,20 +433,68 @@ static void
llvmpipe_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
- assert(transfer->texture);
+ assert(transfer->resource);
+
+ llvmpipe_resource_unmap(transfer->resource,
+ transfer->sr.face,
+ transfer->sr.level,
+ transfer->box.z);
+}
+
+static unsigned int
+llvmpipe_is_resource_referenced( struct pipe_context *pipe,
+ struct pipe_resource *presource,
+ unsigned face, unsigned level)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
+
+ if (presource->target == PIPE_BUFFER)
+ return PIPE_UNREFERENCED;
+
+ return lp_setup_is_resource_referenced(llvmpipe->setup, presource);
+}
+
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_resource *
+llvmpipe_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes,
+ unsigned bind_flags)
+{
+ struct llvmpipe_resource *buffer;
+
+ buffer = CALLOC_STRUCT(llvmpipe_resource);
+ if(!buffer)
+ return NULL;
- llvmpipe_texture_unmap(transfer->texture,
- transfer->face, transfer->level, transfer->zslice);
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */
+ buffer->base.bind = bind_flags;
+ buffer->base._usage = PIPE_USAGE_IMMUTABLE;
+ buffer->base.flags = 0;
+ buffer->base.width0 = bytes;
+ buffer->base.height0 = 1;
+ buffer->base.depth0 = 1;
+ buffer->userBuffer = TRUE;
+ buffer->data = ptr;
+
+ return &buffer->base;
}
void
-llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen)
+llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
{
- screen->texture_create = llvmpipe_texture_create;
- screen->texture_destroy = llvmpipe_texture_destroy;
- screen->texture_from_handle = llvmpipe_texture_from_handle;
- screen->texture_get_handle = llvmpipe_texture_get_handle;
+ screen->resource_create = llvmpipe_resource_create;
+ screen->resource_destroy = llvmpipe_resource_destroy;
+ screen->resource_from_handle = llvmpipe_resource_from_handle;
+ screen->resource_get_handle = llvmpipe_resource_get_handle;
+ screen->user_buffer_create = llvmpipe_user_buffer_create;
screen->get_tex_surface = llvmpipe_get_tex_surface;
screen->tex_surface_destroy = llvmpipe_tex_surface_destroy;
@@ -473,10 +502,14 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen)
void
-llvmpipe_init_context_texture_funcs(struct pipe_context *pipe)
+llvmpipe_init_context_resource_funcs(struct pipe_context *pipe)
{
- pipe->get_tex_transfer = llvmpipe_get_tex_transfer;
- pipe->tex_transfer_destroy = llvmpipe_tex_transfer_destroy;
+ pipe->get_transfer = llvmpipe_get_transfer;
+ pipe->transfer_destroy = llvmpipe_transfer_destroy;
pipe->transfer_map = llvmpipe_transfer_map;
pipe->transfer_unmap = llvmpipe_transfer_unmap;
+ pipe->is_resource_referenced = llvmpipe_is_resource_referenced;
+
+ pipe->transfer_flush_region = u_default_transfer_flush_region;
+ pipe->transfer_inline_write = u_default_transfer_inline_write;
}