This basically boils down to supporting persistent and coherent buffer
storage.
We chose to use coherent buffer storage for all persistent buffers
even if it's not explicitly specified, since using glMemoryBarrier to
obtain coherency would be particularly expensive in our driver stack,
and require a lot of additional bookkeeping.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
if (!svga->pipe.stream_uploader)
goto cleanup;
if (!svga->pipe.stream_uploader)
goto cleanup;
+ u_upload_disable_persistent(svga->pipe.stream_uploader);
+
svga->pipe.const_uploader = u_upload_create(&svga->pipe, 128 * 1024,
PIPE_BIND_CONSTANT_BUFFER,
PIPE_USAGE_STREAM, 0);
if (!svga->pipe.const_uploader)
goto cleanup;
svga->pipe.const_uploader = u_upload_create(&svga->pipe, 128 * 1024,
PIPE_BIND_CONSTANT_BUFFER,
PIPE_USAGE_STREAM, 0);
if (!svga->pipe.const_uploader)
goto cleanup;
+ u_upload_disable_persistent(svga->pipe.const_uploader);
+
svga->swc = svgascreen->sws->context_create(svgascreen->sws);
if (!svga->swc)
goto cleanup;
svga->swc = svgascreen->sws->context_create(svgascreen->sws);
if (!svga->swc)
goto cleanup;
if (!svga->const0_upload)
goto cleanup;
if (!svga->const0_upload)
goto cleanup;
+ u_upload_disable_persistent(svga->const0_upload);
+
if (!svga_texture_transfer_map_upload_create(svga))
goto cleanup;
if (!svga_texture_transfer_map_upload_create(svga))
goto cleanup;
bind_mask |= PIPE_BIND_CONSTANT_BUFFER;
}
bind_mask |= PIPE_BIND_CONSTANT_BUFFER;
}
+ if (template->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
+ return TRUE;
+
return !!(template->bind & bind_mask);
}
return !!(template->bind & bind_mask);
}
pipe_resource_reference(&sbuf->translated_indices.buffer, NULL);
}
pipe_resource_reference(&sbuf->translated_indices.buffer, NULL);
}
- if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty) {
+ if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty &&
+ !sbuf->key.coherent && !svga->swc->force_coherent) {
enum pipe_error ret;
/* Host-side buffers can only be dirtied with vgpu10 features
enum pipe_error ret;
/* Host-side buffers can only be dirtied with vgpu10 features
}
if (usage & PIPE_TRANSFER_WRITE) {
}
if (usage & PIPE_TRANSFER_WRITE) {
- if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
+ if ((usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) &&
+ !(resource->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)) {
/*
* Flush any pending primitives, finish writing any pending DMA
* commands, and tell the host to discard the buffer contents on
/*
* Flush any pending primitives, finish writing any pending DMA
* commands, and tell the host to discard the buffer contents on
assert(transfer->usage & PIPE_TRANSFER_WRITE);
assert(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT);
assert(transfer->usage & PIPE_TRANSFER_WRITE);
assert(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT);
- if (!svga->swc->force_coherent || sbuf->swbuf) {
+ if (!(svga->swc->force_coherent || sbuf->key.coherent) || sbuf->swbuf) {
mtx_lock(&ss->swc_mutex);
svga_buffer_add_range(sbuf, offset, offset + length);
mtx_unlock(&ss->swc_mutex);
mtx_lock(&ss->swc_mutex);
svga_buffer_add_range(sbuf, offset, offset + length);
mtx_unlock(&ss->swc_mutex);
sbuf->dma.flags.discard = TRUE;
sbuf->dma.flags.discard = TRUE;
- if (!svga->swc->force_coherent || sbuf->swbuf)
+ if (!(svga->swc->force_coherent || sbuf->key.coherent) || sbuf->swbuf)
svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
}
}
svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
}
}
sbuf->key.flags = SVGA3D_SURFACE_TRANSFER_FROM_BUFFER;
}
sbuf->key.flags = SVGA3D_SURFACE_TRANSFER_FROM_BUFFER;
}
+ if (sbuf->b.b.flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) {
+ /* This surface can be mapped persistently. We use
+ * coherent memory to avoid implementing memory barriers for
+ * persistent non-coherent memory for now.
+ */
+ sbuf->key.coherent = 1;
+ }
+
sbuf->key.size.width = sbuf->b.b.width0;
sbuf->key.size.height = 1;
sbuf->key.size.depth = 1;
sbuf->key.size.width = sbuf->b.b.width0;
sbuf->key.size.height = 1;
sbuf->key.size.depth = 1;
struct pipe_resource *dummy;
unsigned i;
struct pipe_resource *dummy;
unsigned i;
- if (swc->force_coherent)
+ if (swc->force_coherent || sbuf->key.coherent)
return PIPE_OK;
assert(svga_have_gb_objects(svga));
return PIPE_OK;
assert(svga_have_gb_objects(svga));
unsigned i;
struct pipe_resource *dummy;
unsigned i;
struct pipe_resource *dummy;
- if (!sbuf->dma.pending || svga->swc->force_coherent) {
+ if (!sbuf->dma.pending || svga->swc->force_coherent ||
+ sbuf->key.coherent) {
//debug_printf("no dma pending on buffer\n");
return;
}
//debug_printf("no dma pending on buffer\n");
return;
}
memcpy((uint8_t *) map + start, (uint8_t *) sbuf->swbuf + start, len);
}
memcpy((uint8_t *) map + start, (uint8_t *) sbuf->swbuf + start, len);
}
- if (svga->swc->force_coherent)
+ if (svga->swc->force_coherent || sbuf->key.coherent)
sbuf->map.num_ranges = 0;
svga_buffer_hw_storage_unmap(svga, sbuf);
sbuf->map.num_ranges = 0;
svga_buffer_hw_storage_unmap(svga, sbuf);
- if (svga->swc->force_coherent)
+ if (svga->swc->force_coherent || sbuf->key.coherent)
return sbuf->handle;
if (sbuf->map.num_ranges) {
return sbuf->handle;
if (sbuf->map.num_ranges) {
{
svga->tex_upload = u_upload_create(&svga->pipe, TEX_UPLOAD_DEFAULT_SIZE,
PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING, 0);
{
svga->tex_upload = u_upload_create(&svga->pipe, TEX_UPLOAD_DEFAULT_SIZE,
PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING, 0);
+ if (svga->tex_upload)
+ u_upload_disable_persistent(svga->tex_upload);
+
return svga->tex_upload != NULL;
}
return svga->tex_upload != NULL;
}
return sws->have_sm4_1 ? 1 : 0; /* only single-channel textures */
case PIPE_CAP_MAX_VARYINGS:
return sws->have_vgpu10 ? VGPU10_MAX_FS_INPUTS : 10;
return sws->have_sm4_1 ? 1 : 0; /* only single-channel textures */
case PIPE_CAP_MAX_VARYINGS:
return sws->have_vgpu10 ? VGPU10_MAX_FS_INPUTS : 10;
+ case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+ return sws->have_coherent;
/* Unsupported features */
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
/* Unsupported features */
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
case PIPE_CAP_TEXTURE_GATHER_SM5:
case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
case PIPE_CAP_TEXTURE_GATHER_SM5:
- case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
case PIPE_CAP_DRAW_INDIRECT:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
case PIPE_CAP_DRAW_INDIRECT: