radv/ac: refactor our fmask sample index fixup.
This refactors out the sample index fixup between txf and image load. Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
5e9ead0fa2
commit
8282c5c771
|
@ -2429,50 +2429,42 @@ static void get_image_intr_name(const char *base_name,
|
|||
}
|
||||
}
|
||||
|
||||
static LLVMValueRef get_image_coords(struct nir_to_llvm_context *ctx,
|
||||
nir_intrinsic_instr *instr)
|
||||
/* Adjust the sample index according to FMASK.
|
||||
*
|
||||
* For uncompressed MSAA surfaces, FMASK should return 0x76543210,
|
||||
* which is the identity mapping. Each nibble says which physical sample
|
||||
* should be fetched to get that sample.
|
||||
*
|
||||
* For example, 0x11111100 means there are only 2 samples stored and
|
||||
* the second sample covers 3/4 of the pixel. When reading samples 0
|
||||
* and 1, return physical sample 0 (determined by the first two 0s
|
||||
* in FMASK), otherwise return physical sample 1.
|
||||
*
|
||||
* The sample index should be adjusted as follows:
|
||||
* sample_index = (fmask >> (sample_index * 4)) & 0xF;
|
||||
*/
|
||||
static LLVMValueRef adjust_sample_index_using_fmask(struct nir_to_llvm_context *ctx,
|
||||
LLVMValueRef coord_x, LLVMValueRef coord_y,
|
||||
LLVMValueRef coord_z,
|
||||
LLVMValueRef sample_index,
|
||||
LLVMValueRef fmask_desc_ptr)
|
||||
{
|
||||
const struct glsl_type *type = instr->variables[0]->var->type;
|
||||
if(instr->variables[0]->deref.child)
|
||||
type = instr->variables[0]->deref.child->type;
|
||||
|
||||
LLVMValueRef src0 = get_src(ctx, instr->src[0]);
|
||||
LLVMValueRef coords[4];
|
||||
LLVMValueRef masks[] = {
|
||||
LLVMConstInt(ctx->i32, 0, false), LLVMConstInt(ctx->i32, 1, false),
|
||||
LLVMConstInt(ctx->i32, 2, false), LLVMConstInt(ctx->i32, 3, false),
|
||||
};
|
||||
LLVMValueRef res;
|
||||
LLVMValueRef sample_index = llvm_extract_elem(ctx, get_src(ctx, instr->src[1]), 0);
|
||||
|
||||
int count;
|
||||
enum glsl_sampler_dim dim = glsl_get_sampler_dim(type);
|
||||
bool add_frag_pos = (dim == GLSL_SAMPLER_DIM_SUBPASS ||
|
||||
dim == GLSL_SAMPLER_DIM_SUBPASS_MS);
|
||||
bool is_ms = (dim == GLSL_SAMPLER_DIM_MS ||
|
||||
dim == GLSL_SAMPLER_DIM_SUBPASS_MS);
|
||||
|
||||
count = image_type_to_components_count(dim,
|
||||
glsl_sampler_type_is_array(type));
|
||||
|
||||
if (is_ms) {
|
||||
LLVMValueRef fmask_load_address[4];
|
||||
LLVMValueRef params[7];
|
||||
LLVMValueRef fmask_load_address[4], params[7];
|
||||
LLVMValueRef glc = LLVMConstInt(ctx->i1, 0, false);
|
||||
LLVMValueRef slc = LLVMConstInt(ctx->i1, 0, false);
|
||||
LLVMValueRef da = ctx->i32zero;
|
||||
LLVMValueRef da = coord_z ? ctx->i32one : ctx->i32zero;
|
||||
LLVMValueRef res;
|
||||
char intrinsic_name[64];
|
||||
int chan;
|
||||
fmask_load_address[0] = LLVMBuildExtractElement(ctx->builder, src0, masks[0], "");
|
||||
fmask_load_address[1] = LLVMBuildExtractElement(ctx->builder, src0, masks[1], "");
|
||||
fmask_load_address[2] = LLVMGetUndef(ctx->i32);
|
||||
|
||||
fmask_load_address[0] = coord_x;
|
||||
fmask_load_address[1] = coord_y;
|
||||
if (coord_z) {
|
||||
fmask_load_address[2] = coord_z;
|
||||
fmask_load_address[3] = LLVMGetUndef(ctx->i32);
|
||||
if (add_frag_pos) {
|
||||
for (chan = 0; chan < 2; ++chan)
|
||||
fmask_load_address[chan] = LLVMBuildAdd(ctx->builder, fmask_load_address[chan], LLVMBuildFPToUI(ctx->builder, ctx->frag_pos[chan], ctx->i32, ""), "");
|
||||
}
|
||||
params[0] = ac_build_gather_values(&ctx->ac, fmask_load_address, 4);
|
||||
params[1] = get_sampler_desc(ctx, instr->variables[0], DESC_FMASK);
|
||||
|
||||
params[0] = ac_build_gather_values(&ctx->ac, fmask_load_address, coord_z ? 4 : 2);
|
||||
params[1] = fmask_desc_ptr;
|
||||
params[2] = LLVMConstInt(ctx->i32, 15, false); /* dmask */
|
||||
LLVMValueRef lwe = LLVMConstInt(ctx->i1, 0, false);
|
||||
params[3] = glc;
|
||||
|
@ -2523,6 +2515,55 @@ static LLVMValueRef get_image_coords(struct nir_to_llvm_context *ctx,
|
|||
sample_index =
|
||||
LLVMBuildSelect(ctx->builder, word1_is_nonzero,
|
||||
final_sample, sample_index, "");
|
||||
return sample_index;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_image_coords(struct nir_to_llvm_context *ctx,
|
||||
nir_intrinsic_instr *instr)
|
||||
{
|
||||
const struct glsl_type *type = instr->variables[0]->var->type;
|
||||
if(instr->variables[0]->deref.child)
|
||||
type = instr->variables[0]->deref.child->type;
|
||||
|
||||
LLVMValueRef src0 = get_src(ctx, instr->src[0]);
|
||||
LLVMValueRef coords[4];
|
||||
LLVMValueRef masks[] = {
|
||||
LLVMConstInt(ctx->i32, 0, false), LLVMConstInt(ctx->i32, 1, false),
|
||||
LLVMConstInt(ctx->i32, 2, false), LLVMConstInt(ctx->i32, 3, false),
|
||||
};
|
||||
LLVMValueRef res;
|
||||
LLVMValueRef sample_index = llvm_extract_elem(ctx, get_src(ctx, instr->src[1]), 0);
|
||||
|
||||
int count;
|
||||
enum glsl_sampler_dim dim = glsl_get_sampler_dim(type);
|
||||
bool add_frag_pos = (dim == GLSL_SAMPLER_DIM_SUBPASS ||
|
||||
dim == GLSL_SAMPLER_DIM_SUBPASS_MS);
|
||||
bool is_ms = (dim == GLSL_SAMPLER_DIM_MS ||
|
||||
dim == GLSL_SAMPLER_DIM_SUBPASS_MS);
|
||||
|
||||
count = image_type_to_components_count(dim,
|
||||
glsl_sampler_type_is_array(type));
|
||||
|
||||
if (is_ms) {
|
||||
LLVMValueRef fmask_load_address[3];
|
||||
int chan;
|
||||
|
||||
fmask_load_address[0] = LLVMBuildExtractElement(ctx->builder, src0, masks[0], "");
|
||||
fmask_load_address[1] = LLVMBuildExtractElement(ctx->builder, src0, masks[1], "");
|
||||
if (glsl_sampler_type_is_array(type))
|
||||
fmask_load_address[2] = LLVMBuildExtractElement(ctx->builder, src0, masks[2], "");
|
||||
else
|
||||
fmask_load_address[2] = NULL;
|
||||
if (add_frag_pos) {
|
||||
for (chan = 0; chan < 2; ++chan)
|
||||
fmask_load_address[chan] = LLVMBuildAdd(ctx->builder, fmask_load_address[chan], LLVMBuildFPToUI(ctx->builder, ctx->frag_pos[chan], ctx->i32, ""), "");
|
||||
}
|
||||
sample_index = adjust_sample_index_using_fmask(ctx,
|
||||
fmask_load_address[0],
|
||||
fmask_load_address[1],
|
||||
fmask_load_address[2],
|
||||
sample_index,
|
||||
get_sampler_desc(ctx, instr->variables[0], DESC_FMASK));
|
||||
}
|
||||
if (count == 1) {
|
||||
if (instr->src[0].ssa->num_components)
|
||||
|
@ -3707,71 +3748,15 @@ static void visit_tex(struct nir_to_llvm_context *ctx, nir_tex_instr *instr)
|
|||
goto write_result;
|
||||
}
|
||||
|
||||
/* Adjust the sample index according to FMASK.
|
||||
*
|
||||
* For uncompressed MSAA surfaces, FMASK should return 0x76543210,
|
||||
* which is the identity mapping. Each nibble says which physical sample
|
||||
* should be fetched to get that sample.
|
||||
*
|
||||
* For example, 0x11111100 means there are only 2 samples stored and
|
||||
* the second sample covers 3/4 of the pixel. When reading samples 0
|
||||
* and 1, return physical sample 0 (determined by the first two 0s
|
||||
* in FMASK), otherwise return physical sample 1.
|
||||
*
|
||||
* The sample index should be adjusted as follows:
|
||||
* sample_index = (fmask >> (sample_index * 4)) & 0xF;
|
||||
*/
|
||||
if (instr->sampler_dim == GLSL_SAMPLER_DIM_MS &&
|
||||
instr->op != nir_texop_txs) {
|
||||
LLVMValueRef txf_address[4];
|
||||
struct ac_tex_info txf_info = { 0 };
|
||||
unsigned txf_count = count;
|
||||
memcpy(txf_address, address, sizeof(txf_address));
|
||||
|
||||
if (!instr->is_array)
|
||||
txf_address[2] = ctx->i32zero;
|
||||
txf_address[3] = ctx->i32zero;
|
||||
|
||||
set_tex_fetch_args(ctx, &txf_info, instr, nir_texop_txf,
|
||||
fmask_ptr, NULL,
|
||||
txf_address, txf_count, 0xf);
|
||||
|
||||
result = build_tex_intrinsic(ctx, instr, &txf_info);
|
||||
LLVMValueRef four = LLVMConstInt(ctx->i32, 4, false);
|
||||
LLVMValueRef F = LLVMConstInt(ctx->i32, 0xf, false);
|
||||
|
||||
LLVMValueRef fmask = LLVMBuildExtractElement(ctx->builder,
|
||||
result,
|
||||
ctx->i32zero, "");
|
||||
|
||||
unsigned sample_chan = instr->is_array ? 3 : 2;
|
||||
|
||||
LLVMValueRef sample_index4 =
|
||||
LLVMBuildMul(ctx->builder, address[sample_chan], four, "");
|
||||
LLVMValueRef shifted_fmask =
|
||||
LLVMBuildLShr(ctx->builder, fmask, sample_index4, "");
|
||||
LLVMValueRef final_sample =
|
||||
LLVMBuildAnd(ctx->builder, shifted_fmask, F, "");
|
||||
|
||||
/* Don't rewrite the sample index if WORD1.DATA_FORMAT of the FMASK
|
||||
* resource descriptor is 0 (invalid),
|
||||
*/
|
||||
LLVMValueRef fmask_desc =
|
||||
LLVMBuildBitCast(ctx->builder, fmask_ptr,
|
||||
ctx->v8i32, "");
|
||||
|
||||
LLVMValueRef fmask_word1 =
|
||||
LLVMBuildExtractElement(ctx->builder, fmask_desc,
|
||||
ctx->i32one, "");
|
||||
|
||||
LLVMValueRef word1_is_nonzero =
|
||||
LLVMBuildICmp(ctx->builder, LLVMIntNE,
|
||||
fmask_word1, ctx->i32zero, "");
|
||||
|
||||
/* Replace the MSAA sample index. */
|
||||
address[sample_chan] =
|
||||
LLVMBuildSelect(ctx->builder, word1_is_nonzero,
|
||||
final_sample, address[sample_chan], "");
|
||||
address[sample_chan] = adjust_sample_index_using_fmask(ctx,
|
||||
address[0],
|
||||
address[1],
|
||||
instr->is_array ? address[2] : NULL,
|
||||
address[sample_chan],
|
||||
fmask_ptr);
|
||||
}
|
||||
|
||||
if (offsets && instr->op == nir_texop_txf) {
|
||||
|
|
Loading…
Reference in New Issue