From 766589d89a211e67f313e8cb38f2d05b09975f96 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Jan 2018 11:07:26 +1000 Subject: [PATCH] radv: fix sample_mask_in loading. (v3.1) This is ported from radeonsi and fixes: dEQP-VK.pipeline.multisample_shader_builtin.sample_mask.bit_* v2: don't call this path for radeonsi, it does it in the epilog. use the radeonsi code path. v3: handle NULL pCreateInfo->pMultisampleState properly (Samuel) v3.1: set ps_iter_samples default to 1 (Bas) Reviewed-by: Bas Nieuwenhuizen Fixes: bdcbe7c76 (radv: add sample mask input support) Signed-off-by: Dave Airlie --- src/amd/common/ac_nir_to_llvm.c | 29 ++++++++++++++++++++++++++++- src/amd/common/ac_nir_to_llvm.h | 2 ++ src/amd/vulkan/radv_pipeline.c | 29 ++++++++++++++++++++++++----- src/amd/vulkan/radv_private.h | 2 ++ 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index cc3af773863..8ae8650a7bf 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -4049,6 +4049,30 @@ static LLVMValueRef load_sample_pos(struct ac_nir_context *ctx) return ac_build_gather_values(&ctx->ac, values, 2); } +static LLVMValueRef load_sample_mask_in(struct ac_nir_context *ctx) +{ + uint8_t log2_ps_iter_samples = ctx->nctx->shader_info->info.ps.force_persample ? ctx->nctx->options->key.fs.log2_num_samples : ctx->nctx->options->key.fs.log2_ps_iter_samples; + + /* The bit pattern matches that used by fixed function fragment + * processing. */ + static const uint16_t ps_iter_masks[] = { + 0xffff, /* not used */ + 0x5555, + 0x1111, + 0x0101, + 0x0001, + }; + assert(log2_ps_iter_samples < ARRAY_SIZE(ps_iter_masks)); + + uint32_t ps_iter_mask = ps_iter_masks[log2_ps_iter_samples]; + + LLVMValueRef result, sample_id; + sample_id = unpack_param(&ctx->ac, ctx->abi->ancillary, 8, 4); + sample_id = LLVMBuildShl(ctx->ac.builder, LLVMConstInt(ctx->ac.i32, ps_iter_mask, false), sample_id, ""); + result = LLVMBuildAnd(ctx->ac.builder, sample_id, ctx->abi->sample_coverage, ""); + return result; +} + static LLVMValueRef visit_interp(struct nir_to_llvm_context *ctx, const nir_intrinsic_instr *instr) { @@ -4353,7 +4377,10 @@ static void visit_intrinsic(struct ac_nir_context *ctx, result = load_sample_pos(ctx); break; case nir_intrinsic_load_sample_mask_in: - result = ctx->abi->sample_coverage; + if (ctx->nctx) + result = load_sample_mask_in(ctx); + else + result = ctx->abi->sample_coverage; break; case nir_intrinsic_load_frag_coord: { LLVMValueRef values[4] = { diff --git a/src/amd/common/ac_nir_to_llvm.h b/src/amd/common/ac_nir_to_llvm.h index 62ea38be373..1656289e06e 100644 --- a/src/amd/common/ac_nir_to_llvm.h +++ b/src/amd/common/ac_nir_to_llvm.h @@ -60,6 +60,8 @@ struct ac_tcs_variant_key { struct ac_fs_variant_key { uint32_t col_format; + uint8_t log2_ps_iter_samples; + uint8_t log2_num_samples; uint32_t is_int8; uint32_t is_int10; uint32_t multisample : 1; diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index a49fe059934..21333b808ab 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -798,6 +798,18 @@ radv_pipeline_init_raster_state(struct radv_pipeline *pipeline, } +static uint8_t radv_pipeline_get_ps_iter_samples(const VkPipelineMultisampleStateCreateInfo *vkms) +{ + uint32_t num_samples = vkms->rasterizationSamples; + uint32_t ps_iter_samples = 1; + + if (vkms->sampleShadingEnable) { + ps_iter_samples = ceil(vkms->minSampleShading * num_samples); + ps_iter_samples = util_next_power_of_two(ps_iter_samples); + } + return ps_iter_samples; +} + static void radv_pipeline_init_multisample_state(struct radv_pipeline *pipeline, const VkGraphicsPipelineCreateInfo *pCreateInfo) @@ -813,9 +825,9 @@ radv_pipeline_init_multisample_state(struct radv_pipeline *pipeline, else ms->num_samples = 1; - if (vkms && vkms->sampleShadingEnable) { - ps_iter_samples = ceil(vkms->minSampleShading * ms->num_samples); - } else if (pipeline->shaders[MESA_SHADER_FRAGMENT]->info.info.ps.force_persample) { + if (vkms) + ps_iter_samples = radv_pipeline_get_ps_iter_samples(vkms); + if (vkms && !vkms->sampleShadingEnable && pipeline->shaders[MESA_SHADER_FRAGMENT]->info.info.ps.force_persample) { ps_iter_samples = ms->num_samples; } @@ -838,7 +850,7 @@ radv_pipeline_init_multisample_state(struct radv_pipeline *pipeline, if (ms->num_samples > 1) { unsigned log_samples = util_logbase2(ms->num_samples); - unsigned log_ps_iter_samples = util_logbase2(util_next_power_of_two(ps_iter_samples)); + unsigned log_ps_iter_samples = util_logbase2(ps_iter_samples); ms->pa_sc_mode_cntl_0 |= S_028A48_MSAA_ENABLE(1); ms->pa_sc_line_cntl |= S_028BDC_EXPAND_LINE_WIDTH(1); /* CM_R_028BDC_PA_SC_LINE_CNTL */ ms->db_eqaa |= S_028804_MAX_ANCHOR_SAMPLES(log_samples) | @@ -1745,8 +1757,13 @@ radv_generate_graphics_pipeline_key(struct radv_pipeline *pipeline, if (pCreateInfo->pMultisampleState && - pCreateInfo->pMultisampleState->rasterizationSamples > 1) + pCreateInfo->pMultisampleState->rasterizationSamples > 1) { + uint32_t num_samples = pCreateInfo->pMultisampleState->rasterizationSamples; + uint32_t ps_iter_samples = radv_pipeline_get_ps_iter_samples(pCreateInfo->pMultisampleState); key.multisample = true; + key.log2_num_samples = util_logbase2(num_samples); + key.log2_ps_iter_samples = util_logbase2(ps_iter_samples); + } key.col_format = pipeline->graphics.blend.spi_shader_col_format; if (pipeline->device->physical_device->rad_info.chip_class < VI) @@ -1784,6 +1801,8 @@ radv_fill_shader_keys(struct ac_shader_variant_key *keys, keys[MESA_SHADER_FRAGMENT].fs.col_format = key->col_format; keys[MESA_SHADER_FRAGMENT].fs.is_int8 = key->is_int8; keys[MESA_SHADER_FRAGMENT].fs.is_int10 = key->is_int10; + keys[MESA_SHADER_FRAGMENT].fs.log2_ps_iter_samples = key->log2_ps_iter_samples; + keys[MESA_SHADER_FRAGMENT].fs.log2_num_samples = key->log2_num_samples; } static void diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 808db0007dc..711ae719266 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -331,6 +331,8 @@ struct radv_pipeline_key { uint32_t col_format; uint32_t is_int8; uint32_t is_int10; + uint8_t log2_ps_iter_samples; + uint8_t log2_num_samples; uint32_t multisample : 1; uint32_t has_multiview_view_index : 1; }; -- 2.30.2