svga: fix persistent mapped surface update to constant buffer
Currently when a buffer is mapped with the persistent bit set and is later bound as a constant buffer, the updated buffer content is not properly updated to the constant buffer surface as the constant buffer surface is different from the original buffer surface. Doing a buffer copy to sync the content of the constant buffer will fix the problem, but the buffer copy can be costly. To properly fix the issue, instead of creating a secondary surface for the constant buffer, the original buffer surface will be accessed as a raw buffer. This fixes the rendering issue running yuzu deko_basic.nro Reviewed-by: Martin Krastev <krastevm@vmware.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25381>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. All rights reserved.
|
||||
* Copyright 2008-2022 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
@@ -204,10 +204,25 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
|
||||
|
||||
if (sbuf->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.
|
||||
* coherent memory if available to avoid implementing memory barriers
|
||||
* for persistent non-coherent memory for now.
|
||||
*/
|
||||
sbuf->key.coherent = 1;
|
||||
sbuf->key.coherent = ss->sws->have_coherent;
|
||||
|
||||
/* Set the persistent bit so if the buffer is to be bound
|
||||
* as constant buffer, we'll access it as raw buffer
|
||||
* instead of copying the content back and forth between the
|
||||
* mapped buffer surface and the constant buffer surface.
|
||||
*/
|
||||
sbuf->key.persistent = 1;
|
||||
|
||||
/* Set the raw views bind flag only if the mapped buffer surface
|
||||
* is not already bound as constant buffer since constant buffer
|
||||
* surface cannot have other bind flags.
|
||||
*/
|
||||
if ((bind_flags & PIPE_BIND_CONSTANT_BUFFER) == 0) {
|
||||
sbuf->key.flags |= SVGA3D_SURFACE_BIND_RAW_VIEWS;
|
||||
}
|
||||
}
|
||||
|
||||
sbuf->key.size.width = sbuf->b.width0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
/**********************************************************
|
||||
* Copyright 2008-2009 VMware, Inc. All rights reserved.
|
||||
* Copyright 2008-2022 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
@@ -70,10 +70,11 @@ struct svga_host_surface_cache_key
|
||||
uint32_t sampleCount:5;
|
||||
uint32_t scanout:1;
|
||||
uint32_t coherent:1;
|
||||
uint32_t persistent:1;
|
||||
};
|
||||
|
||||
|
||||
struct svga_host_surface_cache_entry
|
||||
struct svga_host_surface_cache_entry
|
||||
{
|
||||
/**
|
||||
* Head for the LRU list, svga_host_surface_cache::unused, and
|
||||
|
||||
@@ -1437,6 +1437,14 @@ struct svga_tracked_state svga_hw_cs_constbufs =
|
||||
};
|
||||
|
||||
|
||||
static inline boolean
|
||||
has_raw_buffer_view(struct svga_buffer *sbuf)
|
||||
{
|
||||
return (sbuf->uav ||
|
||||
(sbuf->key.persistent &&
|
||||
(sbuf->key.flags & SVGA3D_SURFACE_BIND_RAW_VIEWS) != 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper function to update the rawbuf for constbuf mask
|
||||
*/
|
||||
@@ -1454,7 +1462,7 @@ update_rawbuf_mask(struct svga_context *svga, enum pipe_shader_type shader)
|
||||
struct svga_buffer *sbuf =
|
||||
svga_buffer(svga->curr.constbufs[shader][index].buffer);
|
||||
|
||||
if (sbuf && sbuf->uav) {
|
||||
if (sbuf && has_raw_buffer_view(sbuf)) {
|
||||
svga->state.raw_constbufs[shader] |= (1 << index);
|
||||
} else {
|
||||
svga->state.raw_constbufs[shader] &= ~(1 << index);
|
||||
|
||||
Reference in New Issue
Block a user