summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe/lp_texture.c
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2010-03-13 16:04:06 +0000
committerJosé Fonseca <jfonseca@vmware.com>2010-03-13 16:04:06 +0000
commit3abc7b985ce0787c5103d1a86bd0ba07b127a82f (patch)
tree59b5cbaf0c3c103fb9f5d7237b61ecb29a2b7e32 /src/gallium/drivers/llvmpipe/lp_texture.c
parenta80e33f40731f07e8a39896bfdcd1b1504aedc1f (diff)
llvmpipe: Don't use texture transfer internally.
Now that transfers are context objects their sideeffects must happen in order when used by the state tracker, but that synchronization must be bypassed when used inside the driver, or it would cause infinite recursion.
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_texture.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c158
1 files changed, 96 insertions, 62 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index f2c6dbd088..f3f0cd7b47 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -40,6 +40,7 @@
#include "lp_context.h"
#include "lp_screen.h"
+#include "lp_flush.h"
#include "lp_texture.h"
#include "lp_tile_size.h"
#include "state_tracker/sw_winsys.h"
@@ -163,6 +164,92 @@ 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)
+{
+ struct llvmpipe_texture *lpt = llvmpipe_texture(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);
+ assert(zslice == 0);
+
+ /* FIXME: keep map count? */
+ map = winsys->displaytarget_map(winsys, lpt->dt, usage);
+ }
+ else {
+ /* regular texture */
+ unsigned offset;
+ unsigned stride;
+
+ map = lpt->data;
+
+ assert(level < LP_MAX_TEXTURE_2D_LEVELS);
+
+ offset = lpt->level_offset[level];
+ stride = lpt->stride[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 ?
+ */
+ if (texture->target == PIPE_TEXTURE_CUBE) {
+ unsigned tex_height = u_minify(texture->height0, level);
+ offset += face * util_format_get_nblocksy(texture->format, tex_height) * stride;
+ }
+ else if (texture->target == PIPE_TEXTURE_3D) {
+ unsigned tex_height = u_minify(texture->height0, level);
+ offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * stride;
+ }
+ else {
+ assert(face == 0);
+ assert(zslice == 0);
+ }
+
+ map += offset;
+ }
+
+ return map;
+}
+
+
+/**
+ * Unmap a texture. Without any synchronization.
+ */
+void
+llvmpipe_texture_unmap(struct pipe_texture *texture,
+ unsigned face,
+ unsigned level,
+ unsigned zslice)
+{
+ struct llvmpipe_texture *lpt = llvmpipe_texture(texture);
+
+ if (lpt->dt) {
+ /* display target */
+ struct llvmpipe_screen *lp_screen = llvmpipe_screen(texture->screen);
+ struct sw_winsys *winsys = lp_screen->winsys;
+
+ assert(face == 0);
+ assert(level == 0);
+ assert(zslice == 0);
+
+ winsys->displaytarget_unmap(winsys, lpt->dt);
+ }
+}
+
+
static struct pipe_surface *
llvmpipe_get_tex_surface(struct pipe_screen *screen,
struct pipe_texture *pt,
@@ -181,7 +268,6 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
ps->format = pt->format;
ps->width = u_minify(pt->width0, level);
ps->height = u_minify(pt->height0, level);
- ps->offset = lpt->level_offset[level];
ps->usage = usage;
/* Because we are llvmpipe, anything that the state tracker
@@ -207,23 +293,6 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
ps->face = face;
ps->level = level;
ps->zslice = zslice;
-
- /* XXX shouldn't that rather be
- tex_height = align(ps->height, 2);
- to account for alignment done in llvmpipe_texture_layout ?
- */
- if (pt->target == PIPE_TEXTURE_CUBE) {
- unsigned tex_height = ps->height;
- ps->offset += face * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
- }
- else if (pt->target == PIPE_TEXTURE_3D) {
- unsigned tex_height = ps->height;
- ps->offset += zslice * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
- }
- else {
- assert(face == 0);
- assert(zslice == 0);
- }
}
return ps;
}
@@ -269,24 +338,6 @@ llvmpipe_get_tex_transfer(struct pipe_context *pipe,
pt->level = level;
pt->zslice = zslice;
- lpt->offset = lptex->level_offset[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 ?
- */
- 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;
- }
- 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 {
- assert(face == 0);
- assert(zslice == 0);
- }
return pt;
}
return NULL;
@@ -312,7 +363,7 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
- ubyte *map, *xfer_map;
+ ubyte *map;
struct llvmpipe_texture *lpt;
enum pipe_format format;
@@ -320,34 +371,24 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
lpt = llvmpipe_texture(transfer->texture);
format = lpt->base.format;
- if (lpt->dt) {
- /* display target */
- struct sw_winsys *winsys = screen->winsys;
- map = winsys->displaytarget_map(winsys, lpt->dt,
- pipe_transfer_buffer_flags(transfer));
- if (map == NULL)
- return NULL;
- }
- else {
- /* regular texture */
- map = lpt->data;
- }
+ map = llvmpipe_texture_map(transfer->texture,
+ transfer->face, transfer->level, transfer->zslice);
/* May want to different things here depending on read/write nature
* of the map:
*/
- if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) {
+ if (transfer->usage & PIPE_TRANSFER_WRITE) {
/* Do something to notify sharing contexts of a texture change.
*/
screen->timestamp++;
}
- xfer_map = map + llvmpipe_transfer(transfer)->offset +
+ map +=
transfer->y / util_format_get_blockheight(format) * transfer->stride +
transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
- /*printf("map = %p xfer map = %p\n", map, xfer_map);*/
- return xfer_map;
+
+ return map;
}
@@ -355,17 +396,10 @@ static void
llvmpipe_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
- struct llvmpipe_screen *lp_screen = llvmpipe_screen(pipe->screen);
- struct llvmpipe_texture *lpt;
-
assert(transfer->texture);
- lpt = llvmpipe_texture(transfer->texture);
- if (lpt->dt) {
- /* display target */
- struct sw_winsys *winsys = lp_screen->winsys;
- winsys->displaytarget_unmap(winsys, lpt->dt);
- }
+ llvmpipe_texture_unmap(transfer->texture,
+ transfer->face, transfer->level, transfer->zslice);
}