summaryrefslogtreecommitdiff
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.c176
1 files changed, 114 insertions, 62 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 5f75078109..779b486bfd 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -37,10 +37,12 @@
#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_texture.h"
+#include "lp_setup.h"
#include "lp_tile_size.h"
#include "state_tracker/sw_winsys.h"
@@ -50,10 +52,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;
@@ -91,7 +93,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;
@@ -111,12 +113,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;
@@ -131,7 +133,7 @@ llvmpipe_texture_create(struct pipe_screen *_screen,
goto fail;
}
else {
- if (!llvmpipe_texture_layout(screen, lpt))
+ if (!llvmpipe_resource_layout(screen, lpt))
goto fail;
}
@@ -144,10 +146,11 @@ 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 */
@@ -165,11 +168,11 @@ llvmpipe_texture_destroy(struct pipe_texture *pt)
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 llvmpipe_resource *lpt = llvmpipe_resource(pt);
struct pipe_surface *ps;
assert(level <= pt->last_level);
@@ -177,7 +180,7 @@ 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);
@@ -210,7 +213,7 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
/* XXX shouldn't that rather be
tex_height = align(ps->height, 2);
- to account for alignment done in llvmpipe_texture_layout ?
+ to account for alignment done in llvmpipe_resource_layout ?
*/
if (pt->target == PIPE_TEXTURE_CUBE) {
unsigned tex_height = ps->height;
@@ -237,55 +240,56 @@ 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_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)
+ struct pipe_resource *resource,
+ struct pipe_subresource sr,
+ enum pipe_transfer_usage 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;
- lpt->offset = lptex->level_offset[level];
+ /* XXX: this is bogus - the caller should be doing this, not
+ * imposing it on all transfers.
+ */
+ pt->box.width = align(pt->box.width, TILE_SIZE);
+ pt->box.height = align(pt->box.height, TILE_SIZE);
+
+ pt->stride = lptex->stride[sr.level];
+ lpt->offset = lptex->level_offset[sr.level];
/* XXX shouldn't that rather be
- tex_height = align(u_minify(texture->height0, level), 2)
- to account for alignment done in llvmpipe_texture_layout ?
+ tex_height = align(u_minify(resource->height0, level), 2)
+ to account for alignment done in llvmpipe_resource_layout ?
*/
- if (texture->target == PIPE_TEXTURE_CUBE) {
- unsigned tex_height = u_minify(texture->height0, level);
- lpt->offset += face * util_format_get_nblocksy(texture->format, tex_height) * pt->stride;
+ if (resource->target == PIPE_TEXTURE_CUBE) {
+ unsigned tex_height = u_minify(resource->height0, sr.level);
+ lpt->offset += sr.face * util_format_get_nblocksy(resource->format, tex_height) * pt->stride;
}
- else if (texture->target == PIPE_TEXTURE_3D) {
- unsigned tex_height = u_minify(texture->height0, level);
- lpt->offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * pt->stride;
+ else if (resource->target == PIPE_TEXTURE_3D) {
+ unsigned tex_height = u_minify(resource->height0, sr.level);
+ lpt->offset += box->z * util_format_get_nblocksy(resource->format, tex_height) * pt->stride;
}
else {
- assert(face == 0);
- assert(zslice == 0);
+ assert(sr.face == 0);
+ assert(box->z == 0);
}
return pt;
}
@@ -301,8 +305,8 @@ llvmpipe_transfer_destroy(struct pipe_context *pipe,
* 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);
}
@@ -313,11 +317,11 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
{
struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
ubyte *map, *xfer_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;
if (lpt->dt) {
@@ -325,27 +329,27 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
struct sw_winsys *winsys = screen->winsys;
map = winsys->displaytarget_map(winsys, lpt->dt,
- pipe_transfer_buffer_flags(transfer));
+ transfer->usage);
if (map == NULL)
return NULL;
}
else {
- /* regular texture */
+ /* regular resource */
map = lpt->data;
}
/* May want to different things here depending on read/write nature
* of the map:
*/
- if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) {
- /* Do something to notify sharing contexts of a texture change.
+ if (transfer->resource && (transfer->usage & PIPE_TRANSFER_WRITE)) {
+ /* Do something to notify sharing contexts of a resource change.
*/
screen->timestamp++;
}
xfer_map = map + llvmpipe_transfer(transfer)->offset +
- 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);
/*printf("map = %p xfer map = %p\n", map, xfer_map);*/
return xfer_map;
}
@@ -356,10 +360,10 @@ llvmpipe_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct llvmpipe_screen *lp_screen = llvmpipe_screen(pipe->screen);
- struct llvmpipe_texture *lpt;
+ struct llvmpipe_resource *lpt;
- assert(transfer->texture);
- lpt = llvmpipe_texture(transfer->texture);
+ assert(transfer->resource);
+ lpt = llvmpipe_resource(transfer->resource);
if (lpt->dt) {
/* display target */
@@ -368,12 +372,56 @@ llvmpipe_transfer_unmap(struct pipe_context *pipe,
}
}
+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 usage)
+{
+ struct llvmpipe_resource *buffer;
+
+ buffer = CALLOC_STRUCT(llvmpipe_resource);
+ if(!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */
+ buffer->base.usage = PIPE_BUFFER_USAGE_CPU_READ | usage;
+ 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->resource_create = llvmpipe_resource_create;
+ screen->resource_destroy = llvmpipe_resource_destroy;
+ screen->user_buffer_create = llvmpipe_user_buffer_create;
screen->get_tex_surface = llvmpipe_get_tex_surface;
screen->tex_surface_destroy = llvmpipe_tex_surface_destroy;
@@ -381,10 +429,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_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;
}