radv: handle 10-bit format clamping workaround.
authorDave Airlie <airlied@redhat.com>
Thu, 27 Jul 2017 20:52:20 +0000 (21:52 +0100)
committerDave Airlie <airlied@redhat.com>
Mon, 31 Jul 2017 23:10:23 +0000 (00:10 +0100)
This fixes:
dEQP-VK.api.copy_and_blit.core.blit_image.all_formats.*
for a2r10g10b10 formats as destination on SI/CIK hardware.

This adds support to the meta program for emitting 10-bit
outputs, and adds 10-bit support to the fragment shader key.

It also only does the int8/10 on SI/CIK.

Fixes: f4e499ec7 (radv: add initial non-conformant radv vulkan driver)
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/amd/common/ac_nir_to_llvm.c
src/amd/common/ac_nir_to_llvm.h
src/amd/vulkan/radv_meta_blit.c
src/amd/vulkan/radv_meta_blit2d.c
src/amd/vulkan/radv_meta_clear.c
src/amd/vulkan/radv_meta_resolve_fs.c
src/amd/vulkan/radv_pipeline.c
src/amd/vulkan/radv_private.h

index c08f1020e354ec8fd3ae2a6b8857f82d0db93268..530b5817af39462f6adaf96f2711a6ccf86ebfaa 100644 (file)
@@ -5304,6 +5304,7 @@ si_llvm_init_export_args(struct nir_to_llvm_context *ctx,
                unsigned index = target - V_008DFC_SQ_EXP_MRT;
                unsigned col_format = (ctx->options->key.fs.col_format >> (4 * index)) & 0xf;
                bool is_int8 = (ctx->options->key.fs.is_int8 >> index) & 1;
+               bool is_int10 = (ctx->options->key.fs.is_int10 >> index) & 1;
 
                switch(col_format) {
                case V_028714_SPI_SHADER_ZERO:
@@ -5381,11 +5382,13 @@ si_llvm_init_export_args(struct nir_to_llvm_context *ctx,
                        break;
 
                case V_028714_SPI_SHADER_UINT16_ABGR: {
-                       LLVMValueRef max = LLVMConstInt(ctx->i32, is_int8 ? 255 : 65535, 0);
+                       LLVMValueRef max_rgb = LLVMConstInt(ctx->i32,
+                                                           is_int8 ? 255 : is_int10 ? 1023 : 65535, 0);
+                       LLVMValueRef max_alpha = !is_int10 ? max_rgb : LLVMConstInt(ctx->i32, 3, 0);
 
                        for (unsigned chan = 0; chan < 4; chan++) {
                                val[chan] = to_integer(&ctx->ac, values[chan]);
-                               val[chan] = emit_minmax_int(&ctx->ac, LLVMIntULT, val[chan], max);
+                               val[chan] = emit_minmax_int(&ctx->ac, LLVMIntULT, val[chan], chan == 3 ? max_alpha : max_rgb);
                        }
 
                        args->compr = 1;
@@ -5395,14 +5398,18 @@ si_llvm_init_export_args(struct nir_to_llvm_context *ctx,
                }
 
                case V_028714_SPI_SHADER_SINT16_ABGR: {
-                       LLVMValueRef max = LLVMConstInt(ctx->i32, is_int8 ? 127 : 32767, 0);
-                       LLVMValueRef min = LLVMConstInt(ctx->i32, is_int8 ? -128 : -32768, 0);
+                       LLVMValueRef max_rgb = LLVMConstInt(ctx->i32,
+                                                           is_int8 ? 127 : is_int10 ? 511 : 32767, 0);
+                       LLVMValueRef min_rgb = LLVMConstInt(ctx->i32,
+                                                           is_int8 ? -128 : is_int10 ? -512 : -32768, 0);
+                       LLVMValueRef max_alpha = !is_int10 ? max_rgb : ctx->i32one;
+                       LLVMValueRef min_alpha = !is_int10 ? min_rgb : LLVMConstInt(ctx->i32, -2, 0);
 
                        /* Clamp. */
                        for (unsigned chan = 0; chan < 4; chan++) {
                                val[chan] = to_integer(&ctx->ac, values[chan]);
-                               val[chan] = emit_minmax_int(&ctx->ac, LLVMIntSLT, val[chan], max);
-                               val[chan] = emit_minmax_int(&ctx->ac, LLVMIntSGT, val[chan], min);
+                               val[chan] = emit_minmax_int(&ctx->ac, LLVMIntSLT, val[chan], chan == 3 ? max_alpha : max_rgb);
+                               val[chan] = emit_minmax_int(&ctx->ac, LLVMIntSGT, val[chan], chan == 3 ? min_alpha : min_rgb);
                        }
 
                        args->compr = 1;
index 7def4b72f9fd0803818a7bc2fb0b56518058b2a1..376db1387a46e6935d0f5b0855bca1367aec1e07 100644 (file)
@@ -59,6 +59,7 @@ struct ac_tcs_variant_key {
 struct ac_fs_variant_key {
        uint32_t col_format;
        uint32_t is_int8;
+       uint32_t is_int10;
 };
 
 union ac_shader_variant_key {
index 718e9c50e6ec7dd68f6308be80a395f806b94860..3510e871bbef075650a490141edcf4a792b195f3 100644 (file)
@@ -695,6 +695,8 @@ static VkFormat pipeline_formats[] = {
    VK_FORMAT_R8G8B8A8_UNORM,
    VK_FORMAT_R8G8B8A8_UINT,
    VK_FORMAT_R8G8B8A8_SINT,
+   VK_FORMAT_A2R10G10B10_UINT_PACK32,
+   VK_FORMAT_A2R10G10B10_SINT_PACK32,
    VK_FORMAT_R16G16B16A16_UNORM,
    VK_FORMAT_R16G16B16A16_SNORM,
    VK_FORMAT_R16G16B16A16_UINT,
index 2f18350fd71c48ae7c4b9225dd94faa1fc674cc8..79e76be49bca39fad4afab32a2b617338bdc0c64 100644 (file)
@@ -1134,6 +1134,8 @@ static VkFormat pipeline_formats[] = {
    VK_FORMAT_R8G8B8A8_UNORM,
    VK_FORMAT_R8G8B8A8_UINT,
    VK_FORMAT_R8G8B8A8_SINT,
+   VK_FORMAT_A2R10G10B10_UINT_PACK32,
+   VK_FORMAT_A2R10G10B10_SINT_PACK32,
    VK_FORMAT_R16G16B16A16_UNORM,
    VK_FORMAT_R16G16B16A16_SNORM,
    VK_FORMAT_R16G16B16A16_UINT,
index d007f97b30e3ba516c3531ad3c1526e4075a73cd..e3d823fb58aadeaf3aad911ef0fd3b775abcdb88 100644 (file)
@@ -754,6 +754,8 @@ static VkFormat pipeline_formats[] = {
        VK_FORMAT_R8G8B8A8_UNORM,
        VK_FORMAT_R8G8B8A8_UINT,
        VK_FORMAT_R8G8B8A8_SINT,
+       VK_FORMAT_A2R10G10B10_UINT_PACK32,
+       VK_FORMAT_A2R10G10B10_SINT_PACK32,
        VK_FORMAT_R16G16B16A16_UNORM,
        VK_FORMAT_R16G16B16A16_SNORM,
        VK_FORMAT_R16G16B16A16_UINT,
index 65c5075e2a1e1c5751e9c412aaeb3b64f2a71844..a90678a2a3ea6657f1e0cb3af0cf651a520976f9 100644 (file)
@@ -160,6 +160,8 @@ static VkFormat pipeline_formats[] = {
    VK_FORMAT_R8G8B8A8_UNORM,
    VK_FORMAT_R8G8B8A8_UINT,
    VK_FORMAT_R8G8B8A8_SINT,
+   VK_FORMAT_A2R10G10B10_UINT_PACK32,
+   VK_FORMAT_A2R10G10B10_SINT_PACK32,
    VK_FORMAT_R16G16B16A16_UNORM,
    VK_FORMAT_R16G16B16A16_SNORM,
    VK_FORMAT_R16G16B16A16_UINT,
index c4407ec7e231bea97c167be8a76c8ba8549e9ef9..28389368cec1f2641aba969e1488fc4440fc8227 100644 (file)
@@ -1067,20 +1067,37 @@ format_is_int8(VkFormat format)
               desc->channel[channel].size == 8;
 }
 
+static bool
+format_is_int10(VkFormat format)
+{
+       const struct vk_format_description *desc = vk_format_description(format);
+
+       if (desc->nr_channels != 4)
+               return false;
+       for (unsigned i = 0; i < 4; i++) {
+               if (desc->channel[i].pure_integer && desc->channel[i].size == 10)
+                       return true;
+       }
+       return false;
+}
+
 unsigned radv_format_meta_fs_key(VkFormat format)
 {
        unsigned col_format = si_choose_spi_color_format(format, false, false) - 1;
        bool is_int8 = format_is_int8(format);
+       bool is_int10 = format_is_int10(format);
 
-       return col_format + (is_int8 ? 3 : 0);
+       return col_format + (is_int8 ? 3 : is_int10 ? 5 : 0);
 }
 
-static unsigned
-radv_pipeline_compute_is_int8(const VkGraphicsPipelineCreateInfo *pCreateInfo)
+static void
+radv_pipeline_compute_get_int_clamp(const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                                   unsigned *is_int8, unsigned *is_int10)
 {
        RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass);
        struct radv_subpass *subpass = pass->subpasses + pCreateInfo->subpass;
-       unsigned is_int8 = 0;
+       *is_int8 = 0;
+       *is_int10 = 0;
 
        for (unsigned i = 0; i < subpass->color_count; ++i) {
                struct radv_render_pass_attachment *attachment;
@@ -1091,10 +1108,10 @@ radv_pipeline_compute_is_int8(const VkGraphicsPipelineCreateInfo *pCreateInfo)
                attachment = pass->attachments + subpass->color_attachments[i].attachment;
 
                if (format_is_int8(attachment->format))
-                       is_int8 |= 1 << i;
+                       *is_int8 |= 1 << i;
+               if (format_is_int10(attachment->format))
+                       *is_int10 |= 1 << i;
        }
-
-       return is_int8;
 }
 
 static void
@@ -2053,9 +2070,11 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
        }
 
        if (modules[MESA_SHADER_FRAGMENT]) {
-               union ac_shader_variant_key key;
+               union ac_shader_variant_key key = {0};
                key.fs.col_format = pipeline->graphics.blend.spi_shader_col_format;
-               key.fs.is_int8 = radv_pipeline_compute_is_int8(pCreateInfo);
+
+               if (pipeline->device->physical_device->rad_info.chip_class < VI)
+                       radv_pipeline_compute_get_int_clamp(pCreateInfo, &key.fs.is_int8, &key.fs.is_int10);
 
                const VkPipelineShaderStageCreateInfo *stage = pStages[MESA_SHADER_FRAGMENT];
 
index 21a8d410f00b6dc16102e6d7ee2f518bd49cc063..25afd497da061fc57589d83afb72a705a4d3c0d8 100644 (file)
@@ -84,7 +84,7 @@ typedef uint32_t xcb_window_t;
 #define MAX_PUSH_DESCRIPTORS 32
 #define MAX_DYNAMIC_BUFFERS 16
 #define MAX_SAMPLES_LOG2 4
-#define NUM_META_FS_KEYS 11
+#define NUM_META_FS_KEYS 13
 #define RADV_MAX_DRM_DEVICES 8
 
 #define NUM_DEPTH_CLEAR_PIPELINES 3