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:
Charmaine Lee
2022-08-29 14:14:30 -07:00
committed by Marge Bot
parent 4f96d2f6ba
commit b46526b7a4
3 changed files with 31 additions and 7 deletions
@@ -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;
+3 -2
View File
@@ -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);