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>
tags/17.3-branchpoint
@@ -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; |
@@ -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 { |
@@ -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, |
@@ -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, |
@@ -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, |
@@ -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, |
@@ -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]; | |||
@@ -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 |