st/nine: Add drirc option to use data_internal for dynamic textures
authorAxel Davy <davyaxel0@gmail.com>
Wed, 10 Apr 2019 21:09:08 +0000 (23:09 +0200)
committerAxel Davy <davyaxel0@gmail.com>
Tue, 30 Apr 2019 17:18:51 +0000 (19:18 +0200)
dynamic textures seem to have predictable stride. This stride
should be the same as for a ram buffer.

It seems some game don't check the actual stride value, assuming
it to be the expected one.
Thus this workaround (protected by drirc option) is to use an intermediate
ram buffer.

Fixes Rayman Legends texture issues when enabled.

Signed-off-by: Axel Davy <davyaxel0@gmail.com>
src/gallium/state_trackers/nine/adapter9.h
src/gallium/state_trackers/nine/device9.c
src/gallium/state_trackers/nine/device9.h
src/gallium/state_trackers/nine/surface9.c
src/gallium/state_trackers/nine/volume9.c
src/gallium/targets/d3dadapter9/drm.c
src/util/xmlpool/t_options.h

index 60be056f89203b04dbbcbb25e305e5fb0d184dab..ba20a3abe872c0febec76633d3cc7e893f1bb915 100644 (file)
@@ -42,6 +42,7 @@ struct d3dadapter9_context
     BOOL discard_delayed_release;
     BOOL tearfree_discard;
     int csmt_force;
+    BOOL dynamic_texture_workaround;
 
     void (*destroy)( struct d3dadapter9_context *ctx );
 };
index e7317238e6caadf544685481ba884e287833439e..2cc3a9465fa90f11210e78d682d1d4f1894807b9 100644 (file)
@@ -291,6 +291,8 @@ NineDevice9_ctor( struct NineDevice9 *This,
     if (This->csmt_active)
         DBG("\033[1;32mCSMT is active\033[0m\n");
 
+    This->workarounds.dynamic_texture_workaround = pCTX->dynamic_texture_workaround;
+
     This->buffer_upload = nine_upload_create(This->pipe_secondary, 4 * 1024 * 1024, 4);
 
     /* Initialize a dummy VBO to be used when a vertex declaration does not
index 4cce29a28e0d43de569a0971961506cb4a7966b3..167a830d8242a3e60fcbeef72d86979d0664986d 100644 (file)
@@ -138,6 +138,10 @@ struct NineDevice9
         boolean buggy_barycentrics;
     } driver_bugs;
 
+    struct {
+        boolean dynamic_texture_workaround;
+    } workarounds;
+
     struct u_upload_mgr *vertex_uploader;
 
     struct nine_range_pool range_pool;
index d57d13ef7c6fba072bbfc45e5bfa964ebaa4b84c..db74de2823acd0fe640b70a9903b849b2a9e0128 100644 (file)
@@ -146,7 +146,11 @@ NineSurface9_ctor( struct NineSurface9 *This,
                                                          This->base.info.bind,
                                                          FALSE,
                                                          TRUE);
-    if (This->base.info.format != This->format_internal) {
+    if (This->base.info.format != This->format_internal ||
+        /* DYNAMIC Textures requires same stride as ram buffers.
+         * Do not use workaround by default as it eats more virtual space */
+        (pParams->device->workarounds.dynamic_texture_workaround &&
+         pDesc->Pool == D3DPOOL_DEFAULT && pDesc->Usage & D3DUSAGE_DYNAMIC)) {
         This->data_internal = align_calloc(
             nine_format_get_level_alloc_size(This->format_internal,
                                              pDesc->Width,
index ab0a82e288d4125e5e0a07ab9d345dfcce0a1bf5..7a844b28387cff64fe355b3162682e6c0ce56634 100644 (file)
@@ -118,7 +118,11 @@ NineVolume9_ctor( struct NineVolume9 *This,
                                                          This->info.nr_samples,
                                                          This->info.bind, FALSE,
                                                          TRUE);
-    if (This->info.format != This->format_internal) {
+    if (This->info.format != This->format_internal ||
+        /* DYNAMIC Textures requires same stride as ram buffers.
+         * Do not use workaround by default as it eats more virtual space */
+        (pParams->device->workarounds.dynamic_texture_workaround &&
+         pDesc->Pool == D3DPOOL_DEFAULT && pDesc->Usage & D3DUSAGE_DYNAMIC)) {
         This->stride_internal = nine_format_get_stride(This->format_internal,
                                                          pDesc->Width);
         This->layer_stride_internal = util_format_get_2d_size(This->format_internal,
index 4418ceb93d6c9b034b81748077f34c18f3c9ff36..b9ae076c544ab026cdb627ba400e6671b9d965c8 100644 (file)
@@ -59,6 +59,7 @@ DRI_CONF_BEGIN
         DRI_CONF_NINE_ALLOWDISCARDDELAYEDRELEASE("true")
         DRI_CONF_NINE_TEARFREEDISCARD("false")
         DRI_CONF_NINE_CSMT(-1)
+        DRI_CONF_NINE_DYNAMICTEXTUREWORKAROUND("false")
     DRI_CONF_SECTION_END
 DRI_CONF_END;
 
@@ -298,6 +299,11 @@ drm_create_adapter( int fd,
     else
         ctx->base.csmt_force = -1;
 
+    if (driCheckOption(&userInitOptions, "dynamic_texture_workaround", DRI_BOOL))
+        ctx->base.dynamic_texture_workaround = driQueryOptionb(&userInitOptions, "dynamic_texture_workaround");
+    else
+        ctx->base.dynamic_texture_workaround = FALSE;
+
     driDestroyOptionCache(&userInitOptions);
     driDestroyOptionInfo(&defaultInitOptions);
 
index bafecb7c781a06fc0ab8739bcd62c39639c4b05a..1cc9ec33055339bc32c1720f3a316f73782fadea 100644 (file)
@@ -324,6 +324,11 @@ DRI_CONF_OPT_BEGIN(csmt_force, int, def) \
         DRI_CONF_DESC(en,gettext("If set to 1, force gallium nine CSMT. If set to 0, disable it. By default (-1) CSMT is enabled on known thread-safe drivers.")) \
 DRI_CONF_OPT_END
 
+#define DRI_CONF_NINE_DYNAMICTEXTUREWORKAROUND(def) \
+DRI_CONF_OPT_BEGIN_B(dynamic_texture_workaround, def) \
+        DRI_CONF_DESC(en,gettext("If set to true, use a ram intermediate buffer for dynamic textures. Increases ram usage, which can cause out of memory issues, but can fix glitches for some games.")) \
+DRI_CONF_OPT_END
+
 /**
  * \brief radeonsi specific configuration options
  */