[Mesa-dev] [PATCH] radeonsi: fix the Witcher 2 black transitions

Nicolai Hähnle nhaehnle at gmail.com
Mon Jan 9 08:40:51 UTC 2017


Interesting, this suggests a bug in the LLVM WQM stuff. Anyway, it makes 
sense for now.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

On 05.01.2017 13:58, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> v2: do it properly
> ---
>  src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
> index 996a458..ad7190e 100644
> --- a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
> +++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
> @@ -629,20 +629,29 @@ store_value_to_array(struct lp_build_tgsi_context *bld_base,
>  			default:
>  				continue;
>  			}
>  			value = LLVMBuildExtractElement(builder, array,
>  				lp_build_const_int32(gallivm, i), "");
>  			LLVMBuildStore(builder, value, temp_ptr);
>  		}
>  	}
>  }
>
> +/* If this is true, preload FS inputs at the beginning of shaders. Otherwise,
> + * reload them at each use. This must be 1 if the shader is using derivatives,
> + * because all inputs should be loaded in the WQM mode.
> + */
> +static bool si_preload_fs_inputs(struct si_shader_context *ctx)
> +{
> +	return ctx->shader->selector->info.uses_derivatives;
> +}
> +
>  LLVMValueRef si_llvm_emit_fetch(struct lp_build_tgsi_context *bld_base,
>  				const struct tgsi_full_src_register *reg,
>  				enum tgsi_opcode_type type,
>  				unsigned swizzle)
>  {
>  	struct si_shader_context *ctx = si_shader_context(bld_base);
>  	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
>  	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
>  	LLVMValueRef result = NULL, ptr, ptr2;
>
> @@ -681,21 +690,22 @@ LLVMValueRef si_llvm_emit_fetch(struct lp_build_tgsi_context *bld_base,
>
>  	case TGSI_FILE_INPUT: {
>  		unsigned index = reg->Register.Index;
>  		LLVMValueRef input[4];
>
>  		/* I don't think doing this for vertex shaders is beneficial.
>  		 * For those, we want to make sure the VMEM loads are executed
>  		 * only once. Fragment shaders don't care much, because
>  		 * v_interp instructions are much cheaper than VMEM loads.
>  		 */
> -		if (ctx->soa.bld_base.info->processor == PIPE_SHADER_FRAGMENT)
> +		if (!si_preload_fs_inputs(ctx) &&
> +		    ctx->soa.bld_base.info->processor == PIPE_SHADER_FRAGMENT)
>  			ctx->load_input(ctx, index, &ctx->input_decls[index], input);
>  		else
>  			memcpy(input, &ctx->inputs[index * 4], sizeof(input));
>
>  		result = input[swizzle];
>
>  		if (tgsi_type_is_64bit(type)) {
>  			ptr = result;
>  			ptr2 = input[swizzle + 1];
>  			return si_llvm_emit_fetch_64bit(bld_base, type, ptr, ptr2);
> @@ -874,21 +884,22 @@ static void emit_declaration(struct lp_build_tgsi_context *bld_base,
>  	{
>  		unsigned idx;
>  		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
>  			if (ctx->load_input &&
>  			    ctx->input_decls[idx].Declaration.File != TGSI_FILE_INPUT) {
>  				ctx->input_decls[idx] = *decl;
>  				ctx->input_decls[idx].Range.First = idx;
>  				ctx->input_decls[idx].Range.Last = idx;
>  				ctx->input_decls[idx].Semantic.Index += idx - decl->Range.First;
>
> -				if (bld_base->info->processor != PIPE_SHADER_FRAGMENT)
> +				if (si_preload_fs_inputs(ctx) ||
> +				    bld_base->info->processor != PIPE_SHADER_FRAGMENT)
>  					ctx->load_input(ctx, idx, &ctx->input_decls[idx],
>  							&ctx->inputs[idx * 4]);
>  			}
>  		}
>  	}
>  	break;
>
>  	case TGSI_FILE_SYSTEM_VALUE:
>  	{
>  		unsigned idx;
>


More information about the mesa-dev mailing list