All affected operations have already been moved to context.
More cleanup work can be done, in particular with the buffer transfers.
struct pipe_fence_handle **pfence )
{
struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
+ struct pipe_fence_handle *fence = NULL;
svga->curr.nr_fbs = 0;
u_upload_flush(svga->upload_vb);
u_upload_flush(svga->upload_ib);
- /* Flush screen, to ensure that texture dma uploads are processed
+ /* Ensure that texture dma uploads are processed
* before submitting commands.
*/
- svga_screen_flush(svgascreen, NULL);
-
svga_context_flush_buffers(svga);
/* Flush pending commands to hardware:
*/
- svga->swc->flush(svga->swc, pfence);
+ svga->swc->flush(svga->swc, &fence);
+
+ svga_screen_cache_flush(svgascreen, fence);
if (SVGA_DEBUG & DEBUG_SYNC) {
- if (pfence && *pfence)
- svga->pipe.screen->fence_finish( svga->pipe.screen, *pfence, 0);
+ if (fence)
+ svga->pipe.screen->fence_finish( svga->pipe.screen, fence, 0);
}
+
+ if(pfence)
+ *pfence = fence;
+ else
+ svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
}
static struct pipe_query *svga_create_query( struct pipe_context *pipe,
unsigned query_type )
{
+ struct svga_context *svga = svga_context( pipe );
struct svga_screen *svgascreen = svga_screen(pipe->screen);
struct svga_winsys_screen *sws = svgascreen->sws;
struct svga_query *sq;
sq->type = SVGA3D_QUERYTYPE_OCCLUSION;
- sq->hwbuf = svga_winsys_buffer_create(svgascreen,
+ sq->hwbuf = svga_winsys_buffer_create(svga,
1,
SVGA_BUFFER_USAGE_PINNED,
sizeof *sq->queryResult);
}
if(map) {
- pipe_mutex_lock(ss->swc_mutex);
-
++sbuf->map.count;
if (usage & PIPE_TRANSFER_WRITE) {
if (usage & PIPE_TRANSFER_FLUSH_EXPLICIT)
sbuf->map.flush_explicit = TRUE;
}
-
- pipe_mutex_unlock(ss->swc_mutex);
}
return map;
svga_context_flush_buffers(struct svga_context *svga);
struct svga_winsys_buffer *
-svga_winsys_buffer_create(struct svga_screen *ss,
+svga_winsys_buffer_create(struct svga_context *svga,
unsigned alignment,
unsigned usage,
unsigned size);
#include "svga_debug.h"
-/* Allocate a winsys_buffer (ie. DMA, aka GMR memory).
+/**
+ * Allocate a winsys_buffer (ie. DMA, aka GMR memory).
+ *
+ * It will flush and retry in case the first attempt to create a DMA buffer
+ * fails, so it should not be called from any function involved in flushing
+ * to avoid recursion.
*/
struct svga_winsys_buffer *
-svga_winsys_buffer_create( struct svga_screen *ss,
+svga_winsys_buffer_create( struct svga_context *svga,
unsigned alignment,
unsigned usage,
unsigned size )
{
- struct svga_winsys_screen *sws = ss->sws;
+ struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
+ struct svga_winsys_screen *sws = svgascreen->sws;
struct svga_winsys_buffer *buf;
/* Just try */
size);
/* Try flushing all pending DMAs */
- svga_screen_flush(ss, NULL);
+ svga_context_flush(svga, NULL);
buf = sws->buffer_create(sws, alignment, usage, size);
-
}
return buf;
assert(!sbuf->user);
if(!sbuf->hwbuf) {
+ struct svga_winsys_screen *sws = ss->sws;
unsigned alignment = 16;
unsigned usage = 0;
unsigned size = sbuf->b.b.width0;
- sbuf->hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
+ sbuf->hwbuf = sws->buffer_create(sws, alignment, usage, size);
if(!sbuf->hwbuf)
return PIPE_ERROR_OUT_OF_MEMORY;
if (offset + size > range->end)
size = range->end - offset;
- hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
+ hwbuf = sws->buffer_create(sws, alignment, usage, size);
while (!hwbuf) {
size /= 2;
if (!size)
return PIPE_ERROR_OUT_OF_MEMORY;
- hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
+ hwbuf = sws->buffer_create(sws, alignment, usage, size);
}
SVGA_DBG(DEBUG_DMA, " bytes %u - %u\n",
static INLINE void
-svga_transfer_dma_band(struct svga_transfer *st,
+svga_transfer_dma_band(struct svga_context *svga,
+ struct svga_transfer *st,
SVGA3dTransferType transfer,
unsigned y, unsigned h, unsigned srcy)
{
struct svga_texture *texture = svga_texture(st->base.resource);
- struct svga_screen *screen = svga_screen(texture->b.b.screen);
SVGA3dCopyBox box;
enum pipe_error ret;
box.srcy = srcy;
box.srcz = 0;
- pipe_mutex_lock(screen->swc_mutex);
- ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1);
+ ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1);
if(ret != PIPE_OK) {
- screen->swc->flush(screen->swc, NULL);
- ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1);
+ svga->swc->flush(svga->swc, NULL);
+ ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1);
assert(ret == PIPE_OK);
}
- pipe_mutex_unlock(screen->swc_mutex);
}
static INLINE void
-svga_transfer_dma(struct svga_transfer *st,
- SVGA3dTransferType transfer)
+svga_transfer_dma(struct svga_context *svga,
+ struct svga_transfer *st,
+ SVGA3dTransferType transfer)
{
struct svga_texture *texture = svga_texture(st->base.resource);
struct svga_screen *screen = svga_screen(texture->b.b.screen);
if(!st->swbuf) {
/* Do the DMA transfer in a single go */
- svga_transfer_dma_band(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);
if(transfer == SVGA3D_READ_HOST_VRAM) {
- svga_screen_flush(screen, &fence);
+ svga_context_flush(svga, &fence);
sws->fence_finish(sws, fence, 0);
sws->fence_reference(sws, &fence, NULL);
}
/* Wait for the previous DMAs to complete */
/* TODO: keep one DMA (at half the size) in the background */
if(y) {
- svga_screen_flush(screen, &fence);
+ svga_context_flush(svga, &fence);
sws->fence_finish(sws, fence, 0);
sws->fence_reference(sws, &fence, NULL);
}
}
}
- svga_transfer_dma_band(st, transfer, y, h, srcy);
+ svga_transfer_dma_band(svga, st, transfer, y, h, srcy);
if(transfer == SVGA3D_READ_HOST_VRAM) {
- svga_screen_flush(screen, &fence);
+ svga_context_flush(svga, &fence);
sws->fence_finish(sws, fence, 0);
hw = sws->buffer_map(sws, st->hwbuf, PIPE_TRANSFER_READ);
unsigned usage,
const struct pipe_box *box)
{
+ struct svga_context *svga = svga_context(pipe);
struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_winsys_screen *sws = ss->sws;
struct svga_transfer *st;
st->hw_nblocksy = nblocksy;
- st->hwbuf = svga_winsys_buffer_create(ss,
+ st->hwbuf = svga_winsys_buffer_create(svga,
1,
0,
st->hw_nblocksy*st->base.stride);
while(!st->hwbuf && (st->hw_nblocksy /= 2)) {
- st->hwbuf = svga_winsys_buffer_create(ss,
+ st->hwbuf = svga_winsys_buffer_create(svga,
1,
0,
st->hw_nblocksy*st->base.stride);
}
if (usage & PIPE_TRANSFER_READ)
- svga_transfer_dma(st, SVGA3D_READ_HOST_VRAM);
+ svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM);
return &st->base;
svga_texture_transfer_destroy(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
+ struct svga_context *svga = svga_context(pipe);
struct svga_texture *tex = svga_texture(transfer->resource);
struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_winsys_screen *sws = ss->sws;
struct svga_transfer *st = svga_transfer(transfer);
if (st->base.usage & PIPE_TRANSFER_WRITE) {
- svga_transfer_dma(st, SVGA3D_WRITE_HOST_VRAM);
+ svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM);
ss->texture_timestamp++;
tex->view_age[transfer->sr.level] = ++(tex->age);
tex->defined[transfer->sr.face][transfer->sr.level] = TRUE;
for (i = v->min_lod; i <= v->max_lod; i++) {
for (k = 0; k < numFaces; k++) {
if (v->age < tex->view_age[i])
- svga_texture_copy_handle(svga, NULL,
+ svga_texture_copy_handle(svga,
tex->handle, 0, 0, 0, i, k,
v->handle, 0, 0, 0, i - v->min_lod, k,
u_minify(tex->b.b.width0, i),
pipe_mutex_destroy(svgascreen->swc_mutex);
pipe_mutex_destroy(svgascreen->tex_mutex);
- svgascreen->swc->destroy(svgascreen->swc);
-
svgascreen->sws->destroy(svgascreen->sws);
FREE(svgascreen);
svgascreen->use_vs30 = svgascreen->use_ps30 = FALSE;
#endif
- svgascreen->swc = sws->context_create(sws);
- if(!svgascreen->swc)
- goto error2;
-
pipe_mutex_init(svgascreen->tex_mutex);
pipe_mutex_init(svgascreen->swc_mutex);
return NULL;
}
-void svga_screen_flush( struct svga_screen *svgascreen,
- struct pipe_fence_handle **pfence )
-{
- struct pipe_fence_handle *fence = NULL;
-
- SVGA_DBG(DEBUG_PERF, "%s\n", __FUNCTION__);
-
- pipe_mutex_lock(svgascreen->swc_mutex);
- svgascreen->swc->flush(svgascreen->swc, &fence);
- pipe_mutex_unlock(svgascreen->swc_mutex);
-
- svga_screen_cache_flush(svgascreen, fence);
-
- if(pfence)
- *pfence = fence;
- else
- svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
-}
-
struct svga_winsys_screen *
svga_winsys_screen(struct pipe_screen *screen)
{
boolean no_sampler_view;
} debug;
- /* The screen needs its own context */
- struct svga_winsys_context *swc;
- struct SVGACmdMemory *fifo;
-
unsigned texture_timestamp;
pipe_mutex tex_mutex;
- pipe_mutex swc_mutex; /* Protects the use of swc and dirty_buffers */
-
+
+ pipe_mutex swc_mutex; /* Used for buffer uploads */
+
struct svga_host_surface_cache cache;
};
svga_screen(struct pipe_screen *screen);
#endif
-void svga_screen_flush( struct svga_screen *svga_screen,
- struct pipe_fence_handle **pfence );
-
#endif /* SVGA_SCREEN_H */
void
svga_texture_copy_handle(struct svga_context *svga,
- struct svga_screen *ss,
struct svga_winsys_surface *src_handle,
unsigned src_x, unsigned src_y, unsigned src_z,
unsigned src_level, unsigned src_face,
enum pipe_error ret;
SVGA3dCopyBox box, *boxes;
- assert(svga || ss);
+ assert(svga);
src.handle = src_handle;
src.real_level = src_level;
dst_handle, dst_level, dst_x, dst_y, dst_z);
*/
- if (svga) {
+ ret = SVGA3D_BeginSurfaceCopy(svga->swc,
+ &src.base,
+ &dst.base,
+ &boxes, 1);
+ if(ret != PIPE_OK) {
+ svga_context_flush(svga, NULL);
ret = SVGA3D_BeginSurfaceCopy(svga->swc,
&src.base,
&dst.base,
&boxes, 1);
- if(ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_BeginSurfaceCopy(svga->swc,
- &src.base,
- &dst.base,
- &boxes, 1);
- assert(ret == PIPE_OK);
- }
- *boxes = box;
- SVGA_FIFOCommitAll(svga->swc);
- } else {
- pipe_mutex_lock(ss->swc_mutex);
- ret = SVGA3D_BeginSurfaceCopy(ss->swc,
- &src.base,
- &dst.base,
- &boxes, 1);
- if(ret != PIPE_OK) {
- ss->swc->flush(ss->swc, NULL);
- ret = SVGA3D_BeginSurfaceCopy(ss->swc,
- &src.base,
- &dst.base,
- &boxes, 1);
- assert(ret == PIPE_OK);
- }
- *boxes = box;
- SVGA_FIFOCommitAll(ss->swc);
- pipe_mutex_unlock(ss->swc_mutex);
+ assert(ret == PIPE_OK);
}
+ *boxes = box;
+ SVGA_FIFOCommitAll(svga->swc);
}
1);
svga_texture_copy_handle(svga_context(pipe),
- ss,
tex->handle,
0, 0, z_offset,
i + start_mip,
if (s->handle != tex->handle) {
SVGA_DBG(DEBUG_VIEWS, "svga: Surface propagate: tex %p, level %u, from %p\n", tex, surf->level, surf);
- svga_texture_copy_handle(svga_context(pipe), ss,
+ svga_texture_copy_handle(svga_context(pipe),
s->handle, 0, 0, 0, s->real_level, s->real_face,
tex->handle, 0, 0, surf->zslice, surf->level, surf->face,
u_minify(tex->b.b.width0, surf->level),
void
svga_texture_copy_handle(struct svga_context *svga,
- struct svga_screen *ss,
struct svga_winsys_surface *src_handle,
unsigned src_x, unsigned src_y, unsigned src_z,
unsigned src_level, unsigned src_face,