radv/gfx10: add radv_device::use_ngg
[mesa.git] / src / amd / vulkan / radv_device.c
index ce487aa2eda41070f1b67fa5bdf1c47ef24d9c66..d3c412558baa804cfabdfaca38d5e740847cba88 100644 (file)
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <llvm/Config/llvm-config.h>
 #include "radv_debug.h"
 #include "radv_private.h"
 #include "radv_shader.h"
@@ -85,41 +86,41 @@ radv_get_device_uuid(struct radeon_info *info, void *uuid)
 }
 
 static void
-radv_get_device_name(enum radeon_family family, char *name, size_t name_len)
+radv_get_device_name(enum radeon_family family, char *name, size_t name_len, bool aco)
 {
        const char *chip_string;
 
        switch (family) {
-       case CHIP_TAHITI: chip_string = "AMD RADV TAHITI"; break;
-       case CHIP_PITCAIRN: chip_string = "AMD RADV PITCAIRN"; break;
-       case CHIP_VERDE: chip_string = "AMD RADV CAPE VERDE"; break;
-       case CHIP_OLAND: chip_string = "AMD RADV OLAND"; break;
-       case CHIP_HAINAN: chip_string = "AMD RADV HAINAN"; break;
-       case CHIP_BONAIRE: chip_string = "AMD RADV BONAIRE"; break;
-       case CHIP_KAVERI: chip_string = "AMD RADV KAVERI"; break;
-       case CHIP_KABINI: chip_string = "AMD RADV KABINI"; break;
-       case CHIP_HAWAII: chip_string = "AMD RADV HAWAII"; break;
-       case CHIP_TONGA: chip_string = "AMD RADV TONGA"; break;
-       case CHIP_ICELAND: chip_string = "AMD RADV ICELAND"; break;
-       case CHIP_CARRIZO: chip_string = "AMD RADV CARRIZO"; break;
-       case CHIP_FIJI: chip_string = "AMD RADV FIJI"; break;
-       case CHIP_POLARIS10: chip_string = "AMD RADV POLARIS10"; break;
-       case CHIP_POLARIS11: chip_string = "AMD RADV POLARIS11"; break;
-       case CHIP_POLARIS12: chip_string = "AMD RADV POLARIS12"; break;
-       case CHIP_STONEY: chip_string = "AMD RADV STONEY"; break;
-       case CHIP_VEGAM: chip_string = "AMD RADV VEGA M"; break;
-       case CHIP_VEGA10: chip_string = "AMD RADV VEGA10"; break;
-       case CHIP_VEGA12: chip_string = "AMD RADV VEGA12"; break;
-       case CHIP_VEGA20: chip_string = "AMD RADV VEGA20"; break;
-       case CHIP_RAVEN: chip_string = "AMD RADV RAVEN"; break;
-       case CHIP_RAVEN2: chip_string = "AMD RADV RAVEN2"; break;
-       case CHIP_NAVI10: chip_string = "AMD RADV NAVI10"; break;
-       case CHIP_NAVI12: chip_string = "AMD RADV NAVI12"; break;
-       case CHIP_NAVI14: chip_string = "AMD RADV NAVI14"; break;
-       default: chip_string = "AMD RADV unknown"; break;
-       }
-
-       snprintf(name, name_len, "%s (LLVM " MESA_LLVM_VERSION_STRING ")", chip_string);
+       case CHIP_TAHITI: chip_string = "TAHITI"; break;
+       case CHIP_PITCAIRN: chip_string = "PITCAIRN"; break;
+       case CHIP_VERDE: chip_string = "CAPE VERDE"; break;
+       case CHIP_OLAND: chip_string = "OLAND"; break;
+       case CHIP_HAINAN: chip_string = "HAINAN"; break;
+       case CHIP_BONAIRE: chip_string = "BONAIRE"; break;
+       case CHIP_KAVERI: chip_string = "KAVERI"; break;
+       case CHIP_KABINI: chip_string = "KABINI"; break;
+       case CHIP_HAWAII: chip_string = "HAWAII"; break;
+       case CHIP_TONGA: chip_string = "TONGA"; break;
+       case CHIP_ICELAND: chip_string = "ICELAND"; break;
+       case CHIP_CARRIZO: chip_string = "CARRIZO"; break;
+       case CHIP_FIJI: chip_string = "FIJI"; break;
+       case CHIP_POLARIS10: chip_string = "POLARIS10"; break;
+       case CHIP_POLARIS11: chip_string = "POLARIS11"; break;
+       case CHIP_POLARIS12: chip_string = "POLARIS12"; break;
+       case CHIP_STONEY: chip_string = "STONEY"; break;
+       case CHIP_VEGAM: chip_string = "VEGA M"; break;
+       case CHIP_VEGA10: chip_string = "VEGA10"; break;
+       case CHIP_VEGA12: chip_string = "VEGA12"; break;
+       case CHIP_VEGA20: chip_string = "VEGA20"; break;
+       case CHIP_RAVEN: chip_string = "RAVEN"; break;
+       case CHIP_RAVEN2: chip_string = "RAVEN2"; break;
+       case CHIP_NAVI10: chip_string = "NAVI10"; break;
+       case CHIP_NAVI12: chip_string = "NAVI12"; break;
+       case CHIP_NAVI14: chip_string = "NAVI14"; break;
+       default: chip_string = "unknown"; break;
+       }
+
+       snprintf(name, name_len, "AMD RADV%s %s (LLVM " MESA_LLVM_VERSION_STRING ")", aco ? "/ACO" : "", chip_string);
 }
 
 static uint64_t
@@ -326,7 +327,14 @@ radv_physical_device_init(struct radv_physical_device *device,
 
        radv_handle_env_var_force_family(device);
 
-       radv_get_device_name(device->rad_info.family, device->name, sizeof(device->name));
+       device->use_aco = instance->perftest_flags & RADV_PERFTEST_ACO;
+       if ((device->rad_info.chip_class < GFX8 ||
+            device->rad_info.chip_class > GFX9) && device->use_aco) {
+               fprintf(stderr, "WARNING: disabling ACO on unsupported GPUs.\n");
+               device->use_aco = false;
+       }
+
+       radv_get_device_name(device->rad_info.family, device->name, sizeof(device->name), device->use_aco);
 
        if (radv_device_get_cache_uuid(device->rad_info.family, device->cache_uuid)) {
                device->ws->destroy(device->ws);
@@ -338,7 +346,8 @@ radv_physical_device_init(struct radv_physical_device *device,
        /* These flags affect shader compilation. */
        uint64_t shader_env_flags =
                (device->instance->perftest_flags & RADV_PERFTEST_SISCHED ? 0x1 : 0) |
-               (device->instance->debug_flags & RADV_DEBUG_UNSAFE_MATH ? 0x2 : 0);
+               (device->instance->debug_flags & RADV_DEBUG_UNSAFE_MATH ? 0x2 : 0) |
+               (device->use_aco ? 0x4 : 0);
 
        /* The gpu id is already embedded in the uuid so we just pass "radv"
         * when creating the cache.
@@ -354,15 +363,6 @@ radv_physical_device_init(struct radv_physical_device *device,
        radv_get_driver_uuid(&device->driver_uuid);
        radv_get_device_uuid(&device->rad_info, &device->device_uuid);
 
-       if (device->rad_info.family == CHIP_STONEY ||
-           device->rad_info.chip_class >= GFX9) {
-               device->rbplus_allowed = device->rad_info.family == CHIP_STONEY ||
-                                        device->rad_info.family == CHIP_VEGA12 ||
-                                        device->rad_info.family == CHIP_RAVEN ||
-                                        device->rad_info.family == CHIP_RAVEN2 ||
-                                        device->rad_info.family == CHIP_RENOIR;
-       }
-
        device->out_of_order_rast_allowed = device->rad_info.has_out_of_order_rast &&
                                            !(device->instance->debug_flags & RADV_DEBUG_NO_OUT_OF_ORDER);
 
@@ -370,7 +370,13 @@ radv_physical_device_init(struct radv_physical_device *device,
                (device->instance->perftest_flags & RADV_PERFTEST_DCC_MSAA);
 
        device->use_shader_ballot = device->rad_info.chip_class >= GFX8 &&
-                                   device->instance->perftest_flags & RADV_PERFTEST_SHADER_BALLOT;
+                                   (device->use_aco || device->instance->perftest_flags & RADV_PERFTEST_SHADER_BALLOT);
+
+       device->use_ngg = device->rad_info.chip_class >= GFX10 &&
+                         device->rad_info.family != CHIP_NAVI14 &&
+                         !(device->instance->debug_flags & RADV_DEBUG_NO_NGG);
+
+       device->use_ngg_streamout = false;
 
        /* Determine the number of threads per wave for all stages. */
        device->cs_wave_size = 64;
@@ -484,6 +490,7 @@ static const struct debug_control radv_debug_options[] = {
        {"nongg", RADV_DEBUG_NO_NGG},
        {"noshaderballot", RADV_DEBUG_NO_SHADER_BALLOT},
        {"allentrypoints", RADV_DEBUG_ALL_ENTRYPOINTS},
+       {"metashaders", RADV_DEBUG_DUMP_META_SHADERS},
        {NULL, 0}
 };
 
@@ -505,6 +512,8 @@ static const struct debug_control radv_perftest_options[] = {
        {"cswave32", RADV_PERFTEST_CS_WAVE_32},
        {"pswave32", RADV_PERFTEST_PS_WAVE_32},
        {"gewave32", RADV_PERFTEST_GE_WAVE_32},
+       {"dfsm", RADV_PERFTEST_DFSM},
+       {"aco", RADV_PERFTEST_ACO},
        {NULL, 0}
 };
 
@@ -540,7 +549,7 @@ radv_handle_per_app_options(struct radv_instance *instance,
                 * load/store memory operations.
                 * See https://reviews.llvm.org/D61313
                 */
-               if (HAVE_LLVM < 0x900)
+               if (LLVM_VERSION_MAJOR < 9)
                        instance->debug_flags |= RADV_DEBUG_NO_LOAD_STORE_OPT;
        } else if (!strcmp(name, "Wolfenstein: Youngblood")) {
                if (!(instance->debug_flags & RADV_DEBUG_NO_SHADER_BALLOT)) {
@@ -550,6 +559,14 @@ radv_handle_per_app_options(struct radv_instance *instance,
                         */
                        instance->perftest_flags |= RADV_PERFTEST_SHADER_BALLOT;
                }
+       } else if (!strcmp(name, "Fledge")) {
+               /*
+                * Zero VRAM for "The Surge 2"
+                *
+                * This avoid a hang when when rendering any level. Likely
+                * uninitialized data in an indirect draw.
+                */
+               instance->debug_flags |= RADV_DEBUG_ZERO_VRAM;
        }
 }
 
@@ -564,8 +581,10 @@ static int radv_get_instance_extension_index(const char *name)
 
 static const char radv_dri_options_xml[] =
 DRI_CONF_BEGIN
-       DRI_CONF_SECTION_QUALITY
+       DRI_CONF_SECTION_PERFORMANCE
                DRI_CONF_ADAPTIVE_SYNC("true")
+               DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)
+               DRI_CONF_VK_X11_STRICT_IMAGE_COUNT("false")
        DRI_CONF_SECTION_END
 DRI_CONF_END;
 
@@ -574,7 +593,9 @@ static void  radv_init_dri_options(struct radv_instance *instance)
        driParseOptionInfo(&instance->available_dri_options, radv_dri_options_xml);
        driParseConfigFiles(&instance->dri_options,
                            &instance->available_dri_options,
-                           0, "radv", NULL);
+                           0, "radv", NULL,
+                           instance->engineName,
+                           instance->engineVersion);
 }
 
 VkResult radv_CreateInstance(
@@ -595,6 +616,13 @@ VkResult radv_CreateInstance(
                client_version = VK_API_VERSION_1_0;
        }
 
+       const char *engine_name = NULL;
+       uint32_t engine_version = 0;
+       if (pCreateInfo->pApplicationInfo) {
+               engine_name = pCreateInfo->pApplicationInfo->pEngineName;
+               engine_version = pCreateInfo->pApplicationInfo->engineVersion;
+       }
+
        instance = vk_zalloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
                              VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
        if (!instance)
@@ -616,6 +644,8 @@ VkResult radv_CreateInstance(
        instance->perftest_flags = parse_debug_string(getenv("RADV_PERFTEST"),
                                                   radv_perftest_options);
 
+       if (instance->perftest_flags & RADV_PERFTEST_ACO)
+               fprintf(stderr, "WARNING: Experimental compiler backend enabled. Here be dragons! Incorrect rendering, GPU hangs and/or resets are likely\n");
 
        if (instance->debug_flags & RADV_DEBUG_STARTUP)
                radv_logi("Created an instance");
@@ -638,6 +668,10 @@ VkResult radv_CreateInstance(
                return vk_error(instance, result);
        }
 
+       instance->engineName = vk_strdup(&instance->alloc, engine_name,
+                                        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+       instance->engineVersion = engine_version;
+
        _mesa_locale_init();
        glsl_type_singleton_init_or_ref();
 
@@ -664,6 +698,8 @@ void radv_DestroyInstance(
                radv_physical_device_finish(instance->physicalDevices + i);
        }
 
+       vk_free(&instance->alloc, instance->engineName);
+
        VG(VALGRIND_DESTROY_MEMPOOL(instance));
 
        glsl_type_singleton_decref();
@@ -820,7 +856,7 @@ void radv_GetPhysicalDeviceFeatures(
                .shaderCullDistance                       = true,
                .shaderFloat64                            = true,
                .shaderInt64                              = true,
-               .shaderInt16                              = pdevice->rad_info.chip_class >= GFX9,
+               .shaderInt16                              = pdevice->rad_info.chip_class >= GFX9 && !pdevice->use_aco,
                .sparseBinding                            = true,
                .variableMultisampleRate                  = true,
                .inheritedQueries                         = true,
@@ -862,11 +898,11 @@ void radv_GetPhysicalDeviceFeatures2(
                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
                        VkPhysicalDevice16BitStorageFeatures *features =
                            (VkPhysicalDevice16BitStorageFeatures*)ext;
-                       bool enabled = pdevice->rad_info.chip_class >= GFX8;
+                       bool enabled = pdevice->rad_info.chip_class >= GFX8 && !pdevice->use_aco;
                        features->storageBuffer16BitAccess = enabled;
                        features->uniformAndStorageBuffer16BitAccess = enabled;
                        features->storagePushConstant16 = enabled;
-                       features->storageInputOutput16 = enabled && HAVE_LLVM >= 0x900;
+                       features->storageInputOutput16 = enabled && LLVM_VERSION_MAJOR >= 9;
                        break;
                }
                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
@@ -918,7 +954,7 @@ void radv_GetPhysicalDeviceFeatures2(
                        VkPhysicalDeviceTransformFeedbackFeaturesEXT *features =
                                (VkPhysicalDeviceTransformFeedbackFeaturesEXT*)ext;
                        features->transformFeedback = true;
-                       features->geometryStreams = true;
+                       features->geometryStreams = !pdevice->use_ngg_streamout;
                        break;
                }
                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {
@@ -956,7 +992,7 @@ void radv_GetPhysicalDeviceFeatures2(
                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {
                        VkPhysicalDevice8BitStorageFeaturesKHR *features =
                            (VkPhysicalDevice8BitStorageFeaturesKHR*)ext;
-                       bool enabled = pdevice->rad_info.chip_class >= GFX8;
+                       bool enabled = pdevice->rad_info.chip_class >= GFX8 && !pdevice->use_aco;
                        features->storageBuffer8BitAccess = enabled;
                        features->uniformAndStorageBuffer8BitAccess = enabled;
                        features->storagePushConstant8 = enabled;
@@ -965,15 +1001,21 @@ void radv_GetPhysicalDeviceFeatures2(
                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR: {
                        VkPhysicalDeviceFloat16Int8FeaturesKHR *features =
                                (VkPhysicalDeviceFloat16Int8FeaturesKHR*)ext;
-                       features->shaderFloat16 = pdevice->rad_info.chip_class >= GFX8;
-                       features->shaderInt8 = true;
+                       features->shaderFloat16 = pdevice->rad_info.chip_class >= GFX8 && !pdevice->use_aco;
+                       features->shaderInt8 = !pdevice->use_aco;
                        break;
                }
                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR: {
                        VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *features =
                                (VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *)ext;
-                       features->shaderBufferInt64Atomics = HAVE_LLVM >= 0x0900;
-                       features->shaderSharedInt64Atomics = HAVE_LLVM >= 0x0900;
+                       features->shaderBufferInt64Atomics = LLVM_VERSION_MAJOR >= 9;
+                       features->shaderSharedInt64Atomics = LLVM_VERSION_MAJOR >= 9;
+                       break;
+               }
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT: {
+                       VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *features =
+                               (VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *)ext;
+                       features->shaderDemoteToHelperInvocation = pdevice->use_aco;
                        break;
                }
                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: {
@@ -1234,6 +1276,7 @@ void radv_GetPhysicalDeviceProperties2(
                        if (pdevice->rad_info.chip_class >= GFX8) {
                                properties->supportedOperations |=
                                                        VK_SUBGROUP_FEATURE_ARITHMETIC_BIT |
+                                                       VK_SUBGROUP_FEATURE_CLUSTERED_BIT |
                                                        VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
                                                        VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT;
                        }
@@ -1281,7 +1324,7 @@ void radv_GetPhysicalDeviceProperties2(
 
                        /* SGPR. */
                        properties->sgprsPerSimd =
-                               ac_get_num_physical_sgprs(pdevice->rad_info.chip_class);
+                               pdevice->rad_info.num_physical_sgprs_per_simd;
                        properties->minSgprAllocation =
                                pdevice->rad_info.chip_class >= GFX8 ? 16 : 8;
                        properties->maxSgprAllocation =
@@ -1404,8 +1447,8 @@ void radv_GetPhysicalDeviceProperties2(
                        properties->maxTransformFeedbackStreamDataSize = 512;
                        properties->maxTransformFeedbackBufferDataSize = UINT32_MAX;
                        properties->maxTransformFeedbackBufferDataStride = 512;
-                       properties->transformFeedbackQueries = true;
-                       properties->transformFeedbackStreamsLinesTriangles = true;
+                       properties->transformFeedbackQueries = !pdevice->use_ngg_streamout;
+                       properties->transformFeedbackStreamsLinesTriangles = !pdevice->use_ngg_streamout;
                        properties->transformFeedbackRasterizationStreamSelect = false;
                        properties->transformFeedbackDraw = true;
                        break;
@@ -1735,6 +1778,10 @@ radv_queue_finish(struct radv_queue *queue)
                queue->device->ws->buffer_destroy(queue->gsvs_ring_bo);
        if (queue->tess_rings_bo)
                queue->device->ws->buffer_destroy(queue->tess_rings_bo);
+       if (queue->gds_bo)
+               queue->device->ws->buffer_destroy(queue->gds_bo);
+       if (queue->gds_oa_bo)
+               queue->device->ws->buffer_destroy(queue->gds_oa_bo);
        if (queue->compute_scratch_bo)
                queue->device->ws->buffer_destroy(queue->compute_scratch_bo);
 }
@@ -1945,10 +1992,9 @@ VkResult radv_CreateDevice(
        device->pbb_allowed = device->physical_device->rad_info.chip_class >= GFX9 &&
                              !(device->instance->debug_flags & RADV_DEBUG_NOBINNING);
 
+       /* Disable DFSM by default. As of 2019-09-15 Talos on Low is still 3% slower on Raven. */
        device->dfsm_allowed = device->pbb_allowed &&
-                              (device->physical_device->rad_info.family == CHIP_RAVEN ||
-                               device->physical_device->rad_info.family == CHIP_RAVEN2 ||
-                               device->physical_device->rad_info.family == CHIP_RENOIR);
+                              (device->instance->perftest_flags & RADV_PERFTEST_DFSM);
 
 #ifdef ANDROID
        device->always_use_syncobj = device->physical_device->rad_info.has_syncobj_wait_for_submit;
@@ -2587,6 +2633,7 @@ radv_get_preamble_cs(struct radv_queue *queue,
                     uint32_t esgs_ring_size,
                     uint32_t gsvs_ring_size,
                     bool needs_tess_rings,
+                    bool needs_gds,
                     bool needs_sample_positions,
                     struct radeon_cmdbuf **initial_full_flush_preamble_cs,
                      struct radeon_cmdbuf **initial_preamble_cs,
@@ -2598,8 +2645,10 @@ radv_get_preamble_cs(struct radv_queue *queue,
        struct radeon_winsys_bo *esgs_ring_bo = NULL;
        struct radeon_winsys_bo *gsvs_ring_bo = NULL;
        struct radeon_winsys_bo *tess_rings_bo = NULL;
+       struct radeon_winsys_bo *gds_bo = NULL;
+       struct radeon_winsys_bo *gds_oa_bo = NULL;
        struct radeon_cmdbuf *dest_cs[3] = {0};
-       bool add_tess_rings = false, add_sample_positions = false;
+       bool add_tess_rings = false, add_gds = false, add_sample_positions = false;
        unsigned tess_factor_ring_size = 0, tess_offchip_ring_size = 0;
        unsigned max_offchip_buffers;
        unsigned hs_offchip_param = 0;
@@ -2609,6 +2658,10 @@ radv_get_preamble_cs(struct radv_queue *queue,
                if (needs_tess_rings)
                        add_tess_rings = true;
        }
+       if (!queue->has_gds) {
+               if (needs_gds)
+                       add_gds = true;
+       }
        if (!queue->has_sample_positions) {
                if (needs_sample_positions)
                        add_sample_positions = true;
@@ -2624,7 +2677,7 @@ radv_get_preamble_cs(struct radv_queue *queue,
            compute_scratch_size <= queue->compute_scratch_size &&
            esgs_ring_size <= queue->esgs_ring_size &&
            gsvs_ring_size <= queue->gsvs_ring_size &&
-           !add_tess_rings && !add_sample_positions &&
+           !add_tess_rings && !add_gds && !add_sample_positions &&
            queue->initial_preamble_cs) {
                *initial_full_flush_preamble_cs = queue->initial_full_flush_preamble_cs;
                *initial_preamble_cs = queue->initial_preamble_cs;
@@ -2700,6 +2753,32 @@ radv_get_preamble_cs(struct radv_queue *queue,
                tess_rings_bo = queue->tess_rings_bo;
        }
 
+       if (add_gds) {
+               assert(queue->device->physical_device->rad_info.chip_class >= GFX10);
+
+               /* 4 streamout GDS counters.
+                * We need 256B (64 dw) of GDS, otherwise streamout hangs.
+                */
+               gds_bo = queue->device->ws->buffer_create(queue->device->ws,
+                                                         256, 4,
+                                                         RADEON_DOMAIN_GDS,
+                                                         ring_bo_flags,
+                                                         RADV_BO_PRIORITY_SCRATCH);
+               if (!gds_bo)
+                       goto fail;
+
+               gds_oa_bo = queue->device->ws->buffer_create(queue->device->ws,
+                                                            4, 1,
+                                                            RADEON_DOMAIN_OA,
+                                                            ring_bo_flags,
+                                                            RADV_BO_PRIORITY_SCRATCH);
+               if (!gds_oa_bo)
+                       goto fail;
+       } else {
+               gds_bo = queue->gds_bo;
+               gds_oa_bo = queue->gds_oa_bo;
+       }
+
        if (scratch_bo != queue->scratch_bo ||
            esgs_ring_bo != queue->esgs_ring_bo ||
            gsvs_ring_bo != queue->gsvs_ring_bo ||
@@ -2790,6 +2869,11 @@ radv_get_preamble_cs(struct radv_queue *queue,
                radv_emit_global_shader_pointers(queue, cs, descriptor_bo);
                radv_emit_compute_scratch(queue, cs, compute_scratch_bo);
 
+               if (gds_bo)
+                       radv_cs_add_buffer(queue->device->ws, cs, gds_bo);
+               if (gds_oa_bo)
+                       radv_cs_add_buffer(queue->device->ws, cs, gds_oa_bo);
+
                if (i == 0) {
                        si_cs_emit_cache_flush(cs,
                                               queue->device->physical_device->rad_info.chip_class,
@@ -2865,6 +2949,14 @@ radv_get_preamble_cs(struct radv_queue *queue,
                queue->has_tess_rings = true;
        }
 
+       if (gds_bo != queue->gds_bo) {
+               queue->gds_bo = gds_bo;
+               queue->has_gds = true;
+       }
+
+       if (gds_oa_bo != queue->gds_oa_bo)
+               queue->gds_oa_bo = gds_oa_bo;
+
        if (descriptor_bo != queue->descriptor_bo) {
                if (queue->descriptor_bo)
                        queue->device->ws->buffer_destroy(queue->descriptor_bo);
@@ -2897,6 +2989,11 @@ fail:
                queue->device->ws->buffer_destroy(gsvs_ring_bo);
        if (tess_rings_bo && tess_rings_bo != queue->tess_rings_bo)
                queue->device->ws->buffer_destroy(tess_rings_bo);
+       if (gds_bo && gds_bo != queue->gds_bo)
+               queue->device->ws->buffer_destroy(gds_bo);
+       if (gds_oa_bo && gds_oa_bo != queue->gds_oa_bo)
+               queue->device->ws->buffer_destroy(gds_oa_bo);
+
        return vk_error(queue->device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
 }
 
@@ -3059,6 +3156,7 @@ VkResult radv_QueueSubmit(
        VkResult result;
        bool fence_emitted = false;
        bool tess_rings_needed = false;
+       bool gds_needed = false;
        bool sample_positions_needed = false;
 
        /* Do this first so failing to allocate scratch buffers can't result in
@@ -3074,14 +3172,16 @@ VkResult radv_QueueSubmit(
                        esgs_ring_size = MAX2(esgs_ring_size, cmd_buffer->esgs_ring_size_needed);
                        gsvs_ring_size = MAX2(gsvs_ring_size, cmd_buffer->gsvs_ring_size_needed);
                        tess_rings_needed |= cmd_buffer->tess_rings_needed;
+                       gds_needed |= cmd_buffer->gds_needed;
                        sample_positions_needed |= cmd_buffer->sample_positions_needed;
                }
        }
 
        result = radv_get_preamble_cs(queue, scratch_size, compute_scratch_size,
                                      esgs_ring_size, gsvs_ring_size, tess_rings_needed,
-                                     sample_positions_needed, &initial_flush_preamble_cs,
-                                     &initial_preamble_cs, &continue_preamble_cs);
+                                     gds_needed, sample_positions_needed,
+                                     &initial_flush_preamble_cs,
+                                     &initial_preamble_cs, &continue_preamble_cs);
        if (result != VK_SUCCESS)
                return result;