Invalidate a "new" surface before it is bound to a render target view or
depth stencil view in order to avoid the unnecessary host side copy
of the surface data before it is rendered to.
Note that, recycled surface is already invalidated before it is reused.
Reviewed-by: Brian Paul <brianp@vmware.com>
assert(!sbuf->user);
if (!sbuf->handle) {
assert(!sbuf->user);
if (!sbuf->handle) {
sbuf->key.flags = 0;
sbuf->key.format = SVGA3D_BUFFER;
sbuf->key.flags = 0;
sbuf->key.format = SVGA3D_BUFFER;
sbuf->b.b.width0);
sbuf->handle = svga_screen_surface_create(ss, sbuf->b.b.bind,
sbuf->b.b.width0);
sbuf->handle = svga_screen_surface_create(ss, sbuf->b.b.bind,
- sbuf->b.b.usage, &sbuf->key);
+ sbuf->b.b.usage,
+ &validated, &sbuf->key);
if (!sbuf->handle)
return PIPE_ERROR_OUT_OF_MEMORY;
if (!sbuf->handle)
return PIPE_ERROR_OUT_OF_MEMORY;
SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
tex->handle = svga_screen_surface_create(svgascreen, bindings,
SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
tex->handle = svga_screen_surface_create(svgascreen, bindings,
- tex->b.b.usage, &tex->key);
+ tex->b.b.usage,
+ &tex->validated, &tex->key);
if (!tex->handle) {
goto fail;
}
if (!tex->handle) {
goto fail;
}
struct svga_winsys_surface *handle;
/**
struct svga_winsys_surface *handle;
/**
+ * Whether the host side surface is validated, either through the
+ * InvalidateGBSurface command or after the surface is updated
+ * or rendered to.
+ */
+ boolean validated;
+
+ /**
* Whether the host side surface is imported and not created by this
* driver.
*/
* Whether the host side surface is imported and not created by this
* driver.
*/
{
check_face_level(tex, face, level);
tex->defined[face] |= 1 << level;
{
check_face_level(tex, face, level);
tex->defined[face] |= 1 << level;
{
check_face_level(tex, face, level);
tex->rendered_to[face] |= 1 << level;
{
check_face_level(tex, face, level);
tex->rendered_to[face] |= 1 << level;
* allocate a new surface.
* \param bind_flags bitmask of PIPE_BIND_x flags
* \param usage one of PIPE_USAGE_x values
* allocate a new surface.
* \param bind_flags bitmask of PIPE_BIND_x flags
* \param usage one of PIPE_USAGE_x values
+ * \param validated return True if the surface is a reused surface
*/
struct svga_winsys_surface *
svga_screen_surface_create(struct svga_screen *svgascreen,
unsigned bind_flags, enum pipe_resource_usage usage,
*/
struct svga_winsys_surface *
svga_screen_surface_create(struct svga_screen *svgascreen,
unsigned bind_flags, enum pipe_resource_usage usage,
struct svga_host_surface_cache_key *key)
{
struct svga_winsys_screen *sws = svgascreen->sws;
struct svga_host_surface_cache_key *key)
{
struct svga_winsys_screen *sws = svgascreen->sws;
key->numMipLevels,
key->numFaces,
key->arraySize);
key->numMipLevels,
key->numFaces,
key->arraySize);
key->size.width,
key->size.height,
key->size.depth);
key->size.width,
key->size.height,
key->size.depth);
struct svga_winsys_surface *
svga_screen_surface_create(struct svga_screen *svgascreen,
unsigned bind_flags, enum pipe_resource_usage usage,
struct svga_winsys_surface *
svga_screen_surface_create(struct svga_screen *svgascreen,
unsigned bind_flags, enum pipe_resource_usage usage,
struct svga_host_surface_cache_key *key);
void
struct svga_host_surface_cache_key *key);
void
struct svga_winsys_surface *handle;
uint32_t i, j;
unsigned z_offset = 0;
struct svga_winsys_surface *handle;
uint32_t i, j;
unsigned z_offset = 0;
SVGA_DBG(DEBUG_PERF,
"svga: Create surface view: layer %d zslice %d mips %d..%d\n",
SVGA_DBG(DEBUG_PERF,
"svga: Create surface view: layer %d zslice %d mips %d..%d\n",
}
SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
}
SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
- handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT, key);
+ handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT,
+ &validated, key);
if (!handle) {
key->cachable = 0;
return NULL;
if (!handle) {
key->cachable = 0;
return NULL;
if (s && s->view_id == SVGA3D_INVALID_ID) {
SVGA3dResourceType resType;
SVGA3dRenderTargetViewDesc desc;
if (s && s->view_id == SVGA3D_INVALID_ID) {
SVGA3dResourceType resType;
SVGA3dRenderTargetViewDesc desc;
+ struct svga_texture *stex = svga_texture(s->base.texture);
+
+ if (stex->validated == FALSE) {
+ assert(stex->handle);
+
+ /* We are about to render into a surface that has not been validated.
+ * First invalidate the surface so that the device does not
+ * need to update the host-side copy with the invalid
+ * content when the associated mob is first bound to the surface.
+ */
+ ret = SVGA3D_InvalidateGBSurface(svga->swc, stex->handle);
+ if (ret != PIPE_OK) {
+ s = NULL;
+ goto done;
+ }
+ stex->validated = TRUE;
+ }
desc.tex.mipSlice = s->real_level;
desc.tex.firstArraySlice = s->real_layer + s->real_zslice;
desc.tex.mipSlice = s->real_level;
desc.tex.firstArraySlice = s->real_layer + s->real_zslice;
SVGA_STATS_TIME_POP(svga_sws(svga));
return s ? &s->base : NULL;
SVGA_STATS_TIME_POP(svga_sws(svga));
return s ? &s->base : NULL;