From df61a05019d5c7479d4b29d251af4231f125e61c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 27 Jul 2017 21:52:20 +0100 Subject: [PATCH] radv: handle 10-bit format clamping workaround. 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 Signed-off-by: Dave Airlie --- src/amd/common/ac_nir_to_llvm.c | 19 +++++++++----- src/amd/common/ac_nir_to_llvm.h | 1 + src/amd/vulkan/radv_meta_blit.c | 2 ++ src/amd/vulkan/radv_meta_blit2d.c | 2 ++ src/amd/vulkan/radv_meta_clear.c | 2 ++ src/amd/vulkan/radv_meta_resolve_fs.c | 2 ++ src/amd/vulkan/radv_pipeline.c | 37 ++++++++++++++++++++------- src/amd/vulkan/radv_private.h | 2 +- 8 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index c08f1020e35..530b5817af3 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -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; diff --git a/src/amd/common/ac_nir_to_llvm.h b/src/amd/common/ac_nir_to_llvm.h index 7def4b72f9f..376db1387a4 100644 --- a/src/amd/common/ac_nir_to_llvm.h +++ b/src/amd/common/ac_nir_to_llvm.h @@ -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 { diff --git a/src/amd/vulkan/radv_meta_blit.c b/src/amd/vulkan/radv_meta_blit.c index 718e9c50e6e..3510e871bbe 100644 --- a/src/amd/vulkan/radv_meta_blit.c +++ b/src/amd/vulkan/radv_meta_blit.c @@ -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, diff --git a/src/amd/vulkan/radv_meta_blit2d.c b/src/amd/vulkan/radv_meta_blit2d.c index 2f18350fd71..79e76be49bc 100644 --- a/src/amd/vulkan/radv_meta_blit2d.c +++ b/src/amd/vulkan/radv_meta_blit2d.c @@ -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, diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c index d007f97b30e..e3d823fb58a 100644 --- a/src/amd/vulkan/radv_meta_clear.c +++ b/src/amd/vulkan/radv_meta_clear.c @@ -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, diff --git a/src/amd/vulkan/radv_meta_resolve_fs.c b/src/amd/vulkan/radv_meta_resolve_fs.c index 65c5075e2a1..a90678a2a3e 100644 --- a/src/amd/vulkan/radv_meta_resolve_fs.c +++ b/src/amd/vulkan/radv_meta_resolve_fs.c @@ -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, diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index c4407ec7e23..28389368cec 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -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]; diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 21a8d410f00..25afd497da0 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -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 -- 2.30.2