nv50,nvc0: add invalidate_resource support for buffer resources

Provide a callback to reallocate the underlying storage of a resource so
that it is not bound to any existing fences.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
Ilia Mirkin 2016-04-03 15:11:39 -04:00
parent 30b818d5eb
commit f9480d7918
7 changed files with 51 additions and 2 deletions

View file

@ -843,6 +843,39 @@ nouveau_user_buffer_upload(struct nouveau_context *nv,
return true;
}
/* Invalidate underlying buffer storage, reset fences, reallocate to non-busy
* buffer.
*/
void
nouveau_buffer_invalidate(struct pipe_context *pipe,
struct pipe_resource *resource)
{
struct nouveau_context *nv = nouveau_context(pipe);
struct nv04_resource *buf = nv04_resource(resource);
int ref = buf->base.reference.count - 1;
/* Shared buffers shouldn't get reallocated */
if (unlikely(buf->base.bind & PIPE_BIND_SHARED))
return;
/* We can't touch persistent/coherent buffers */
if (buf->base.flags & (PIPE_RESOURCE_FLAG_MAP_PERSISTENT |
PIPE_RESOURCE_FLAG_MAP_COHERENT))
return;
/* If the buffer is sub-allocated and not currently being written, just
* wipe the valid buffer range. Otherwise we have to create fresh
* storage. (We don't keep track of fences for non-sub-allocated BO's.)
*/
if (buf->mm && !nouveau_buffer_busy(buf, PIPE_TRANSFER_WRITE)) {
util_range_set_empty(&buf->valid_buffer_range);
} else {
nouveau_buffer_reallocate(nv->screen, buf, buf->domain);
if (ref > 0) /* any references inside context possible ? */
nv->invalidate_resource_storage(nv, &buf->base, ref);
}
}
/* Scratch data allocation. */

View file

@ -99,6 +99,10 @@ bool
nouveau_user_buffer_upload(struct nouveau_context *, struct nv04_resource *,
unsigned base, unsigned size);
void
nouveau_buffer_invalidate(struct pipe_context *pipe,
struct pipe_resource *resource);
/* Copy data to a scratch buffer and return address & bo the data resides in.
* Returns 0 on failure.
*/

View file

@ -84,6 +84,13 @@ nv50_surface_destroy(struct pipe_context *pipe, struct pipe_surface *ps)
FREE(s);
}
void
nv50_invalidate_resource(struct pipe_context *pipe, struct pipe_resource *res)
{
if (res->target == PIPE_BUFFER)
nouveau_buffer_invalidate(pipe, res);
}
void
nv50_init_resource_functions(struct pipe_context *pcontext)
{
@ -93,6 +100,7 @@ nv50_init_resource_functions(struct pipe_context *pcontext)
pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
pcontext->create_surface = nv50_surface_create;
pcontext->surface_destroy = nv50_surface_destroy;
pcontext->invalidate_resource = nv50_invalidate_resource;
}
void

View file

@ -151,6 +151,9 @@ nv50_surface_from_buffer(struct pipe_context *pipe,
void
nv50_surface_destroy(struct pipe_context *, struct pipe_surface *);
void
nv50_invalidate_resource(struct pipe_context *, struct pipe_resource *);
void
nv50_clear_texture(struct pipe_context *pipe,
struct pipe_resource *res,

View file

@ -193,6 +193,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_CLEAR_TEXTURE:
case PIPE_CAP_COMPUTE:
case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
case PIPE_CAP_INVALIDATE_BUFFER:
return 1;
case PIPE_CAP_SEAMLESS_CUBE_MAP:
return 1; /* class_3d >= NVA0_3D_CLASS; */
@ -234,7 +235,6 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
case PIPE_CAP_INVALIDATE_BUFFER:
case PIPE_CAP_GENERATE_MIPMAP:
case PIPE_CAP_STRING_MARKER:
case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:

View file

@ -52,6 +52,7 @@ nvc0_init_resource_functions(struct pipe_context *pcontext)
pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
pcontext->create_surface = nvc0_surface_create;
pcontext->surface_destroy = nv50_surface_destroy;
pcontext->invalidate_resource = nv50_invalidate_resource;
}
void

View file

@ -216,6 +216,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
case PIPE_CAP_QUERY_BUFFER_OBJECT:
case PIPE_CAP_INVALIDATE_BUFFER:
return 1;
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
@ -241,7 +242,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
case PIPE_CAP_INVALIDATE_BUFFER:
case PIPE_CAP_GENERATE_MIPMAP:
case PIPE_CAP_STRING_MARKER:
case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY: