mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 10:40:11 +01:00
llvmpipe: Implement 64-bit image operations
LLVM has support and everything should be in place to support them. There are just a few 32-bit assumptions that have to be removed. Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33628>
This commit is contained in:
parent
d49de8f10a
commit
c05e42eaea
11 changed files with 176 additions and 70 deletions
|
|
@ -314,8 +314,7 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm,
|
|||
assert(format_desc->block.width == 1);
|
||||
assert(format_desc->block.height == 1);
|
||||
assert(format_desc->block.bits <= type.width);
|
||||
/* FIXME: Support more output types */
|
||||
assert(type.width == 32);
|
||||
assert(type.width >= 32);
|
||||
|
||||
lp_build_context_init(&bld, gallivm, type);
|
||||
|
||||
|
|
@ -427,6 +426,24 @@ lp_build_fetch_rgba_soa(struct gallivm_state *gallivm,
|
|||
enum pipe_format format = format_desc->format;
|
||||
struct lp_type fetch_type;
|
||||
|
||||
if (util_format_is_int64(format_desc)) {
|
||||
uint32_t c = 0;
|
||||
for (; c < format_desc->nr_channels; c++) {
|
||||
LLVMValueRef channel_offset =
|
||||
LLVMBuildAdd(builder, offset, lp_build_const_int_vec(gallivm, lp_type_uint_vec(32, 32 * type.length), c * 8), "");
|
||||
rgba_out[c] =
|
||||
lp_build_gather(gallivm, type.length, format_desc->channel[c].size, lp_type_uint(type.width),
|
||||
aligned, base_ptr, channel_offset, false);
|
||||
}
|
||||
for (; c < 4; c++) {
|
||||
if (c == 3)
|
||||
rgba_out[c] = lp_build_one(gallivm, type);
|
||||
else
|
||||
rgba_out[c] = lp_build_zero(gallivm, type);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
|
||||
(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
|
||||
format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB ||
|
||||
|
|
@ -992,7 +1009,6 @@ lp_build_pack_rgba_soa(struct gallivm_state *gallivm,
|
|||
assert(format_desc->block.width == 1);
|
||||
assert(format_desc->block.height == 1);
|
||||
assert(format_desc->block.bits <= type.width);
|
||||
/* FIXME: Support more output types */
|
||||
assert(type.width == 32);
|
||||
|
||||
lp_build_context_init(&bld, gallivm, type);
|
||||
|
|
@ -1024,7 +1040,11 @@ lp_build_store_rgba_soa(struct gallivm_state *gallivm,
|
|||
unsigned num_stores = 0;
|
||||
|
||||
memset(packed, 0, sizeof(LLVMValueRef) * 4);
|
||||
if (format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
|
||||
|
||||
if (util_format_is_int64(format_desc)) {
|
||||
memcpy(packed, rgba_in, sizeof(packed));
|
||||
num_stores = format_desc->nr_channels;
|
||||
} else if (format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
|
||||
format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB &&
|
||||
!util_format_is_alpha(format) &&
|
||||
format_desc->block.width == 1 &&
|
||||
|
|
@ -1096,6 +1116,7 @@ lp_build_store_rgba_soa(struct gallivm_state *gallivm,
|
|||
|
||||
assert(exec_mask);
|
||||
|
||||
LLVMTypeRef int64_ptr_type = LLVMPointerType(LLVMInt64TypeInContext(gallivm->context), 0);
|
||||
LLVMTypeRef int32_ptr_type = LLVMPointerType(LLVMInt32TypeInContext(gallivm->context), 0);
|
||||
LLVMTypeRef int16_ptr_type = LLVMPointerType(LLVMInt16TypeInContext(gallivm->context), 0);
|
||||
LLVMTypeRef int8_ptr_type = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0);
|
||||
|
|
@ -1123,8 +1144,11 @@ lp_build_store_rgba_soa(struct gallivm_state *gallivm,
|
|||
} else if (format_desc->block.bits == 16) {
|
||||
this_offset = LLVMBuildBitCast(gallivm->builder, this_offset, int16_ptr_type, "");
|
||||
data = LLVMBuildTrunc(gallivm->builder, data, LLVMInt16TypeInContext(gallivm->context), "");
|
||||
} else
|
||||
} else if (format_desc->block.bits == 32) {
|
||||
this_offset = LLVMBuildBitCast(gallivm->builder, this_offset, int32_ptr_type, "");
|
||||
} else {
|
||||
this_offset = LLVMBuildBitCast(gallivm->builder, this_offset, int64_ptr_type, "");
|
||||
}
|
||||
LLVMBuildStore(gallivm->builder, data, this_offset);
|
||||
lp_build_endif(&ifthen);
|
||||
lp_build_loop_end_cond(&loop_state, lp_build_const_int32(gallivm, type.length),
|
||||
|
|
|
|||
|
|
@ -472,7 +472,11 @@ lp_bld_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
|
|||
gallivm, params->resource, offsetof(struct lp_descriptor, functions),
|
||||
offsetof(struct lp_texture_functions, image_functions));
|
||||
|
||||
LLVMTypeRef image_function_type = lp_build_image_function_type(gallivm, params, params->ms_index);
|
||||
uint32_t flags = params->packed_op / LP_IMAGE_OP_COUNT;
|
||||
bool ms = flags & LP_IMAGE_OP_MS;
|
||||
bool is64 = flags & LP_IMAGE_OP_64;
|
||||
|
||||
LLVMTypeRef image_function_type = lp_build_image_function_type(gallivm, params, ms, is64);
|
||||
LLVMTypeRef image_function_ptr_type = LLVMPointerType(image_function_type, 0);
|
||||
LLVMTypeRef image_functions_type = LLVMPointerType(image_function_ptr_type, 0);
|
||||
LLVMTypeRef image_base_type = LLVMPointerType(image_functions_type, 0);
|
||||
|
|
@ -480,16 +484,7 @@ lp_bld_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
|
|||
image_base_ptr = LLVMBuildIntToPtr(builder, image_base_ptr, image_base_type, "");
|
||||
LLVMValueRef image_functions = LLVMBuildLoad2(builder, image_functions_type, image_base_ptr, "");
|
||||
|
||||
uint32_t op = params->img_op;
|
||||
if (op == LP_IMG_ATOMIC_CAS)
|
||||
op--;
|
||||
else if (op == LP_IMG_ATOMIC)
|
||||
op = params->op + (LP_IMG_OP_COUNT - 1);
|
||||
|
||||
if (params->ms_index)
|
||||
op += LP_TOTAL_IMAGE_OP_COUNT / 2;
|
||||
|
||||
LLVMValueRef function_index = lp_build_const_int32(gallivm, op);
|
||||
LLVMValueRef function_index = lp_build_const_int32(gallivm, params->packed_op);
|
||||
|
||||
LLVMValueRef image_function_ptr = LLVMBuildGEP2(builder, image_function_ptr_type, image_functions, &function_index, 1, "");
|
||||
LLVMValueRef image_function = LLVMBuildLoad2(builder, image_function_ptr_type, image_function_ptr, "");
|
||||
|
|
|
|||
|
|
@ -65,10 +65,4 @@ lp_bld_llvm_image_soa_destroy(struct lp_build_image_soa *image)
|
|||
FREE(image);
|
||||
}
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 15
|
||||
#define LP_TOTAL_IMAGE_OP_COUNT ((LP_IMG_OP_COUNT + LLVMAtomicRMWBinOpFMin) * 2)
|
||||
#else
|
||||
#define LP_TOTAL_IMAGE_OP_COUNT ((LP_IMG_OP_COUNT + 14) * 2)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -842,7 +842,7 @@ lp_build_size_function_type(struct gallivm_state *gallivm,
|
|||
|
||||
LLVMTypeRef
|
||||
lp_build_image_function_type(struct gallivm_state *gallivm,
|
||||
const struct lp_img_params *params, bool ms)
|
||||
const struct lp_img_params *params, bool ms, bool is64)
|
||||
{
|
||||
struct lp_type type;
|
||||
memset(&type, 0, sizeof type);
|
||||
|
|
@ -871,7 +871,11 @@ lp_build_image_function_type(struct gallivm_state *gallivm,
|
|||
if (params->img_op == LP_IMG_ATOMIC_CAS)
|
||||
num_inputs = 8;
|
||||
|
||||
const struct util_format_description *desc = util_format_description(params->format);
|
||||
enum pipe_format format = params->format;
|
||||
if (is64 && format == PIPE_FORMAT_NONE)
|
||||
format = PIPE_FORMAT_R64G64B64A64_UINT;
|
||||
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
LLVMTypeRef component_type = lp_build_vec_type(gallivm, lp_build_texel_type(type, desc));
|
||||
|
||||
for (uint32_t i = 0; i < num_inputs; i++)
|
||||
|
|
|
|||
|
|
@ -203,7 +203,8 @@ LLVMTypeRef lp_build_size_function_type(struct gallivm_state *gallivm,
|
|||
const struct lp_sampler_size_query_params *params);
|
||||
|
||||
LLVMTypeRef lp_build_image_function_type(struct gallivm_state *gallivm,
|
||||
const struct lp_img_params *params, bool ms);
|
||||
const struct lp_img_params *params, bool ms,
|
||||
bool is64);
|
||||
|
||||
struct lp_texture_functions {
|
||||
void ***sample_functions;
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ lp_build_nir_sample_key(gl_shader_stage stage, nir_tex_instr *instr);
|
|||
|
||||
void lp_img_op_from_intrinsic(struct lp_img_params *params, nir_intrinsic_instr *instr);
|
||||
|
||||
uint32_t lp_packed_img_op_from_intrinsic(nir_intrinsic_instr *instr);
|
||||
|
||||
enum lp_nir_call_context_args {
|
||||
LP_NIR_CALL_CONTEXT_CONTEXT,
|
||||
LP_NIR_CALL_CONTEXT_RESOURCES,
|
||||
|
|
|
|||
|
|
@ -4234,13 +4234,17 @@ visit_load_image(struct lp_build_nir_soa_context *bld,
|
|||
params.coords = coords;
|
||||
params.outdata = result;
|
||||
lp_img_op_from_intrinsic(¶ms, instr);
|
||||
params.packed_op = lp_packed_img_op_from_intrinsic(instr);
|
||||
if (nir_intrinsic_image_dim(instr) == GLSL_SAMPLER_DIM_MS ||
|
||||
nir_intrinsic_image_dim(instr) == GLSL_SAMPLER_DIM_SUBPASS_MS)
|
||||
params.ms_index = cast_type(bld, get_src(bld, &instr->src[2], 0),
|
||||
nir_type_uint, 32);
|
||||
|
||||
img_params_init_resource(bld, ¶ms, &instr->src[0]);
|
||||
|
||||
params.format = nir_intrinsic_format(instr);
|
||||
if (instr->def.bit_size == 64)
|
||||
params.format = PIPE_FORMAT_R64G64B64A64_UINT;
|
||||
|
||||
emit_image_op(bld, ¶ms);
|
||||
}
|
||||
|
|
@ -4265,6 +4269,8 @@ visit_store_image(struct lp_build_nir_soa_context *bld,
|
|||
params.coords = coords;
|
||||
|
||||
params.format = nir_intrinsic_format(instr);
|
||||
if (nir_src_bit_size(instr->src[3]) == 64)
|
||||
params.format = PIPE_FORMAT_R64G64B64A64_UINT;
|
||||
|
||||
const struct util_format_description *desc = util_format_description(params.format);
|
||||
bool integer = desc->channel[util_format_get_first_non_void_channel(params.format)].pure_integer;
|
||||
|
|
@ -4272,14 +4278,20 @@ visit_store_image(struct lp_build_nir_soa_context *bld,
|
|||
for (unsigned i = 0; i < 4; i++) {
|
||||
params.indata[i] = in_val[i];
|
||||
|
||||
if (integer)
|
||||
params.indata[i] = LLVMBuildBitCast(builder, params.indata[i], bld->int_bld.vec_type, "");
|
||||
else
|
||||
params.indata[i] = LLVMBuildBitCast(builder, params.indata[i], bld->base.vec_type, "");
|
||||
if (nir_src_bit_size(instr->src[3]) == 64) {
|
||||
assert(integer);
|
||||
params.indata[i] = LLVMBuildBitCast(builder, params.indata[i], bld->int64_bld.vec_type, "");
|
||||
} else {
|
||||
if (integer)
|
||||
params.indata[i] = LLVMBuildBitCast(builder, params.indata[i], bld->int_bld.vec_type, "");
|
||||
else
|
||||
params.indata[i] = LLVMBuildBitCast(builder, params.indata[i], bld->base.vec_type, "");
|
||||
}
|
||||
}
|
||||
if (nir_intrinsic_image_dim(instr) == GLSL_SAMPLER_DIM_MS)
|
||||
params.ms_index = get_src(bld, &instr->src[2], 0);
|
||||
params.img_op = LP_IMG_STORE;
|
||||
params.packed_op = lp_packed_img_op_from_intrinsic(instr);
|
||||
|
||||
img_params_init_resource(bld, ¶ms, &instr->src[0]);
|
||||
|
||||
|
|
@ -4345,6 +4357,37 @@ lp_img_op_from_intrinsic(struct lp_img_params *params, nir_intrinsic_instr *inst
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
lp_packed_img_op_from_intrinsic(nir_intrinsic_instr *instr)
|
||||
{
|
||||
struct lp_img_params params;
|
||||
lp_img_op_from_intrinsic(¶ms, instr);
|
||||
|
||||
if (params.img_op == -1)
|
||||
return -1;
|
||||
|
||||
uint32_t op = params.img_op;
|
||||
if (op == LP_IMG_ATOMIC_CAS)
|
||||
op--;
|
||||
else if (op == LP_IMG_ATOMIC)
|
||||
op = params.op + (LP_IMG_OP_COUNT - 1);
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (nir_intrinsic_image_dim(instr) == GLSL_SAMPLER_DIM_MS ||
|
||||
nir_intrinsic_image_dim(instr) == GLSL_SAMPLER_DIM_SUBPASS_MS)
|
||||
flags |= LP_IMAGE_OP_MS;
|
||||
|
||||
if (params.img_op == LP_IMG_LOAD || params.img_op == LP_IMG_LOAD_SPARSE) {
|
||||
if (instr->def.bit_size == 64)
|
||||
flags |= LP_IMAGE_OP_64;
|
||||
} else {
|
||||
if (nir_src_bit_size(instr->src[3]) == 64)
|
||||
flags |= LP_IMAGE_OP_64;
|
||||
}
|
||||
|
||||
return op + flags * LP_IMAGE_OP_COUNT;
|
||||
}
|
||||
|
||||
static void
|
||||
visit_atomic_image(struct lp_build_nir_soa_context *bld,
|
||||
nir_intrinsic_instr *instr,
|
||||
|
|
@ -4369,6 +4412,8 @@ visit_atomic_image(struct lp_build_nir_soa_context *bld,
|
|||
params.coords = coords;
|
||||
|
||||
params.format = nir_intrinsic_format(instr);
|
||||
if (nir_src_bit_size(instr->src[3]) == 64)
|
||||
params.format = PIPE_FORMAT_R64G64B64A64_UINT;
|
||||
|
||||
const struct util_format_description *desc = util_format_description(params.format);
|
||||
bool integer = desc->channel[util_format_get_first_non_void_channel(params.format)].pure_integer;
|
||||
|
|
@ -4376,28 +4421,33 @@ visit_atomic_image(struct lp_build_nir_soa_context *bld,
|
|||
if (nir_intrinsic_image_dim(instr) == GLSL_SAMPLER_DIM_MS)
|
||||
params.ms_index = get_src(bld, &instr->src[2], 0);
|
||||
|
||||
LLVMTypeRef indata_type = NULL;
|
||||
if (nir_src_bit_size(instr->src[3]) == 64) {
|
||||
assert(integer);
|
||||
indata_type = bld->int64_bld.vec_type;
|
||||
} else {
|
||||
if (integer)
|
||||
indata_type = bld->int_bld.vec_type;
|
||||
else
|
||||
indata_type = bld->base.vec_type;
|
||||
}
|
||||
|
||||
if (instr->intrinsic == nir_intrinsic_image_atomic_swap ||
|
||||
instr->intrinsic == nir_intrinsic_bindless_image_atomic_swap) {
|
||||
LLVMValueRef cas_val = get_src(bld, &instr->src[4], 0);
|
||||
params.indata[0] = in_val;
|
||||
params.indata2[0] = cas_val;
|
||||
|
||||
if (integer)
|
||||
params.indata2[0] = LLVMBuildBitCast(builder, params.indata2[0], bld->int_bld.vec_type, "");
|
||||
else
|
||||
params.indata2[0] = LLVMBuildBitCast(builder, params.indata2[0], bld->base.vec_type, "");
|
||||
params.indata2[0] = LLVMBuildBitCast(builder, params.indata2[0], indata_type, "");
|
||||
} else {
|
||||
params.indata[0] = in_val;
|
||||
}
|
||||
|
||||
if (integer)
|
||||
params.indata[0] = LLVMBuildBitCast(builder, params.indata[0], bld->int_bld.vec_type, "");
|
||||
else
|
||||
params.indata[0] = LLVMBuildBitCast(builder, params.indata[0], bld->base.vec_type, "");
|
||||
params.indata[0] = LLVMBuildBitCast(builder, params.indata[0], indata_type, "");
|
||||
|
||||
params.outdata = result;
|
||||
|
||||
lp_img_op_from_intrinsic(¶ms, instr);
|
||||
params.packed_op = lp_packed_img_op_from_intrinsic(instr);
|
||||
|
||||
img_params_init_resource(bld, ¶ms, &instr->src[0]);
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,17 @@ struct lp_sampler_size_query_params
|
|||
#define LP_IMG_ATOMIC_CAS 4
|
||||
#define LP_IMG_OP_COUNT 5
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 15
|
||||
#define LP_IMAGE_OP_COUNT (LP_IMG_OP_COUNT + LLVMAtomicRMWBinOpFMin)
|
||||
#else
|
||||
#define LP_IMAGE_OP_COUNT (LP_IMG_OP_COUNT + 14)
|
||||
#endif
|
||||
|
||||
#define LP_IMAGE_OP_MS 1
|
||||
#define LP_IMAGE_OP_64 2
|
||||
|
||||
#define LP_TOTAL_IMAGE_OP_COUNT (LP_IMAGE_OP_COUNT * 4)
|
||||
|
||||
struct lp_img_params
|
||||
{
|
||||
struct lp_type type;
|
||||
|
|
@ -163,6 +174,7 @@ struct lp_img_params
|
|||
LLVMValueRef image_index_offset;
|
||||
unsigned img_op;
|
||||
unsigned target;
|
||||
unsigned packed_op;
|
||||
LLVMAtomicRMWBinOp op;
|
||||
LLVMValueRef exec_mask;
|
||||
bool exec_mask_nz;
|
||||
|
|
|
|||
|
|
@ -3114,6 +3114,10 @@ struct lp_type
|
|||
lp_build_texel_type(struct lp_type texel_type,
|
||||
const struct util_format_description *format_desc)
|
||||
{
|
||||
if (format_desc->channel[0].size == 64 && format_desc->block.width == 1 &&
|
||||
format_desc->block.height == 1 && format_desc->block.depth == 1)
|
||||
texel_type.width = 64;
|
||||
|
||||
/* always using the first channel hopefully should be safe,
|
||||
* if not things WILL break in other places anyway.
|
||||
*/
|
||||
|
|
@ -3830,6 +3834,10 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
|
|||
if (!bld.texel_type.floating) {
|
||||
unsigned chan;
|
||||
for (chan = 0; chan < 4; chan++) {
|
||||
if (bld.texel_type.width == 64) {
|
||||
texel_out[chan] =
|
||||
LLVMBuildTrunc(builder, texel_out[chan], lp_build_int_vec_type(gallivm, type), "");
|
||||
}
|
||||
texel_out[chan] = LLVMBuildBitCast(builder, texel_out[chan],
|
||||
lp_build_vec_type(gallivm, type), "");
|
||||
}
|
||||
|
|
@ -4539,7 +4547,9 @@ lp_build_do_atomic_soa(struct gallivm_state *gallivm,
|
|||
{
|
||||
const enum pipe_format format = format_desc->format;
|
||||
|
||||
bool valid = format == PIPE_FORMAT_R32_UINT ||
|
||||
bool valid = format == PIPE_FORMAT_R64_UINT ||
|
||||
format == PIPE_FORMAT_R64_SINT ||
|
||||
format == PIPE_FORMAT_R32_UINT ||
|
||||
format == PIPE_FORMAT_R32_SINT ||
|
||||
format == PIPE_FORMAT_R32_FLOAT;
|
||||
|
||||
|
|
@ -4581,6 +4591,10 @@ lp_build_do_atomic_soa(struct gallivm_state *gallivm,
|
|||
LLVMTypeRef ref_type = (format == PIPE_FORMAT_R32_FLOAT) ?
|
||||
LLVMFloatTypeInContext(gallivm->context) :
|
||||
LLVMInt32TypeInContext(gallivm->context);
|
||||
if (format_desc->block.bits == 64) {
|
||||
assert(integer);
|
||||
ref_type = LLVMInt64TypeInContext(gallivm->context);
|
||||
}
|
||||
|
||||
LLVMTypeRef atom_res_elem_type =
|
||||
LLVMVectorType(ref_type, type.length);
|
||||
|
|
|
|||
|
|
@ -537,22 +537,28 @@ lp_storage_image_format_supported(enum pipe_format format)
|
|||
case PIPE_FORMAT_R11G11B10_FLOAT:
|
||||
case PIPE_FORMAT_R32_FLOAT:
|
||||
case PIPE_FORMAT_R16_FLOAT:
|
||||
case PIPE_FORMAT_R64G64B64A64_UINT:
|
||||
case PIPE_FORMAT_R32G32B32A32_UINT:
|
||||
case PIPE_FORMAT_R16G16B16A16_UINT:
|
||||
case PIPE_FORMAT_R10G10B10A2_UINT:
|
||||
case PIPE_FORMAT_R8G8B8A8_UINT:
|
||||
case PIPE_FORMAT_R64G64_UINT:
|
||||
case PIPE_FORMAT_R32G32_UINT:
|
||||
case PIPE_FORMAT_R16G16_UINT:
|
||||
case PIPE_FORMAT_R8G8_UINT:
|
||||
case PIPE_FORMAT_R64_UINT:
|
||||
case PIPE_FORMAT_R32_UINT:
|
||||
case PIPE_FORMAT_R16_UINT:
|
||||
case PIPE_FORMAT_R8_UINT:
|
||||
case PIPE_FORMAT_R64G64B64A64_SINT:
|
||||
case PIPE_FORMAT_R32G32B32A32_SINT:
|
||||
case PIPE_FORMAT_R16G16B16A16_SINT:
|
||||
case PIPE_FORMAT_R8G8B8A8_SINT:
|
||||
case PIPE_FORMAT_R64G64_SINT:
|
||||
case PIPE_FORMAT_R32G32_SINT:
|
||||
case PIPE_FORMAT_R16G16_SINT:
|
||||
case PIPE_FORMAT_R8G8_SINT:
|
||||
case PIPE_FORMAT_R64_SINT:
|
||||
case PIPE_FORMAT_R32_SINT:
|
||||
case PIPE_FORMAT_R16_SINT:
|
||||
case PIPE_FORMAT_R8_SINT:
|
||||
|
|
|
|||
|
|
@ -278,30 +278,48 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st
|
|||
if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && !lp_storage_render_image_format_supported(texture->format))
|
||||
return NULL;
|
||||
|
||||
bool ms = op >= LP_TOTAL_IMAGE_OP_COUNT / 2;
|
||||
if (ms)
|
||||
op -= LP_TOTAL_IMAGE_OP_COUNT / 2;
|
||||
uint32_t flags = op / LP_IMAGE_OP_COUNT;
|
||||
bool ms = flags & LP_IMAGE_OP_MS;
|
||||
bool is64 = flags & LP_IMAGE_OP_64;
|
||||
|
||||
struct lp_img_params params = { 0 };
|
||||
|
||||
params.img_op = op;
|
||||
if (op >= LP_IMG_OP_COUNT - 1) {
|
||||
params.img_op = op % LP_IMAGE_OP_COUNT;
|
||||
if (params.img_op >= LP_IMG_OP_COUNT - 1) {
|
||||
params.op = params.img_op - (LP_IMG_OP_COUNT - 1);
|
||||
params.img_op = LP_IMG_ATOMIC;
|
||||
params.op = op - (LP_IMG_OP_COUNT - 1);
|
||||
} else if (op != LP_IMG_LOAD && op != LP_IMG_LOAD_SPARSE && op != LP_IMG_STORE) {
|
||||
} else if (params.img_op != LP_IMG_LOAD && params.img_op != LP_IMG_LOAD_SPARSE && params.img_op != LP_IMG_STORE) {
|
||||
params.img_op = LP_IMG_ATOMIC_CAS;
|
||||
}
|
||||
|
||||
struct lp_static_texture_state local_texture = *texture;
|
||||
/* Rewrite rg32 stype formats as r64 for 64-bit atomics. */
|
||||
if (params.img_op == LP_IMG_ATOMIC && is64) {
|
||||
switch (local_texture.res_format) {
|
||||
case PIPE_FORMAT_R32G32_SINT:
|
||||
local_texture.format = PIPE_FORMAT_R64_SINT;
|
||||
local_texture.res_format = PIPE_FORMAT_R64_SINT;
|
||||
break;
|
||||
case PIPE_FORMAT_R32G32_UINT:
|
||||
local_texture.format = PIPE_FORMAT_R64_UINT;
|
||||
local_texture.res_format = PIPE_FORMAT_R64_UINT;
|
||||
break;
|
||||
default:
|
||||
/* Nothing to do. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loads need to support a wider range of formats for input attachments. */
|
||||
if (params.img_op != LP_IMG_LOAD)
|
||||
if (texture->format != PIPE_FORMAT_NONE && !lp_storage_image_format_supported(texture->format))
|
||||
if (local_texture.format != PIPE_FORMAT_NONE && !lp_storage_image_format_supported(local_texture.format))
|
||||
return NULL;
|
||||
|
||||
uint8_t cache_key[SHA1_DIGEST_LENGTH];
|
||||
struct mesa_sha1 hash_ctx;
|
||||
_mesa_sha1_init(&hash_ctx);
|
||||
_mesa_sha1_update(&hash_ctx, image_function_base_hash, strlen(image_function_base_hash));
|
||||
_mesa_sha1_update(&hash_ctx, texture, sizeof(*texture));
|
||||
_mesa_sha1_update(&hash_ctx, &local_texture, sizeof(local_texture));
|
||||
_mesa_sha1_update(&hash_ctx, &op, sizeof(op));
|
||||
_mesa_sha1_update(&hash_ctx, &ms, sizeof(ms));
|
||||
_mesa_sha1_final(&hash_ctx, cache_key);
|
||||
|
|
@ -313,7 +331,7 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st
|
|||
struct gallivm_state *gallivm = gallivm_create("sample_function", get_llvm_context(ctx), &cached);
|
||||
|
||||
struct lp_image_static_state state = {
|
||||
.image_state = *texture,
|
||||
.image_state = local_texture,
|
||||
};
|
||||
struct lp_build_image_soa *image_soa = lp_bld_llvm_image_soa_create(&state, 1);
|
||||
|
||||
|
|
@ -329,11 +347,11 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st
|
|||
lp_jit_init_cs_types(&cs);
|
||||
|
||||
params.type = type;
|
||||
params.target = texture->target;
|
||||
params.target = local_texture.target;
|
||||
params.resources_type = cs.jit_resources_type;
|
||||
params.format = texture->format;
|
||||
params.format = local_texture.format;
|
||||
|
||||
LLVMTypeRef function_type = lp_build_image_function_type(gallivm, ¶ms, ms);
|
||||
LLVMTypeRef function_type = lp_build_image_function_type(gallivm, ¶ms, ms, is64);
|
||||
if (!function_type) {
|
||||
free(image_soa);
|
||||
gallivm_destroy(gallivm);
|
||||
|
|
@ -373,7 +391,7 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st
|
|||
LLVMPositionBuilderAtEnd(gallivm->builder, block);
|
||||
|
||||
LLVMValueRef outdata[5] = { 0 };
|
||||
lp_build_img_op_soa(texture, lp_build_image_soa_dynamic_state(image_soa), gallivm, ¶ms, outdata);
|
||||
lp_build_img_op_soa(&local_texture, lp_build_image_soa_dynamic_state(image_soa), gallivm, ¶ms, outdata);
|
||||
|
||||
for (uint32_t i = 1; i < 4; i++)
|
||||
if (!outdata[i])
|
||||
|
|
@ -1027,23 +1045,9 @@ register_instr(nir_builder *b, nir_instr *instr, void *data)
|
|||
} else if (instr->type == nir_instr_type_intrinsic) {
|
||||
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
||||
|
||||
struct lp_img_params params;
|
||||
lp_img_op_from_intrinsic(¶ms, intrin);
|
||||
|
||||
if (params.img_op == -1)
|
||||
return false;
|
||||
|
||||
uint32_t op = params.img_op;
|
||||
if (op == LP_IMG_ATOMIC_CAS)
|
||||
op--;
|
||||
else if (op == LP_IMG_ATOMIC)
|
||||
op = params.op + (LP_IMG_OP_COUNT - 1);
|
||||
|
||||
if (nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_MS ||
|
||||
nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_SUBPASS_MS)
|
||||
op += LP_TOTAL_IMAGE_OP_COUNT / 2;
|
||||
|
||||
register_image_op(ctx, op);
|
||||
uint32_t op = lp_packed_img_op_from_intrinsic(intrin);
|
||||
if (op != -1)
|
||||
register_image_op(ctx, op);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue