#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
-static unsigned int
-svga_texture_is_referenced( struct pipe_context *pipe,
- struct pipe_resource *texture,
- unsigned level, int layer)
-{
- struct svga_texture *tex = svga_texture(texture);
- struct svga_screen *ss = svga_screen(pipe->screen);
-
- /**
- * The screen does not cache texture writes.
- */
-
- if (!tex->handle || ss->sws->surface_is_flushed(ss->sws, tex->handle))
- return PIPE_UNREFERENCED;
-
- /**
- * sws->surface_is_flushed() does not distinguish between read references
- * and write references. So assume a reference is both.
- */
-
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-}
-
-
-
/*
* Helper function and arrays
*/
case PIPE_FORMAT_L8_UNORM:
return svga_translate_format(format);
-#if 1
- /* For on host conversion */
- case PIPE_FORMAT_DXT1_RGB:
- return SVGA3D_X8R8G8B8;
- case PIPE_FORMAT_DXT1_RGBA:
- case PIPE_FORMAT_DXT3_RGBA:
- case PIPE_FORMAT_DXT5_RGBA:
- return SVGA3D_A8R8G8B8;
-#endif
-
default:
return SVGA3D_FORMAT_INVALID;
}
svga_transfer_dma_band(struct svga_context *svga,
struct svga_transfer *st,
SVGA3dTransferType transfer,
- unsigned y, unsigned h, unsigned srcy)
+ unsigned y, unsigned h, unsigned srcy,
+ SVGA3dSurfaceDMAFlags flags)
{
struct svga_texture *texture = svga_texture(st->base.resource);
SVGA3dCopyBox box;
util_format_get_blocksize(texture->b.b.format) * 8 /
(util_format_get_blockwidth(texture->b.b.format)*util_format_get_blockheight(texture->b.b.format)));
- ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1);
+ ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
if(ret != PIPE_OK) {
svga_context_flush(svga, NULL);
- ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1);
+ ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
assert(ret == PIPE_OK);
}
}
static INLINE void
svga_transfer_dma(struct svga_context *svga,
struct svga_transfer *st,
- SVGA3dTransferType transfer)
+ SVGA3dTransferType transfer,
+ SVGA3dSurfaceDMAFlags flags)
{
struct svga_texture *texture = svga_texture(st->base.resource);
struct svga_screen *screen = svga_screen(texture->b.b.screen);
SVGA_DBG(DEBUG_PERF, "%s: readback transfer\n", __FUNCTION__);
}
+ /* Ensure any pending operations on host surfaces are queued on the command
+ * buffer first.
+ */
+ svga_surfaces_flush( svga );
if(!st->swbuf) {
/* Do the DMA transfer in a single go */
- svga_transfer_dma_band(svga, st, transfer, st->base.box.y, st->base.box.height, 0);
+ svga_transfer_dma_band(svga, st, transfer,
+ st->base.box.y, st->base.box.height, 0,
+ flags);
if(transfer == SVGA3D_READ_HOST_VRAM) {
svga_context_flush(svga, &fence);
sw = (uint8_t *)st->swbuf + offset;
- if(transfer == SVGA3D_WRITE_HOST_VRAM) {
+ if (transfer == SVGA3D_WRITE_HOST_VRAM) {
+ unsigned usage = PIPE_TRANSFER_WRITE;
+
/* Wait for the previous DMAs to complete */
/* TODO: keep one DMA (at half the size) in the background */
- if(y) {
- svga_context_flush(svga, &fence);
- sws->fence_finish(sws, fence, 0);
- sws->fence_reference(sws, &fence, NULL);
+ if (y) {
+ svga_context_flush(svga, NULL);
+ usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
}
- hw = sws->buffer_map(sws, st->hwbuf, PIPE_TRANSFER_WRITE);
+ hw = sws->buffer_map(sws, st->hwbuf, usage);
assert(hw);
- if(hw) {
+ if (hw) {
memcpy(hw, sw, length);
sws->buffer_unmap(sws, st->hwbuf);
}
}
- svga_transfer_dma_band(svga, st, transfer, y, h, srcy);
+ svga_transfer_dma_band(svga, st, transfer, y, h, srcy, flags);
+
+ /*
+ * Prevent the texture contents to be discarded on the next band
+ * upload.
+ */
+
+ flags.discard = FALSE;
if(transfer == SVGA3D_READ_HOST_VRAM) {
svga_context_flush(svga, &fence);
goto no_swbuf;
}
- if (usage & PIPE_TRANSFER_READ)
- svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM);
+ if (usage & PIPE_TRANSFER_READ) {
+ SVGA3dSurfaceDMAFlags flags;
+ memset(&flags, 0, sizeof flags);
+ svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM, flags);
+ }
return &st->base;
struct svga_transfer *st = svga_transfer(transfer);
if (st->base.usage & PIPE_TRANSFER_WRITE) {
- svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM);
+ SVGA3dSurfaceDMAFlags flags;
+
+ memset(&flags, 0, sizeof flags);
+ if (transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
+ flags.discard = TRUE;
+ }
+ if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
+ flags.unsynchronized = TRUE;
+ }
+
+ svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM, flags);
ss->texture_timestamp++;
tex->view_age[transfer->level] = ++(tex->age);
if (transfer->resource->target == PIPE_TEXTURE_CUBE)
{
svga_texture_get_handle, /* get_handle */
svga_texture_destroy, /* resource_destroy */
- svga_texture_is_referenced, /* is_resource_referenced */
svga_texture_get_transfer, /* get_transfer */
svga_texture_transfer_destroy, /* transfer_destroy */
svga_texture_transfer_map, /* transfer_map */
tex->key.numFaces = 1;
}
- tex->key.cachable = 1;
+ /* XXX: Disabled for now */
+ tex->key.cachable = 0;
if (template->bind & PIPE_BIND_SAMPLER_VIEW)
tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE;
if (tex->handle)
SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture)\n", tex->handle);
+ debug_reference(&tex->b.b.reference,
+ (debug_reference_descriptor)debug_describe_resource, 0);
+
return &tex->b.b;
error2: