diff --git a/layers/gpu_validation/debug_printf.cpp b/layers/gpu_validation/debug_printf.cpp
index af282977ca4..e1efaef7d2d 100644
--- a/layers/gpu_validation/debug_printf.cpp
+++ b/layers/gpu_validation/debug_printf.cpp
@@ -448,7 +448,7 @@ void DebugPrintf::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQ
     if (!expect && !use_uncached_buffer) return;
 
     uint32_t index = spvtools::kDebugOutputDataOffset;
-    while (debug_output_buffer[index] && (index < output_buffer_size)) {
+    while ((index < output_buffer_size) && debug_output_buffer[index]) {
         std::stringstream shader_message;
         VkShaderModule shader_module_handle = VK_NULL_HANDLE;
         VkPipeline pipeline_handle = VK_NULL_HANDLE;
@@ -816,7 +816,7 @@ void DebugPrintf::AllocateDebugPrintfResources(const VkCommandBuffer cmd_buffer,
     VmaAllocationCreateInfo alloc_info = {};
     alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
     if (use_uncached_buffer) {
-        alloc_info.requiredFlags |= VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD;
+        alloc_info.requiredFlags |= VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD | VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD;
     }
     result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
     if (result != VK_SUCCESS) {
diff --git a/layers/layer_options.cpp b/layers/layer_options.cpp
index 9050b40a43e..b7b38e15976 100644
--- a/layers/layer_options.cpp
+++ b/layers/layer_options.cpp
@@ -54,6 +54,8 @@ const char *SETTING_CUSTOM_STYPE_LIST = "custom_stype_list";
 const char *SETTING_DUPLICATE_MESSAGE_LIMIT = "duplicate_message_limit";
 const char *SETTING_FINE_GRAINED_LOCKING = "fine_grained_locking";
 
+const char *SETTING_DEBUG_PRINTF_UNCACHED_BUFFER = "printf_uncached_buffer";
+
 // Set the local disable flag for the appropriate VALIDATION_CHECK_DISABLE enum
 void SetValidationDisable(CHECK_DISABLED &disable_data, const ValidationCheckDisables disable_id) {
     switch (disable_id) {
@@ -374,6 +376,11 @@ static std::string GetConfigValue(const char *setting) {
     return getLayerOption(key.c_str());
 }
 
+static void SetConfigValue(const char *setting, const char* value) {
+    const std::string key(GetSettingKey(setting));
+    return setLayerOption(key.c_str(), value);
+}
+
 static std::string GetEnvVarValue(const char *setting) {
     std::string env_var = setting;
     vvl::ToUpper(env_var);
@@ -439,6 +446,8 @@ void ProcessConfigAndEnvSettings(ConfigAndEnvSettings *settings_data) {
                 CreateFilterMessageIdList(data, ",", settings_data->message_filter_list);
             } else if (name == SETTING_DUPLICATE_MESSAGE_LIMIT) {
                 *settings_data->duplicate_message_limit = cur_setting.data.value32;
+            } else if ((name == SETTING_DEBUG_PRINTF_UNCACHED_BUFFER) && cur_setting.data.valueBool) {
+                SetConfigValue(SETTING_DEBUG_PRINTF_UNCACHED_BUFFER, "true");
             } else if (name == SETTING_CUSTOM_STYPE_LIST) {
                 if (cur_setting.type == VK_LAYER_SETTING_VALUE_TYPE_STRING_ARRAY_EXT) {
                     std::string data(cur_setting.data.arrayString.pCharArray);
diff --git a/tests/framework/layer_validation_tests.h b/tests/framework/layer_validation_tests.h
index bcf556b128d..bea26f99a0e 100644
--- a/tests/framework/layer_validation_tests.h
+++ b/tests/framework/layer_validation_tests.h
@@ -281,7 +281,7 @@ class VkGpuAssistedLayerTest : public VkLayerTest {
 
 class NegativeDebugPrintf : public VkLayerTest {
   public:
-    void InitDebugPrintfFramework();
+    void InitDebugPrintfFramework(bool use_uncached_buffer = false);
 
   protected:
 };
diff --git a/tests/negative/debug_printf.cpp b/tests/negative/debug_printf.cpp
index 042c9afe7a4..3fdef7e3751 100644
--- a/tests/negative/debug_printf.cpp
+++ b/tests/negative/debug_printf.cpp
@@ -13,7 +13,25 @@
 
 #include "../framework/layer_validation_tests.h"
 
-void NegativeDebugPrintf::InitDebugPrintfFramework() {
+class UncachedBufferSetting {
+  public:
+    UncachedBufferSetting(const bool use_uncached_buffer /*= false*/) {
+        setting_value_data.valueBool = use_uncached_buffer;
+
+        strncpy(setting_val.name, "printf_uncached_buffer", sizeof(setting_val.name));
+        setting_val.type = VK_LAYER_SETTING_VALUE_TYPE_BOOL_EXT;
+        setting_val.data = setting_value_data;
+        setting = {VK_STRUCTURE_TYPE_INSTANCE_LAYER_SETTINGS_EXT, nullptr, 1, &setting_val};
+    }
+    VkLayerSettingsEXT *pnext{&setting};
+
+  private:
+    VkLayerSettingValueDataEXT setting_value_data{};
+    VkLayerSettingValueEXT setting_val;
+    VkLayerSettingsEXT setting;
+};
+
+void NegativeDebugPrintf::InitDebugPrintfFramework(bool use_uncached_buffer) {
     VkValidationFeatureEnableEXT enables[] = {VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT};
     VkValidationFeatureDisableEXT disables[] = {
         VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT, VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT,
@@ -24,6 +42,11 @@ void NegativeDebugPrintf::InitDebugPrintfFramework() {
     features.pEnabledValidationFeatures = enables;
     features.pDisabledValidationFeatures = disables;
 
+    auto uncached_buffer_setting = UncachedBufferSetting(use_uncached_buffer);
+    if (use_uncached_buffer) {
+        features.pNext = uncached_buffer_setting.pnext;
+    }
+
     InitFramework(m_errorMonitor, &features);
 }
 
@@ -1063,3 +1086,113 @@ TEST_F(NegativeDebugPrintf, GPLFragmentIndependentSets) {
     vk::QueueWaitIdle(m_device->m_queue);
     m_errorMonitor->VerifyFound();
 }
+
+TEST_F(NegativeDebugPrintf, UncachedBuffer) {
+    TEST_DESCRIPTION("Verify that calls to debugPrintfEXT are received in debug stream");
+    SetTargetApiVersion(VK_API_VERSION_1_1);
+    AddRequiredExtensions(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME);
+    AddRequiredExtensions(VK_AMD_DEVICE_COHERENT_MEMORY_EXTENSION_NAME);  // It must be supported but if not enabled
+                                                                          // Debug Printf can force enable it.
+    InitDebugPrintfFramework(true /*use_uncached_buffer*/);
+
+    if (!AreRequiredExtensionsEnabled()) {
+        GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported";
+    }
+
+    // deviceCoherentMemory feature needs to be supported, but if not specified or enabled, Debug Printf will force enable it.
+    auto dcm_features = LvlInitStruct<VkPhysicalDeviceCoherentMemoryFeaturesAMD>();
+    auto features2 = GetPhysicalDeviceFeatures2(dcm_features);
+    if (dcm_features.deviceCoherentMemory == 0) {
+        GTEST_SKIP() << "deviceCoherentMemory feature not supported";
+    }
+
+    ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &dcm_features, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
+    if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
+        GTEST_SKIP() << "At least Vulkan version 1.1 is required";
+    }
+
+    auto features = m_device->phy().features();
+    if (!features.vertexPipelineStoresAndAtomics || !features.fragmentStoresAndAtomics) {
+        GTEST_SKIP() << "GPU-Assisted printf test requires vertexPipelineStoresAndAtomics and fragmentStoresAndAtomics";
+    }
+    ASSERT_NO_FATAL_FAILURE(InitViewport());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    if (IsPlatform(kMockICD)) {
+        GTEST_SKIP() << "Test not supported by MockICD, GPU-Assisted validation test requires a driver that can draw";
+    }
+    // Make a uniform buffer to be passed to the shader that contains the test number
+    uint32_t qfi = 0;
+    VkBufferCreateInfo bci = LvlInitStruct<VkBufferCreateInfo>();
+    bci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    bci.size = 8;
+    bci.queueFamilyIndexCount = 1;
+    bci.pQueueFamilyIndices = &qfi;
+
+    VkPushConstantRange push_constant_range = {VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float) * 4};
+
+    const VkPipelineLayoutObj pipeline_layout(m_device, {}, {push_constant_range});
+
+    float push_constants[4] = {0.0, 1.0, 2.0, 3.0};
+
+    char const *shader_source = R"glsl(
+        #version 450
+        #extension GL_EXT_debug_printf : enable
+        layout(push_constant, std430) uniform foo { float x[4]; } constants;
+
+        void main() {
+            float myfloat = 3.1415f;
+            gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
+            if (gl_VertexIndex == 0) {
+                debugPrintfEXT("Here are three float values %f, %f, %f", 1.0, myfloat, gl_Position.x);
+                float x = constants.x[0];
+                while(x > -1.f) { // infinite loop
+                    x += 0.000001f;
+                }
+                debugPrintfEXT("Here is a value that should not be printed %f", x);
+            }
+        }
+    )glsl";
+    char const *message = "Here are three float values 1.000000, 3.141500, 0.000000";
+
+    VkShaderObj vs(this, shader_source, VK_SHADER_STAGE_VERTEX_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_GLSL, nullptr, "main", true);
+
+    VkViewport viewport = m_viewports[0];
+    VkRect2D scissors = m_scissors[0];
+
+    VkSubmitInfo submit_info = LvlInitStruct<VkSubmitInfo>();
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddShader(&vs);
+    pipe.AddDefaultColorAttachment();
+    pipe.DisableRasterization();
+    VkResult err = pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
+    ASSERT_VK_SUCCESS(err);
+
+    VkCommandBufferBeginInfo begin_info = LvlInitStruct<VkCommandBufferBeginInfo>();
+    VkCommandBufferInheritanceInfo hinfo = LvlInitStruct<VkCommandBufferInheritanceInfo>();
+    begin_info.pInheritanceInfo = &hinfo;
+
+    m_commandBuffer->begin(&begin_info);
+    m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
+    vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
+    vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout.handle(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push_constants),
+                         push_constants);
+    vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
+    vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissors);
+    vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
+    vk::CmdEndRenderPass(m_commandBuffer->handle());
+    m_commandBuffer->end();
+
+    m_errorMonitor->SetDesiredFailureMsg(kInformationBit, message);
+
+    err = vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    ASSERT_TRUE((err == VK_SUCCESS) || (err == VK_ERROR_DEVICE_LOST)) << vk_result_string(err);
+    if (err == VK_SUCCESS) {
+        err = vk::QueueWaitIdle(m_device->m_queue);
+        ASSERT_TRUE((err == VK_SUCCESS) || (err == VK_ERROR_DEVICE_LOST)) << vk_result_string(err);
+    }
+    m_errorMonitor->VerifyFound();
+}