lavapipe: Implement shaderResourceResidency
Adds a bit set to llvmpipe_resurce where each bit stores the residency of a 64KB tile. The sampling code is adjusted to make use of said table and return a residency code for sparse texture operations. Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29408>
This commit is contained in:

committed by
Marge Bot

parent
d747c4a874
commit
6168317b84
@@ -154,8 +154,8 @@ lp_bld_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base
|
|||||||
if (params->texture_resource) {
|
if (params->texture_resource) {
|
||||||
LLVMTypeRef out_data_type = lp_build_vec_type(gallivm, params->type);
|
LLVMTypeRef out_data_type = lp_build_vec_type(gallivm, params->type);
|
||||||
|
|
||||||
LLVMValueRef out_data[4];
|
LLVMValueRef out_data[5];
|
||||||
for (uint32_t i = 0; i < 4; i++) {
|
for (uint32_t i = 0; i < ARRAY_SIZE(out_data); i++) {
|
||||||
out_data[i] = lp_build_alloca(gallivm, out_data_type, "");
|
out_data[i] = lp_build_alloca(gallivm, out_data_type, "");
|
||||||
LLVMBuildStore(builder, lp_build_const_vec(gallivm, params->type, 0), out_data[i]);
|
LLVMBuildStore(builder, lp_build_const_vec(gallivm, params->type, 0), out_data[i]);
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ lp_bld_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base
|
|||||||
|
|
||||||
LLVMValueRef result = LLVMBuildCall2(builder, texture_function_type, texture_function, args, num_args, "");
|
LLVMValueRef result = LLVMBuildCall2(builder, texture_function_type, texture_function, args, num_args, "");
|
||||||
|
|
||||||
for (unsigned i = 0; i < 4; i++) {
|
for (unsigned i = 0; i < ARRAY_SIZE(out_data); i++) {
|
||||||
params->texel[i] = LLVMBuildExtractValue(gallivm->builder, result, i, "");
|
params->texel[i] = LLVMBuildExtractValue(gallivm->builder, result, i, "");
|
||||||
|
|
||||||
if (params->type.length != lp_native_vector_width / 32)
|
if (params->type.length != lp_native_vector_width / 32)
|
||||||
@@ -275,7 +275,7 @@ lp_bld_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base
|
|||||||
|
|
||||||
lp_build_endif(&if_state);
|
lp_build_endif(&if_state);
|
||||||
|
|
||||||
for (unsigned i = 0; i < 4; i++)
|
for (unsigned i = 0; i < ARRAY_SIZE(out_data); i++)
|
||||||
params->texel[i] = LLVMBuildLoad2(gallivm->builder, out_data_type, out_data[i], "");
|
params->texel[i] = LLVMBuildLoad2(gallivm->builder, out_data_type, out_data[i], "");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -443,8 +443,8 @@ lp_bld_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
|
|||||||
const struct util_format_description *desc = util_format_description(params->format);
|
const struct util_format_description *desc = util_format_description(params->format);
|
||||||
LLVMTypeRef out_data_type = lp_build_vec_type(gallivm, lp_build_texel_type(params->type, desc));
|
LLVMTypeRef out_data_type = lp_build_vec_type(gallivm, lp_build_texel_type(params->type, desc));
|
||||||
|
|
||||||
LLVMValueRef out_data[4];
|
LLVMValueRef out_data[5];
|
||||||
for (uint32_t i = 0; i < 4; i++) {
|
for (uint32_t i = 0; i < ARRAY_SIZE(out_data); i++) {
|
||||||
out_data[i] = lp_build_alloca(gallivm, out_data_type, "");
|
out_data[i] = lp_build_alloca(gallivm, out_data_type, "");
|
||||||
LLVMBuildStore(builder, lp_build_const_vec(gallivm, lp_build_texel_type(params->type, desc), 0), out_data[i]);
|
LLVMBuildStore(builder, lp_build_const_vec(gallivm, lp_build_texel_type(params->type, desc), 0), out_data[i]);
|
||||||
}
|
}
|
||||||
@@ -500,7 +500,7 @@ lp_bld_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
|
|||||||
|
|
||||||
args[num_args++] = image_descriptor;
|
args[num_args++] = image_descriptor;
|
||||||
|
|
||||||
if (params->img_op != LP_IMG_LOAD)
|
if (params->img_op != LP_IMG_LOAD && params->img_op != LP_IMG_LOAD_SPARSE)
|
||||||
args[num_args++] = params->exec_mask;
|
args[num_args++] = params->exec_mask;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 3; i++)
|
for (uint32_t i = 0; i < 3; i++)
|
||||||
@@ -509,7 +509,7 @@ lp_bld_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
|
|||||||
if (params->ms_index)
|
if (params->ms_index)
|
||||||
args[num_args++] = params->ms_index;
|
args[num_args++] = params->ms_index;
|
||||||
|
|
||||||
if (params->img_op != LP_IMG_LOAD)
|
if (params->img_op != LP_IMG_LOAD && params->img_op != LP_IMG_LOAD_SPARSE)
|
||||||
for (uint32_t i = 0; i < 4; i++)
|
for (uint32_t i = 0; i < 4; i++)
|
||||||
args[num_args++] = params->indata[i];
|
args[num_args++] = params->indata[i];
|
||||||
|
|
||||||
@@ -532,7 +532,8 @@ lp_bld_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
|
|||||||
LLVMValueRef result = LLVMBuildCall2(builder, image_function_type, image_function, args, num_args, "");
|
LLVMValueRef result = LLVMBuildCall2(builder, image_function_type, image_function, args, num_args, "");
|
||||||
|
|
||||||
if (params->img_op != LP_IMG_STORE) {
|
if (params->img_op != LP_IMG_STORE) {
|
||||||
for (unsigned i = 0; i < 4; i++) {
|
uint32_t channel_count = params->img_op == LP_IMG_LOAD_SPARSE ? 5 : 4;
|
||||||
|
for (unsigned i = 0; i < channel_count; i++) {
|
||||||
LLVMValueRef channel = LLVMBuildExtractValue(gallivm->builder, result, i, "");
|
LLVMValueRef channel = LLVMBuildExtractValue(gallivm->builder, result, i, "");
|
||||||
if (params->type.length != lp_native_vector_width / 32)
|
if (params->type.length != lp_native_vector_width / 32)
|
||||||
channel = truncate_to_type_width(gallivm, channel, params->type);
|
channel = truncate_to_type_width(gallivm, channel, params->type);
|
||||||
@@ -544,7 +545,7 @@ lp_bld_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
|
|||||||
lp_build_endif(&if_state);
|
lp_build_endif(&if_state);
|
||||||
|
|
||||||
if (params->img_op != LP_IMG_STORE) {
|
if (params->img_op != LP_IMG_STORE) {
|
||||||
for (unsigned i = 0; i < 4; i++) {
|
for (unsigned i = 0; i < ARRAY_SIZE(out_data); i++) {
|
||||||
params->outdata[i] = LLVMBuildLoad2(gallivm->builder, out_data_type, out_data[i], "");
|
params->outdata[i] = LLVMBuildLoad2(gallivm->builder, out_data_type, out_data[i], "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -239,10 +239,12 @@ lp_build_create_jit_image_type(struct gallivm_state *gallivm)
|
|||||||
elem_types[LP_JIT_IMAGE_HEIGHT] =
|
elem_types[LP_JIT_IMAGE_HEIGHT] =
|
||||||
elem_types[LP_JIT_IMAGE_DEPTH] = LLVMInt16TypeInContext(lc);
|
elem_types[LP_JIT_IMAGE_DEPTH] = LLVMInt16TypeInContext(lc);
|
||||||
elem_types[LP_JIT_IMAGE_NUM_SAMPLES] = LLVMInt8TypeInContext(lc);
|
elem_types[LP_JIT_IMAGE_NUM_SAMPLES] = LLVMInt8TypeInContext(lc);
|
||||||
elem_types[LP_JIT_IMAGE_BASE] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
|
elem_types[LP_JIT_IMAGE_BASE] =
|
||||||
|
elem_types[LP_JIT_IMAGE_RESIDENCY] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
|
||||||
elem_types[LP_JIT_IMAGE_ROW_STRIDE] =
|
elem_types[LP_JIT_IMAGE_ROW_STRIDE] =
|
||||||
elem_types[LP_JIT_IMAGE_IMG_STRIDE] =
|
elem_types[LP_JIT_IMAGE_IMG_STRIDE] =
|
||||||
elem_types[LP_JIT_IMAGE_SAMPLE_STRIDE] = LLVMInt32TypeInContext(lc);
|
elem_types[LP_JIT_IMAGE_SAMPLE_STRIDE] =
|
||||||
|
elem_types[LP_JIT_IMAGE_BASE_OFFSET] = LLVMInt32TypeInContext(lc);
|
||||||
|
|
||||||
image_type = LLVMStructTypeInContext(lc, elem_types,
|
image_type = LLVMStructTypeInContext(lc, elem_types,
|
||||||
ARRAY_SIZE(elem_types), 0);
|
ARRAY_SIZE(elem_types), 0);
|
||||||
@@ -407,6 +409,38 @@ lp_build_llvm_texture_member(struct gallivm_state *gallivm,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LLVMValueRef
|
||||||
|
lp_build_llvm_texture_residency(struct gallivm_state *gallivm,
|
||||||
|
LLVMTypeRef resources_type,
|
||||||
|
LLVMValueRef resources_ptr,
|
||||||
|
unsigned texture_unit,
|
||||||
|
LLVMValueRef texture_unit_offset)
|
||||||
|
{
|
||||||
|
LLVMBuilderRef builder = gallivm->builder;
|
||||||
|
|
||||||
|
static_assert(offsetof(struct lp_descriptor, texture) == 0, "Invalid texture offset");
|
||||||
|
LLVMValueRef texture_ptr = gallivm->texture_descriptor;
|
||||||
|
|
||||||
|
LLVMTypeRef texture_ptr_type = LLVMStructGetTypeAtIndex(resources_type, LP_JIT_RES_TEXTURES);
|
||||||
|
LLVMTypeRef texture_type = LLVMGetElementType(texture_ptr_type);
|
||||||
|
texture_ptr_type = LLVMPointerType(texture_type, 0);
|
||||||
|
|
||||||
|
texture_ptr = LLVMBuildIntToPtr(builder, texture_ptr, texture_ptr_type, "");
|
||||||
|
|
||||||
|
static_assert(offsetof(struct lp_jit_texture, row_stride) == offsetof(struct lp_jit_texture, residency),
|
||||||
|
"Invalid texture descriptor layout");
|
||||||
|
LLVMValueRef indices[2] = {
|
||||||
|
lp_build_const_int32(gallivm, 0),
|
||||||
|
lp_build_const_int32(gallivm, LP_JIT_TEXTURE_ROW_STRIDE),
|
||||||
|
};
|
||||||
|
LLVMValueRef ptr = LLVMBuildGEP2(builder, texture_type, texture_ptr, indices, ARRAY_SIZE(indices), "");
|
||||||
|
|
||||||
|
LLVMTypeRef residency_type = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0);
|
||||||
|
ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(residency_type, 0), "");
|
||||||
|
|
||||||
|
return LLVMBuildLoad2(builder, residency_type, ptr, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper macro to instantiate the functions that generate the code to
|
* Helper macro to instantiate the functions that generate the code to
|
||||||
@@ -652,6 +686,8 @@ LP_BUILD_LLVM_IMAGE_MEMBER_OUTTYPE(row_stride, LP_JIT_IMAGE_ROW_STRIDE, true)
|
|||||||
LP_BUILD_LLVM_IMAGE_MEMBER_OUTTYPE(img_stride, LP_JIT_IMAGE_IMG_STRIDE, true)
|
LP_BUILD_LLVM_IMAGE_MEMBER_OUTTYPE(img_stride, LP_JIT_IMAGE_IMG_STRIDE, true)
|
||||||
LP_BUILD_LLVM_IMAGE_MEMBER(num_samples, LP_JIT_IMAGE_NUM_SAMPLES, true)
|
LP_BUILD_LLVM_IMAGE_MEMBER(num_samples, LP_JIT_IMAGE_NUM_SAMPLES, true)
|
||||||
LP_BUILD_LLVM_IMAGE_MEMBER(sample_stride, LP_JIT_IMAGE_SAMPLE_STRIDE, true)
|
LP_BUILD_LLVM_IMAGE_MEMBER(sample_stride, LP_JIT_IMAGE_SAMPLE_STRIDE, true)
|
||||||
|
LP_BUILD_LLVM_IMAGE_MEMBER(residency, LP_JIT_IMAGE_RESIDENCY, true)
|
||||||
|
LP_BUILD_LLVM_IMAGE_MEMBER(base_offset, LP_JIT_IMAGE_BASE_OFFSET, true)
|
||||||
|
|
||||||
void
|
void
|
||||||
lp_build_jit_fill_sampler_dynamic_state(struct lp_sampler_dynamic_state *state)
|
lp_build_jit_fill_sampler_dynamic_state(struct lp_sampler_dynamic_state *state)
|
||||||
@@ -665,6 +701,7 @@ lp_build_jit_fill_sampler_dynamic_state(struct lp_sampler_dynamic_state *state)
|
|||||||
state->row_stride = lp_build_llvm_texture_row_stride;
|
state->row_stride = lp_build_llvm_texture_row_stride;
|
||||||
state->img_stride = lp_build_llvm_texture_img_stride;
|
state->img_stride = lp_build_llvm_texture_img_stride;
|
||||||
state->mip_offsets = lp_build_llvm_texture_mip_offsets;
|
state->mip_offsets = lp_build_llvm_texture_mip_offsets;
|
||||||
|
state->residency = lp_build_llvm_texture_residency;
|
||||||
|
|
||||||
state->min_lod = lp_build_llvm_sampler_min_lod;
|
state->min_lod = lp_build_llvm_sampler_min_lod;
|
||||||
state->max_lod = lp_build_llvm_sampler_max_lod;
|
state->max_lod = lp_build_llvm_sampler_max_lod;
|
||||||
@@ -685,6 +722,8 @@ lp_build_jit_fill_image_dynamic_state(struct lp_sampler_dynamic_state *state)
|
|||||||
state->img_stride = lp_build_llvm_image_img_stride;
|
state->img_stride = lp_build_llvm_image_img_stride;
|
||||||
state->last_level = lp_build_llvm_image_num_samples;
|
state->last_level = lp_build_llvm_image_num_samples;
|
||||||
state->sample_stride = lp_build_llvm_image_sample_stride;
|
state->sample_stride = lp_build_llvm_image_sample_stride;
|
||||||
|
state->residency = lp_build_llvm_image_residency;
|
||||||
|
state->base_offset = lp_build_llvm_image_base_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -751,7 +790,7 @@ lp_build_sample_function_type(struct gallivm_state *gallivm, uint32_t sample_key
|
|||||||
|
|
||||||
LLVMTypeRef arg_types[LP_MAX_TEX_FUNC_ARGS];
|
LLVMTypeRef arg_types[LP_MAX_TEX_FUNC_ARGS];
|
||||||
LLVMTypeRef ret_type;
|
LLVMTypeRef ret_type;
|
||||||
LLVMTypeRef val_type[4];
|
LLVMTypeRef val_type[5];
|
||||||
uint32_t num_params = 0;
|
uint32_t num_params = 0;
|
||||||
|
|
||||||
LLVMTypeRef coord_type;
|
LLVMTypeRef coord_type;
|
||||||
@@ -782,7 +821,8 @@ lp_build_sample_function_type(struct gallivm_state *gallivm, uint32_t sample_key
|
|||||||
arg_types[num_params++] = coord_type;
|
arg_types[num_params++] = coord_type;
|
||||||
|
|
||||||
val_type[0] = val_type[1] = val_type[2] = val_type[3] = lp_build_vec_type(gallivm, type);
|
val_type[0] = val_type[1] = val_type[2] = val_type[3] = lp_build_vec_type(gallivm, type);
|
||||||
ret_type = LLVMStructTypeInContext(gallivm->context, val_type, 4, 0);
|
val_type[4] = lp_build_int_vec_type(gallivm, type);
|
||||||
|
ret_type = LLVMStructTypeInContext(gallivm->context, val_type, 5, 0);
|
||||||
return LLVMFunctionType(ret_type, arg_types, num_params, false);
|
return LLVMFunctionType(ret_type, arg_types, num_params, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -831,7 +871,7 @@ lp_build_image_function_type(struct gallivm_state *gallivm,
|
|||||||
|
|
||||||
arg_types[num_params++] = LLVMInt64TypeInContext(gallivm->context);
|
arg_types[num_params++] = LLVMInt64TypeInContext(gallivm->context);
|
||||||
|
|
||||||
if (params->img_op != LP_IMG_LOAD)
|
if (params->img_op != LP_IMG_LOAD && params->img_op != LP_IMG_LOAD_SPARSE)
|
||||||
arg_types[num_params++] = lp_build_int_vec_type(gallivm, type);
|
arg_types[num_params++] = lp_build_int_vec_type(gallivm, type);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 3; i++)
|
for (uint32_t i = 0; i < 3; i++)
|
||||||
@@ -840,7 +880,7 @@ lp_build_image_function_type(struct gallivm_state *gallivm,
|
|||||||
if (ms)
|
if (ms)
|
||||||
arg_types[num_params++] = lp_build_vec_type(gallivm, lp_uint_type(type));
|
arg_types[num_params++] = lp_build_vec_type(gallivm, lp_uint_type(type));
|
||||||
|
|
||||||
uint32_t num_inputs = params->img_op != LP_IMG_LOAD ? 4 : 0;
|
uint32_t num_inputs = params->img_op != LP_IMG_LOAD && params->img_op != LP_IMG_LOAD_SPARSE ? 4 : 0;
|
||||||
if (params->img_op == LP_IMG_ATOMIC_CAS)
|
if (params->img_op == LP_IMG_ATOMIC_CAS)
|
||||||
num_inputs = 8;
|
num_inputs = 8;
|
||||||
|
|
||||||
@@ -849,8 +889,13 @@ lp_build_image_function_type(struct gallivm_state *gallivm,
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < num_inputs; i++)
|
for (uint32_t i = 0; i < num_inputs; i++)
|
||||||
arg_types[num_params++] = component_type;
|
arg_types[num_params++] = component_type;
|
||||||
|
|
||||||
if (params->img_op != LP_IMG_STORE) {
|
if (params->img_op == LP_IMG_LOAD_SPARSE) {
|
||||||
|
LLVMTypeRef val_type[5];
|
||||||
|
val_type[0] = val_type[1] = val_type[2] = val_type[3] = component_type;
|
||||||
|
val_type[4] = lp_build_int_vec_type(gallivm, type);
|
||||||
|
ret_type = LLVMStructTypeInContext(gallivm->context, val_type, 5, 0);
|
||||||
|
} else if (params->img_op != LP_IMG_STORE) {
|
||||||
LLVMTypeRef val_type[4];
|
LLVMTypeRef val_type[4];
|
||||||
val_type[0] = val_type[1] = val_type[2] = val_type[3] = component_type;
|
val_type[0] = val_type[1] = val_type[2] = val_type[3] = component_type;
|
||||||
ret_type = LLVMStructTypeInContext(gallivm->context, val_type, 4, 0);
|
ret_type = LLVMStructTypeInContext(gallivm->context, val_type, 4, 0);
|
||||||
|
@@ -68,10 +68,15 @@ struct lp_jit_texture
|
|||||||
uint32_t width; /* same as number of elements */
|
uint32_t width; /* same as number of elements */
|
||||||
uint16_t height;
|
uint16_t height;
|
||||||
uint16_t depth; /* doubles as array size */
|
uint16_t depth; /* doubles as array size */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
|
||||||
|
uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
|
||||||
|
};
|
||||||
|
const void *residency;
|
||||||
|
};
|
||||||
uint8_t first_level;
|
uint8_t first_level;
|
||||||
uint8_t last_level; /* contains num_samples for multisample */
|
uint8_t last_level; /* contains num_samples for multisample */
|
||||||
uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
|
|
||||||
uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
|
|
||||||
uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]; /* sample stride is in mip_offsets[15] */
|
uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]; /* sample stride is in mip_offsets[15] */
|
||||||
uint32_t sampler_index;
|
uint32_t sampler_index;
|
||||||
};
|
};
|
||||||
@@ -81,10 +86,10 @@ enum {
|
|||||||
LP_JIT_TEXTURE_WIDTH,
|
LP_JIT_TEXTURE_WIDTH,
|
||||||
LP_JIT_TEXTURE_HEIGHT,
|
LP_JIT_TEXTURE_HEIGHT,
|
||||||
LP_JIT_TEXTURE_DEPTH,
|
LP_JIT_TEXTURE_DEPTH,
|
||||||
LP_JIT_TEXTURE_FIRST_LEVEL,
|
|
||||||
LP_JIT_TEXTURE_LAST_LEVEL,
|
|
||||||
LP_JIT_TEXTURE_ROW_STRIDE,
|
LP_JIT_TEXTURE_ROW_STRIDE,
|
||||||
LP_JIT_TEXTURE_IMG_STRIDE,
|
LP_JIT_TEXTURE_IMG_STRIDE,
|
||||||
|
LP_JIT_TEXTURE_FIRST_LEVEL,
|
||||||
|
LP_JIT_TEXTURE_LAST_LEVEL,
|
||||||
LP_JIT_TEXTURE_MIP_OFFSETS,
|
LP_JIT_TEXTURE_MIP_OFFSETS,
|
||||||
LP_JIT_SAMPLER_INDEX_DUMMY,
|
LP_JIT_SAMPLER_INDEX_DUMMY,
|
||||||
LP_JIT_TEXTURE_NUM_FIELDS /* number of fields above */
|
LP_JIT_TEXTURE_NUM_FIELDS /* number of fields above */
|
||||||
@@ -118,6 +123,8 @@ struct lp_jit_image
|
|||||||
uint32_t sample_stride;
|
uint32_t sample_stride;
|
||||||
uint32_t row_stride;
|
uint32_t row_stride;
|
||||||
uint32_t img_stride;
|
uint32_t img_stride;
|
||||||
|
const void *residency;
|
||||||
|
uint32_t base_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -129,6 +136,8 @@ enum {
|
|||||||
LP_JIT_IMAGE_SAMPLE_STRIDE,
|
LP_JIT_IMAGE_SAMPLE_STRIDE,
|
||||||
LP_JIT_IMAGE_ROW_STRIDE,
|
LP_JIT_IMAGE_ROW_STRIDE,
|
||||||
LP_JIT_IMAGE_IMG_STRIDE,
|
LP_JIT_IMAGE_IMG_STRIDE,
|
||||||
|
LP_JIT_IMAGE_RESIDENCY,
|
||||||
|
LP_JIT_IMAGE_BASE_OFFSET,
|
||||||
LP_JIT_IMAGE_NUM_FIELDS /* number of fields above */
|
LP_JIT_IMAGE_NUM_FIELDS /* number of fields above */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1624,7 +1624,7 @@ visit_load_image(struct lp_build_nir_context *bld_base,
|
|||||||
|
|
||||||
params.coords = coords;
|
params.coords = coords;
|
||||||
params.outdata = result;
|
params.outdata = result;
|
||||||
params.img_op = LP_IMG_LOAD;
|
lp_img_op_from_intrinsic(¶ms, instr);
|
||||||
if (nir_intrinsic_image_dim(instr) == GLSL_SAMPLER_DIM_MS ||
|
if (nir_intrinsic_image_dim(instr) == GLSL_SAMPLER_DIM_MS ||
|
||||||
nir_intrinsic_image_dim(instr) == GLSL_SAMPLER_DIM_SUBPASS_MS)
|
nir_intrinsic_image_dim(instr) == GLSL_SAMPLER_DIM_SUBPASS_MS)
|
||||||
params.ms_index = cast_type(bld_base, get_src(bld_base, instr->src[2]),
|
params.ms_index = cast_type(bld_base, get_src(bld_base, instr->src[2]),
|
||||||
@@ -1710,6 +1710,11 @@ lp_img_op_from_intrinsic(struct lp_img_params *params, nir_intrinsic_instr *inst
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instr->intrinsic == nir_intrinsic_bindless_image_sparse_load) {
|
||||||
|
params->img_op = LP_IMG_LOAD_SPARSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (instr->intrinsic == nir_intrinsic_image_store ||
|
if (instr->intrinsic == nir_intrinsic_image_store ||
|
||||||
instr->intrinsic == nir_intrinsic_bindless_image_store) {
|
instr->intrinsic == nir_intrinsic_bindless_image_store) {
|
||||||
params->img_op = LP_IMG_STORE;
|
params->img_op = LP_IMG_STORE;
|
||||||
@@ -2191,6 +2196,7 @@ visit_intrinsic(struct lp_build_nir_context *bld_base,
|
|||||||
break;
|
break;
|
||||||
case nir_intrinsic_image_load:
|
case nir_intrinsic_image_load:
|
||||||
case nir_intrinsic_bindless_image_load:
|
case nir_intrinsic_bindless_image_load:
|
||||||
|
case nir_intrinsic_bindless_image_sparse_load:
|
||||||
visit_load_image(bld_base, instr, result);
|
visit_load_image(bld_base, instr, result);
|
||||||
break;
|
break;
|
||||||
case nir_intrinsic_image_store:
|
case nir_intrinsic_image_store:
|
||||||
@@ -2450,6 +2456,9 @@ lp_build_nir_sample_key(gl_shader_stage stage, nir_tex_instr *instr)
|
|||||||
|
|
||||||
sample_key |= lod_property << LP_SAMPLER_LOD_PROPERTY_SHIFT;
|
sample_key |= lod_property << LP_SAMPLER_LOD_PROPERTY_SHIFT;
|
||||||
|
|
||||||
|
if (instr->is_sparse)
|
||||||
|
sample_key |= LP_SAMPLER_RESIDENCY;
|
||||||
|
|
||||||
return sample_key;
|
return sample_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -98,6 +98,8 @@ enum lp_sampler_op_type {
|
|||||||
#define LP_SAMPLER_GATHER_COMP_SHIFT 8
|
#define LP_SAMPLER_GATHER_COMP_SHIFT 8
|
||||||
#define LP_SAMPLER_GATHER_COMP_MASK (3 << 8)
|
#define LP_SAMPLER_GATHER_COMP_MASK (3 << 8)
|
||||||
#define LP_SAMPLER_FETCH_MS (1 << 10)
|
#define LP_SAMPLER_FETCH_MS (1 << 10)
|
||||||
|
#define LP_SAMPLER_RESIDENCY (1 << 11)
|
||||||
|
#define LP_SAMPLE_KEY_COUNT (1 << 12)
|
||||||
|
|
||||||
|
|
||||||
/* Parameters used to handle TEX instructions */
|
/* Parameters used to handle TEX instructions */
|
||||||
@@ -147,10 +149,11 @@ struct lp_sampler_size_query_params
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define LP_IMG_LOAD 0
|
#define LP_IMG_LOAD 0
|
||||||
#define LP_IMG_STORE 1
|
#define LP_IMG_LOAD_SPARSE 1
|
||||||
#define LP_IMG_ATOMIC 2
|
#define LP_IMG_STORE 2
|
||||||
#define LP_IMG_ATOMIC_CAS 3
|
#define LP_IMG_ATOMIC 3
|
||||||
#define LP_IMG_OP_COUNT 4
|
#define LP_IMG_ATOMIC_CAS 4
|
||||||
|
#define LP_IMG_OP_COUNT 5
|
||||||
|
|
||||||
struct lp_img_params
|
struct lp_img_params
|
||||||
{
|
{
|
||||||
@@ -373,6 +376,20 @@ struct lp_sampler_dynamic_state
|
|||||||
LLVMTypeRef thread_data_type,
|
LLVMTypeRef thread_data_type,
|
||||||
LLVMValueRef thread_data_ptr,
|
LLVMValueRef thread_data_ptr,
|
||||||
unsigned unit);
|
unsigned unit);
|
||||||
|
|
||||||
|
/** Obtain pointer to a bitset of resident tiles. */
|
||||||
|
LLVMValueRef
|
||||||
|
(*residency)(struct gallivm_state *gallivm,
|
||||||
|
LLVMTypeRef resources_type,
|
||||||
|
LLVMValueRef resources_ptr,
|
||||||
|
unsigned texture_unit, LLVMValueRef texture_unit_offset);
|
||||||
|
|
||||||
|
/** Obtain the offset of base_ptr into the referenced resource. */
|
||||||
|
LLVMValueRef
|
||||||
|
(*base_offset)(struct gallivm_state *gallivm,
|
||||||
|
LLVMTypeRef resources_type,
|
||||||
|
LLVMValueRef resources_ptr,
|
||||||
|
unsigned texture_unit, LLVMValueRef texture_unit_offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -416,6 +433,7 @@ struct lp_build_sample_context
|
|||||||
bool no_brilinear;
|
bool no_brilinear;
|
||||||
bool no_rho_approx;
|
bool no_rho_approx;
|
||||||
bool fetch_ms;
|
bool fetch_ms;
|
||||||
|
bool residency;
|
||||||
|
|
||||||
/** regular scalar float type */
|
/** regular scalar float type */
|
||||||
struct lp_type float_type;
|
struct lp_type float_type;
|
||||||
@@ -494,6 +512,8 @@ struct lp_build_sample_context
|
|||||||
LLVMValueRef resources_ptr;
|
LLVMValueRef resources_ptr;
|
||||||
|
|
||||||
LLVMValueRef aniso_filter_table;
|
LLVMValueRef aniso_filter_table;
|
||||||
|
|
||||||
|
LLVMValueRef resident;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -774,7 +794,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
|
|||||||
LLVMValueRef lod, /* optional */
|
LLVMValueRef lod, /* optional */
|
||||||
LLVMValueRef ms_index, /* optional */
|
LLVMValueRef ms_index, /* optional */
|
||||||
LLVMValueRef aniso_filter_table,
|
LLVMValueRef aniso_filter_table,
|
||||||
LLVMValueRef texel_out[4]);
|
LLVMValueRef *texel_out);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -818,7 +838,7 @@ lp_build_img_op_soa(const struct lp_static_texture_state *static_texture_state,
|
|||||||
struct lp_sampler_dynamic_state *dynamic_state,
|
struct lp_sampler_dynamic_state *dynamic_state,
|
||||||
struct gallivm_state *gallivm,
|
struct gallivm_state *gallivm,
|
||||||
const struct lp_img_params *params,
|
const struct lp_img_params *params,
|
||||||
LLVMValueRef outdata[4]);
|
LLVMValueRef *outdata);
|
||||||
|
|
||||||
void
|
void
|
||||||
lp_build_sample_array_init_soa(struct lp_build_sample_array_switch *switch_info,
|
lp_build_sample_array_init_soa(struct lp_build_sample_array_switch *switch_info,
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include "pipe/p_defines.h"
|
#include "pipe/p_defines.h"
|
||||||
#include "pipe/p_state.h"
|
#include "pipe/p_state.h"
|
||||||
#include "pipe/p_shader_tokens.h"
|
#include "pipe/p_shader_tokens.h"
|
||||||
|
#include "util/bitset.h"
|
||||||
#include "util/compiler.h"
|
#include "util/compiler.h"
|
||||||
#include "util/u_debug.h"
|
#include "util/u_debug.h"
|
||||||
#include "util/u_dump.h"
|
#include "util/u_dump.h"
|
||||||
@@ -65,6 +66,52 @@
|
|||||||
#include "lp_bld_misc.h"
|
#include "lp_bld_misc.h"
|
||||||
#include "lp_bld_jit_types.h"
|
#include "lp_bld_jit_types.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
lp_build_gather_resident(struct lp_build_context *bld,
|
||||||
|
struct lp_sampler_dynamic_state *dynamic_state,
|
||||||
|
LLVMTypeRef resources_type,
|
||||||
|
LLVMValueRef resources_ptr,
|
||||||
|
LLVMValueRef offset,
|
||||||
|
LLVMValueRef *out_resident)
|
||||||
|
{
|
||||||
|
struct lp_type type = lp_int_type(bld->type);
|
||||||
|
|
||||||
|
struct gallivm_state *gallivm = bld->gallivm;
|
||||||
|
LLVMBuilderRef builder = gallivm->builder;
|
||||||
|
|
||||||
|
static_assert(sizeof(BITSET_WORD) == 4, "Unexpected BITSET_WORD size");
|
||||||
|
|
||||||
|
LLVMValueRef residency =
|
||||||
|
dynamic_state->residency(gallivm, resources_type, resources_ptr, 0, NULL);
|
||||||
|
|
||||||
|
LLVMValueRef tile_size_log2 =
|
||||||
|
lp_build_const_int_vec(gallivm, type, util_logbase2(64 * 1024));
|
||||||
|
LLVMValueRef tile_index = LLVMBuildLShr(builder, offset, tile_size_log2, "");
|
||||||
|
|
||||||
|
LLVMValueRef dword_bitsize_log2 =
|
||||||
|
lp_build_const_int_vec(gallivm, type, util_logbase2(32));
|
||||||
|
LLVMValueRef dword_index = LLVMBuildLShr(builder, tile_index, dword_bitsize_log2, "");
|
||||||
|
|
||||||
|
LLVMValueRef dword_size_log2 =
|
||||||
|
lp_build_const_int_vec(gallivm, type, util_logbase2(4));
|
||||||
|
LLVMValueRef dword_offset = LLVMBuildShl(builder, dword_index, dword_size_log2, "");
|
||||||
|
|
||||||
|
residency = lp_build_gather(gallivm, type.length, type.width, lp_elem_type(type),
|
||||||
|
true, residency, dword_offset, true);
|
||||||
|
|
||||||
|
LLVMValueRef dword_bit_mask =
|
||||||
|
lp_build_const_int_vec(gallivm, type, 31);
|
||||||
|
LLVMValueRef bit_index = LLVMBuildAnd(builder, tile_index, dword_bit_mask, "");
|
||||||
|
LLVMValueRef bit_mask = LLVMBuildShl(builder, lp_build_one(gallivm, type), bit_index, "");
|
||||||
|
|
||||||
|
LLVMValueRef resident = LLVMBuildAnd(builder, residency, bit_mask, "");
|
||||||
|
resident = LLVMBuildICmp(builder, LLVMIntNE, resident, lp_build_zero(gallivm, type), "");
|
||||||
|
|
||||||
|
if (*out_resident)
|
||||||
|
*out_resident = LLVMBuildAnd(builder, *out_resident, resident, "");
|
||||||
|
else
|
||||||
|
*out_resident = resident;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate code to fetch a texel from a texture at int coords (x, y, z).
|
* Generate code to fetch a texel from a texture at int coords (x, y, z).
|
||||||
@@ -87,6 +134,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
|
|||||||
LLVMValueRef z_stride,
|
LLVMValueRef z_stride,
|
||||||
LLVMValueRef data_ptr,
|
LLVMValueRef data_ptr,
|
||||||
LLVMValueRef mipoffsets,
|
LLVMValueRef mipoffsets,
|
||||||
|
LLVMValueRef ilevel,
|
||||||
LLVMValueRef texel_out[4])
|
LLVMValueRef texel_out[4])
|
||||||
{
|
{
|
||||||
const struct lp_static_sampler_state *static_state = bld->static_sampler_state;
|
const struct lp_static_sampler_state *static_state = bld->static_sampler_state;
|
||||||
@@ -167,6 +215,22 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
|
|||||||
offset = lp_build_andnot(&bld->int_coord_bld, offset, use_border);
|
offset = lp_build_andnot(&bld->int_coord_bld, offset, use_border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bld->residency) {
|
||||||
|
LLVMValueRef real_offset = offset;
|
||||||
|
|
||||||
|
if (!mipoffsets) {
|
||||||
|
mipoffsets = lp_build_get_mip_offsets(bld, ilevel);
|
||||||
|
real_offset = lp_build_add(&bld->int_coord_bld, real_offset, mipoffsets);
|
||||||
|
|
||||||
|
if (use_border)
|
||||||
|
real_offset = lp_build_andnot(&bld->int_coord_bld, real_offset, use_border);
|
||||||
|
}
|
||||||
|
|
||||||
|
lp_build_gather_resident(&bld->float_vec_bld, bld->dynamic_state,
|
||||||
|
bld->resources_type, bld->resources_ptr,
|
||||||
|
real_offset, &bld->resident);
|
||||||
|
}
|
||||||
|
|
||||||
lp_build_fetch_rgba_soa(bld->gallivm,
|
lp_build_fetch_rgba_soa(bld->gallivm,
|
||||||
bld->format_desc,
|
bld->format_desc,
|
||||||
bld->texel_type, true,
|
bld->texel_type, true,
|
||||||
@@ -916,6 +980,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
|
|||||||
LLVMValueRef img_stride_vec,
|
LLVMValueRef img_stride_vec,
|
||||||
LLVMValueRef data_ptr,
|
LLVMValueRef data_ptr,
|
||||||
LLVMValueRef mipoffsets,
|
LLVMValueRef mipoffsets,
|
||||||
|
LLVMValueRef ilevel,
|
||||||
const LLVMValueRef *coords,
|
const LLVMValueRef *coords,
|
||||||
const LLVMValueRef *offsets,
|
const LLVMValueRef *offsets,
|
||||||
LLVMValueRef colors_out[4])
|
LLVMValueRef colors_out[4])
|
||||||
@@ -985,7 +1050,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
|
|||||||
width_vec, height_vec, depth_vec,
|
width_vec, height_vec, depth_vec,
|
||||||
x, y, z,
|
x, y, z,
|
||||||
row_stride_vec, img_stride_vec,
|
row_stride_vec, img_stride_vec,
|
||||||
data_ptr, mipoffsets, colors_out);
|
data_ptr, mipoffsets, ilevel, colors_out);
|
||||||
|
|
||||||
if (bld->static_sampler_state->compare_mode != PIPE_TEX_COMPARE_NONE) {
|
if (bld->static_sampler_state->compare_mode != PIPE_TEX_COMPARE_NONE) {
|
||||||
LLVMValueRef cmpval;
|
LLVMValueRef cmpval;
|
||||||
@@ -1062,6 +1127,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
|
|||||||
LLVMValueRef img_stride_vec,
|
LLVMValueRef img_stride_vec,
|
||||||
LLVMValueRef data_ptr,
|
LLVMValueRef data_ptr,
|
||||||
LLVMValueRef mipoffsets,
|
LLVMValueRef mipoffsets,
|
||||||
|
LLVMValueRef ilevel,
|
||||||
const LLVMValueRef *coords,
|
const LLVMValueRef *coords,
|
||||||
const LLVMValueRef *offsets,
|
const LLVMValueRef *offsets,
|
||||||
LLVMValueRef colors_out[4])
|
LLVMValueRef colors_out[4])
|
||||||
@@ -1395,12 +1461,12 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
|
|||||||
width_vec, height_vec, depth_vec,
|
width_vec, height_vec, depth_vec,
|
||||||
x00, y00, z00,
|
x00, y00, z00,
|
||||||
row_stride_vec, img_stride_vec,
|
row_stride_vec, img_stride_vec,
|
||||||
data_ptr, mipoffsets, neighbors[0][0]);
|
data_ptr, mipoffsets, ilevel, neighbors[0][0]);
|
||||||
lp_build_sample_texel_soa(bld,
|
lp_build_sample_texel_soa(bld,
|
||||||
width_vec, height_vec, depth_vec,
|
width_vec, height_vec, depth_vec,
|
||||||
x01, y01, z01,
|
x01, y01, z01,
|
||||||
row_stride_vec, img_stride_vec,
|
row_stride_vec, img_stride_vec,
|
||||||
data_ptr, mipoffsets, neighbors[0][1]);
|
data_ptr, mipoffsets, ilevel, neighbors[0][1]);
|
||||||
|
|
||||||
if (dims == 1) {
|
if (dims == 1) {
|
||||||
assert(!is_gather);
|
assert(!is_gather);
|
||||||
@@ -1432,12 +1498,12 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
|
|||||||
width_vec, height_vec, depth_vec,
|
width_vec, height_vec, depth_vec,
|
||||||
x10, y10, z10,
|
x10, y10, z10,
|
||||||
row_stride_vec, img_stride_vec,
|
row_stride_vec, img_stride_vec,
|
||||||
data_ptr, mipoffsets, neighbors[1][0]);
|
data_ptr, mipoffsets, ilevel, neighbors[1][0]);
|
||||||
lp_build_sample_texel_soa(bld,
|
lp_build_sample_texel_soa(bld,
|
||||||
width_vec, height_vec, depth_vec,
|
width_vec, height_vec, depth_vec,
|
||||||
x11, y11, z11,
|
x11, y11, z11,
|
||||||
row_stride_vec, img_stride_vec,
|
row_stride_vec, img_stride_vec,
|
||||||
data_ptr, mipoffsets, neighbors[1][1]);
|
data_ptr, mipoffsets, ilevel, neighbors[1][1]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To avoid having to duplicate linear_mask / fetch code use
|
* To avoid having to duplicate linear_mask / fetch code use
|
||||||
@@ -1723,22 +1789,22 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
|
|||||||
width_vec, height_vec, depth_vec,
|
width_vec, height_vec, depth_vec,
|
||||||
x00, y00, z1,
|
x00, y00, z1,
|
||||||
row_stride_vec, img_stride_vec,
|
row_stride_vec, img_stride_vec,
|
||||||
data_ptr, mipoffsets, neighbors1[0][0]);
|
data_ptr, mipoffsets, ilevel, neighbors1[0][0]);
|
||||||
lp_build_sample_texel_soa(bld,
|
lp_build_sample_texel_soa(bld,
|
||||||
width_vec, height_vec, depth_vec,
|
width_vec, height_vec, depth_vec,
|
||||||
x01, y01, z1,
|
x01, y01, z1,
|
||||||
row_stride_vec, img_stride_vec,
|
row_stride_vec, img_stride_vec,
|
||||||
data_ptr, mipoffsets, neighbors1[0][1]);
|
data_ptr, mipoffsets, ilevel, neighbors1[0][1]);
|
||||||
lp_build_sample_texel_soa(bld,
|
lp_build_sample_texel_soa(bld,
|
||||||
width_vec, height_vec, depth_vec,
|
width_vec, height_vec, depth_vec,
|
||||||
x10, y10, z1,
|
x10, y10, z1,
|
||||||
row_stride_vec, img_stride_vec,
|
row_stride_vec, img_stride_vec,
|
||||||
data_ptr, mipoffsets, neighbors1[1][0]);
|
data_ptr, mipoffsets, ilevel, neighbors1[1][0]);
|
||||||
lp_build_sample_texel_soa(bld,
|
lp_build_sample_texel_soa(bld,
|
||||||
width_vec, height_vec, depth_vec,
|
width_vec, height_vec, depth_vec,
|
||||||
x11, y11, z1,
|
x11, y11, z1,
|
||||||
row_stride_vec, img_stride_vec,
|
row_stride_vec, img_stride_vec,
|
||||||
data_ptr, mipoffsets, neighbors1[1][1]);
|
data_ptr, mipoffsets, ilevel, neighbors1[1][1]);
|
||||||
|
|
||||||
if (bld->static_sampler_state->compare_mode == PIPE_TEX_COMPARE_NONE) {
|
if (bld->static_sampler_state->compare_mode == PIPE_TEX_COMPARE_NONE) {
|
||||||
/* Bilinear interpolate the four samples from the second Z slice */
|
/* Bilinear interpolate the four samples from the second Z slice */
|
||||||
@@ -1854,13 +1920,13 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
|
|||||||
if (img_filter == PIPE_TEX_FILTER_NEAREST) {
|
if (img_filter == PIPE_TEX_FILTER_NEAREST) {
|
||||||
lp_build_sample_image_nearest(bld, size0,
|
lp_build_sample_image_nearest(bld, size0,
|
||||||
row_stride0_vec, img_stride0_vec,
|
row_stride0_vec, img_stride0_vec,
|
||||||
data_ptr0, mipoff0, coords, offsets,
|
data_ptr0, mipoff0, ilevel0, coords, offsets,
|
||||||
colors0);
|
colors0);
|
||||||
} else {
|
} else {
|
||||||
assert(img_filter == PIPE_TEX_FILTER_LINEAR);
|
assert(img_filter == PIPE_TEX_FILTER_LINEAR);
|
||||||
lp_build_sample_image_linear(bld, is_gather, size0, NULL,
|
lp_build_sample_image_linear(bld, is_gather, size0, NULL,
|
||||||
row_stride0_vec, img_stride0_vec,
|
row_stride0_vec, img_stride0_vec,
|
||||||
data_ptr0, mipoff0, coords, offsets,
|
data_ptr0, mipoff0, ilevel0, coords, offsets,
|
||||||
colors0);
|
colors0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1914,12 +1980,12 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
|
|||||||
if (img_filter == PIPE_TEX_FILTER_NEAREST) {
|
if (img_filter == PIPE_TEX_FILTER_NEAREST) {
|
||||||
lp_build_sample_image_nearest(bld, size1,
|
lp_build_sample_image_nearest(bld, size1,
|
||||||
row_stride1_vec, img_stride1_vec,
|
row_stride1_vec, img_stride1_vec,
|
||||||
data_ptr1, mipoff1, coords, offsets,
|
data_ptr1, mipoff1, ilevel1, coords, offsets,
|
||||||
colors1);
|
colors1);
|
||||||
} else {
|
} else {
|
||||||
lp_build_sample_image_linear(bld, false, size1, NULL,
|
lp_build_sample_image_linear(bld, false, size1, NULL,
|
||||||
row_stride1_vec, img_stride1_vec,
|
row_stride1_vec, img_stride1_vec,
|
||||||
data_ptr1, mipoff1, coords, offsets,
|
data_ptr1, mipoff1, ilevel1, coords, offsets,
|
||||||
colors1);
|
colors1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1991,7 +2057,7 @@ lp_build_sample_mipmap_both(struct lp_build_sample_context *bld,
|
|||||||
|
|
||||||
lp_build_sample_image_linear(bld, false, size0, linear_mask,
|
lp_build_sample_image_linear(bld, false, size0, linear_mask,
|
||||||
row_stride0_vec, img_stride0_vec,
|
row_stride0_vec, img_stride0_vec,
|
||||||
data_ptr0, mipoff0, coords, offsets,
|
data_ptr0, mipoff0, ilevel0, coords, offsets,
|
||||||
colors0);
|
colors0);
|
||||||
|
|
||||||
/* Store the first level's colors in the output variables */
|
/* Store the first level's colors in the output variables */
|
||||||
@@ -2035,7 +2101,7 @@ lp_build_sample_mipmap_both(struct lp_build_sample_context *bld,
|
|||||||
|
|
||||||
lp_build_sample_image_linear(bld, false, size1, linear_mask,
|
lp_build_sample_image_linear(bld, false, size1, linear_mask,
|
||||||
row_stride1_vec, img_stride1_vec,
|
row_stride1_vec, img_stride1_vec,
|
||||||
data_ptr1, mipoff1, coords, offsets,
|
data_ptr1, mipoff1, ilevel1, coords, offsets,
|
||||||
colors1);
|
colors1);
|
||||||
|
|
||||||
/* interpolate samples from the two mipmap levels */
|
/* interpolate samples from the two mipmap levels */
|
||||||
@@ -2456,7 +2522,7 @@ lp_build_sample_aniso(struct lp_build_sample_context *bld,
|
|||||||
LLVMValueRef temp_colors[4];
|
LLVMValueRef temp_colors[4];
|
||||||
lp_build_sample_image_nearest(bld, size0,
|
lp_build_sample_image_nearest(bld, size0,
|
||||||
row_stride0_vec, img_stride0_vec,
|
row_stride0_vec, img_stride0_vec,
|
||||||
data_ptr0, mipoff0, new_coords, offsets,
|
data_ptr0, mipoff0, ilevel0, new_coords, offsets,
|
||||||
temp_colors);
|
temp_colors);
|
||||||
|
|
||||||
for (unsigned chan = 0; chan < 4; chan++) {
|
for (unsigned chan = 0; chan < 4; chan++) {
|
||||||
@@ -2546,7 +2612,7 @@ lp_build_sample_aniso(struct lp_build_sample_context *bld,
|
|||||||
LLVMValueRef colors_den0[4];
|
LLVMValueRef colors_den0[4];
|
||||||
lp_build_sample_image_linear(bld, false, size0, NULL,
|
lp_build_sample_image_linear(bld, false, size0, NULL,
|
||||||
row_stride0_vec, img_stride0_vec,
|
row_stride0_vec, img_stride0_vec,
|
||||||
data_ptr0, mipoff0, coords, offsets,
|
data_ptr0, mipoff0, ilevel0, coords, offsets,
|
||||||
colors_den0);
|
colors_den0);
|
||||||
for (unsigned chan = 0; chan < 4; chan++) {
|
for (unsigned chan = 0; chan < 4; chan++) {
|
||||||
LLVMValueRef chan_val =
|
LLVMValueRef chan_val =
|
||||||
@@ -3290,6 +3356,12 @@ lp_build_fetch_texel(struct lp_build_sample_context *bld,
|
|||||||
&offset, &out_of_bounds);
|
&offset, &out_of_bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bld->residency) {
|
||||||
|
lp_build_gather_resident(&bld->float_vec_bld, bld->dynamic_state,
|
||||||
|
bld->resources_type, bld->resources_ptr,
|
||||||
|
offset, &bld->resident);
|
||||||
|
}
|
||||||
|
|
||||||
offset = lp_build_andnot(int_coord_bld, offset, out_of_bounds);
|
offset = lp_build_andnot(int_coord_bld, offset, out_of_bounds);
|
||||||
|
|
||||||
lp_build_fetch_rgba_soa(bld->gallivm,
|
lp_build_fetch_rgba_soa(bld->gallivm,
|
||||||
@@ -3388,7 +3460,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
|
|||||||
LLVMValueRef lod, /* optional */
|
LLVMValueRef lod, /* optional */
|
||||||
LLVMValueRef ms_index, /* optional */
|
LLVMValueRef ms_index, /* optional */
|
||||||
LLVMValueRef aniso_filter_table,
|
LLVMValueRef aniso_filter_table,
|
||||||
LLVMValueRef texel_out[4])
|
LLVMValueRef *texel_out)
|
||||||
{
|
{
|
||||||
assert(static_texture_state);
|
assert(static_texture_state);
|
||||||
assert(static_texture_state->format < PIPE_FORMAT_COUNT);
|
assert(static_texture_state->format < PIPE_FORMAT_COUNT);
|
||||||
@@ -3596,6 +3668,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bld.fetch_ms = fetch_ms;
|
bld.fetch_ms = fetch_ms;
|
||||||
|
bld.residency = !!(sample_key & LP_SAMPLER_RESIDENCY);
|
||||||
if (op_is_gather)
|
if (op_is_gather)
|
||||||
bld.gather_comp = (sample_key & LP_SAMPLER_GATHER_COMP_MASK) >> LP_SAMPLER_GATHER_COMP_SHIFT;
|
bld.gather_comp = (sample_key & LP_SAMPLER_GATHER_COMP_MASK) >> LP_SAMPLER_GATHER_COMP_SHIFT;
|
||||||
bld.lodf_type = type;
|
bld.lodf_type = type;
|
||||||
@@ -3770,6 +3843,8 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
|
|||||||
} else if (op_type == LP_SAMPLER_OP_FETCH) {
|
} else if (op_type == LP_SAMPLER_OP_FETCH) {
|
||||||
lp_build_fetch_texel(&bld, texture_index, ms_index, newcoords,
|
lp_build_fetch_texel(&bld, texture_index, ms_index, newcoords,
|
||||||
lod, offsets, texel_out);
|
lod, offsets, texel_out);
|
||||||
|
if (bld.residency)
|
||||||
|
texel_out[4] = bld.resident;
|
||||||
} else {
|
} else {
|
||||||
LLVMValueRef lod_fpart = NULL, lod_positive = NULL;
|
LLVMValueRef lod_fpart = NULL, lod_positive = NULL;
|
||||||
LLVMValueRef ilevel0 = NULL, ilevel1 = NULL, lod = NULL;
|
LLVMValueRef ilevel0 = NULL, ilevel1 = NULL, lod = NULL;
|
||||||
@@ -3830,6 +3905,8 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
|
|||||||
texel_out[0] = lod_fpart;
|
texel_out[0] = lod_fpart;
|
||||||
texel_out[1] = lod;
|
texel_out[1] = lod;
|
||||||
texel_out[2] = texel_out[3] = bld.coord_bld.zero;
|
texel_out[2] = texel_out[3] = bld.coord_bld.zero;
|
||||||
|
if (bld.residency)
|
||||||
|
texel_out[4] = bld.resident;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3863,6 +3940,8 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
|
|||||||
lod_positive, lod_fpart,
|
lod_positive, lod_fpart,
|
||||||
ilevel0, ilevel1,
|
ilevel0, ilevel1,
|
||||||
texel_out);
|
texel_out);
|
||||||
|
if (bld.residency)
|
||||||
|
texel_out[4] = bld.resident;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct lp_build_sample_context bld4;
|
struct lp_build_sample_context bld4;
|
||||||
@@ -4895,7 +4974,7 @@ lp_build_img_op_soa(const struct lp_static_texture_state *static_texture_state,
|
|||||||
struct lp_sampler_dynamic_state *dynamic_state,
|
struct lp_sampler_dynamic_state *dynamic_state,
|
||||||
struct gallivm_state *gallivm,
|
struct gallivm_state *gallivm,
|
||||||
const struct lp_img_params *params,
|
const struct lp_img_params *params,
|
||||||
LLVMValueRef outdata[4])
|
LLVMValueRef *outdata)
|
||||||
{
|
{
|
||||||
const enum pipe_texture_target target = params->target;
|
const enum pipe_texture_target target = params->target;
|
||||||
const unsigned dims = texture_dims(target);
|
const unsigned dims = texture_dims(target);
|
||||||
@@ -5005,9 +5084,22 @@ lp_build_img_op_soa(const struct lp_static_texture_state *static_texture_state,
|
|||||||
sample_stride, &offset,
|
sample_stride, &offset,
|
||||||
&out_of_bounds);
|
&out_of_bounds);
|
||||||
}
|
}
|
||||||
if (params->img_op == LP_IMG_LOAD) {
|
if (params->img_op == LP_IMG_LOAD || params->img_op == LP_IMG_LOAD_SPARSE) {
|
||||||
struct lp_type texel_type = lp_build_texel_type(params->type, format_desc);
|
struct lp_type texel_type = lp_build_texel_type(params->type, format_desc);
|
||||||
|
|
||||||
|
if (params->img_op == LP_IMG_LOAD_SPARSE && static_texture_state->tiled) {
|
||||||
|
LLVMValueRef base_offset =
|
||||||
|
dynamic_state->base_offset(gallivm, params->resources_type,
|
||||||
|
params->resources_ptr, params->image_index, NULL);
|
||||||
|
base_offset = lp_build_broadcast_scalar(&int_coord_bld, base_offset);
|
||||||
|
|
||||||
|
LLVMValueRef full_offset = LLVMBuildAdd(gallivm->builder, base_offset, offset, "");
|
||||||
|
|
||||||
|
lp_build_gather_resident(&int_coord_bld, dynamic_state,
|
||||||
|
params->resources_type, params->resources_ptr,
|
||||||
|
full_offset, &outdata[4]);
|
||||||
|
}
|
||||||
|
|
||||||
offset = lp_build_andnot(&int_coord_bld, offset, out_of_bounds);
|
offset = lp_build_andnot(&int_coord_bld, offset, out_of_bounds);
|
||||||
struct lp_build_context texel_bld;
|
struct lp_build_context texel_bld;
|
||||||
lp_build_context_init(&texel_bld, gallivm, texel_type);
|
lp_build_context_init(&texel_bld, gallivm, texel_type);
|
||||||
|
@@ -445,6 +445,9 @@ lp_jit_texture_from_pipe(struct lp_jit_texture *jit, const struct pipe_sampler_v
|
|||||||
else
|
else
|
||||||
assert(view->u.tex.last_layer < res->array_size);
|
assert(view->u.tex.last_layer < res->array_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res->flags & PIPE_RESOURCE_FLAG_SPARSE)
|
||||||
|
jit->residency = lp_tex->residency;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* For tex2d_from_buf, adjust width and height with application
|
* For tex2d_from_buf, adjust width and height with application
|
||||||
@@ -610,6 +613,11 @@ lp_jit_image_from_pipe(struct lp_jit_image *jit, const struct pipe_image_view *v
|
|||||||
view->u.tex2d_from_buf.offset * image_blocksize;
|
view->u.tex2d_from_buf.offset * image_blocksize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res->flags & PIPE_RESOURCE_FLAG_SPARSE) {
|
||||||
|
jit->residency = lp_res->residency;
|
||||||
|
jit->base_offset = (uint32_t)((uintptr_t)jit->base - (uintptr_t)lp_res->tex_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -327,6 +327,8 @@ llvmpipe_resource_create_all(struct pipe_screen *_screen,
|
|||||||
-1, 0);
|
-1, 0);
|
||||||
madvise(lpr->tex_data, lpr->size_required, MADV_DONTNEED);
|
madvise(lpr->tex_data, lpr->size_required, MADV_DONTNEED);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
lpr->residency = calloc(DIV_ROUND_UP(lpr->size_required, 64 * 1024 * sizeof(uint32_t) * 8), sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -578,6 +580,8 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(lpr->residency);
|
||||||
|
|
||||||
#if MESA_DEBUG
|
#if MESA_DEBUG
|
||||||
simple_mtx_lock(&resource_list_mutex);
|
simple_mtx_lock(&resource_list_mutex);
|
||||||
if (!list_is_empty(&lpr->list))
|
if (!list_is_empty(&lpr->list))
|
||||||
@@ -1564,6 +1568,7 @@ llvmpipe_resource_bind_backing(struct pipe_screen *pscreen,
|
|||||||
if (llvmpipe_resource_is_texture(&lpr->base)) {
|
if (llvmpipe_resource_is_texture(&lpr->base)) {
|
||||||
mmap((char *)lpr->tex_data + offset, size, PROT_READ|PROT_WRITE,
|
mmap((char *)lpr->tex_data + offset, size, PROT_READ|PROT_WRITE,
|
||||||
MAP_SHARED|MAP_FIXED, mem->fd, mem->offset + fd_offset);
|
MAP_SHARED|MAP_FIXED, mem->fd, mem->offset + fd_offset);
|
||||||
|
BITSET_SET(lpr->residency, offset / (64 * 1024));
|
||||||
} else {
|
} else {
|
||||||
mmap((char *)lpr->data + offset, size, PROT_READ|PROT_WRITE,
|
mmap((char *)lpr->data + offset, size, PROT_READ|PROT_WRITE,
|
||||||
MAP_SHARED|MAP_FIXED, mem->fd, mem->offset + fd_offset);
|
MAP_SHARED|MAP_FIXED, mem->fd, mem->offset + fd_offset);
|
||||||
@@ -1572,6 +1577,7 @@ llvmpipe_resource_bind_backing(struct pipe_screen *pscreen,
|
|||||||
if (llvmpipe_resource_is_texture(&lpr->base)) {
|
if (llvmpipe_resource_is_texture(&lpr->base)) {
|
||||||
mmap((char *)lpr->tex_data + offset, size, PROT_READ|PROT_WRITE,
|
mmap((char *)lpr->tex_data + offset, size, PROT_READ|PROT_WRITE,
|
||||||
MAP_SHARED|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
|
MAP_SHARED|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
|
||||||
|
BITSET_CLEAR(lpr->residency, offset / (64 * 1024));
|
||||||
} else {
|
} else {
|
||||||
mmap((char *)lpr->data + offset, size, PROT_READ|PROT_WRITE,
|
mmap((char *)lpr->data + offset, size, PROT_READ|PROT_WRITE,
|
||||||
MAP_SHARED|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
|
MAP_SHARED|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include "pipe/p_state.h"
|
#include "pipe/p_state.h"
|
||||||
#include "util/u_debug.h"
|
#include "util/u_debug.h"
|
||||||
#include "lp_limits.h"
|
#include "lp_limits.h"
|
||||||
|
#include "util/bitset.h"
|
||||||
#if MESA_DEBUG
|
#if MESA_DEBUG
|
||||||
#include "util/list.h"
|
#include "util/list.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -93,6 +94,8 @@ struct llvmpipe_resource
|
|||||||
*/
|
*/
|
||||||
void *tex_data;
|
void *tex_data;
|
||||||
|
|
||||||
|
BITSET_WORD *residency;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data for non-texture resources.
|
* Data for non-texture resources.
|
||||||
*/
|
*/
|
||||||
|
@@ -261,7 +261,7 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st
|
|||||||
if (op >= LP_IMG_OP_COUNT - 1) {
|
if (op >= LP_IMG_OP_COUNT - 1) {
|
||||||
params.img_op = LP_IMG_ATOMIC;
|
params.img_op = LP_IMG_ATOMIC;
|
||||||
params.op = op - (LP_IMG_OP_COUNT - 1);
|
params.op = op - (LP_IMG_OP_COUNT - 1);
|
||||||
} else if (op != LP_IMG_LOAD && op != LP_IMG_STORE) {
|
} else if (op != LP_IMG_LOAD && op != LP_IMG_LOAD_SPARSE && op != LP_IMG_STORE) {
|
||||||
params.img_op = LP_IMG_ATOMIC_CAS;
|
params.img_op = LP_IMG_ATOMIC_CAS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +319,7 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st
|
|||||||
|
|
||||||
gallivm->texture_descriptor = LLVMGetParam(function, arg_index++);
|
gallivm->texture_descriptor = LLVMGetParam(function, arg_index++);
|
||||||
|
|
||||||
if (params.img_op != LP_IMG_LOAD)
|
if (params.img_op != LP_IMG_LOAD && params.img_op != LP_IMG_LOAD_SPARSE)
|
||||||
params.exec_mask = LLVMGetParam(function, arg_index++);
|
params.exec_mask = LLVMGetParam(function, arg_index++);
|
||||||
|
|
||||||
LLVMValueRef coords[3];
|
LLVMValueRef coords[3];
|
||||||
@@ -330,7 +330,7 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st
|
|||||||
if (ms)
|
if (ms)
|
||||||
params.ms_index = LLVMGetParam(function, arg_index++);
|
params.ms_index = LLVMGetParam(function, arg_index++);
|
||||||
|
|
||||||
if (params.img_op != LP_IMG_LOAD)
|
if (params.img_op != LP_IMG_LOAD && params.img_op != LP_IMG_LOAD_SPARSE)
|
||||||
for (uint32_t i = 0; i < 4; i++)
|
for (uint32_t i = 0; i < 4; i++)
|
||||||
params.indata[i] = LLVMGetParam(function, arg_index++);
|
params.indata[i] = LLVMGetParam(function, arg_index++);
|
||||||
|
|
||||||
@@ -343,15 +343,20 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st
|
|||||||
gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
|
gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
|
||||||
LLVMPositionBuilderAtEnd(gallivm->builder, block);
|
LLVMPositionBuilderAtEnd(gallivm->builder, block);
|
||||||
|
|
||||||
LLVMValueRef outdata[4] = { 0 };
|
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(texture, lp_build_image_soa_dynamic_state(image_soa), gallivm, ¶ms, outdata);
|
||||||
|
|
||||||
for (uint32_t i = 1; i < 4; i++)
|
for (uint32_t i = 1; i < 4; i++)
|
||||||
if (!outdata[i])
|
if (!outdata[i])
|
||||||
outdata[i] = outdata[0];
|
outdata[i] = outdata[0];
|
||||||
|
|
||||||
|
if (outdata[4])
|
||||||
|
outdata[4] = LLVMBuildZExt(gallivm->builder, outdata[4], lp_build_int_vec_type(gallivm, lp_int_type(type)), "");
|
||||||
|
else
|
||||||
|
outdata[4] = lp_build_one(gallivm, lp_int_type(type));
|
||||||
|
|
||||||
if (params.img_op != LP_IMG_STORE)
|
if (params.img_op != LP_IMG_STORE)
|
||||||
LLVMBuildAggregateRet(gallivm->builder, outdata, 4);
|
LLVMBuildAggregateRet(gallivm->builder, outdata, params.img_op == LP_IMG_LOAD_SPARSE ? 5 : 4);
|
||||||
else
|
else
|
||||||
LLVMBuildRetVoid(gallivm->builder);
|
LLVMBuildRetVoid(gallivm->builder);
|
||||||
|
|
||||||
@@ -492,7 +497,7 @@ compile_sample_function(struct llvmpipe_context *ctx, struct lp_static_texture_s
|
|||||||
gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
|
gallivm->builder = LLVMCreateBuilderInContext(gallivm->context);
|
||||||
LLVMPositionBuilderAtEnd(gallivm->builder, block);
|
LLVMPositionBuilderAtEnd(gallivm->builder, block);
|
||||||
|
|
||||||
LLVMValueRef texel_out[4] = { 0 };
|
LLVMValueRef texel_out[5] = { 0 };
|
||||||
if (supported) {
|
if (supported) {
|
||||||
lp_build_sample_soa_code(gallivm, texture, sampler, lp_build_sampler_soa_dynamic_state(sampler_soa),
|
lp_build_sample_soa_code(gallivm, texture, sampler, lp_build_sampler_soa_dynamic_state(sampler_soa),
|
||||||
type, sample_key, 0, 0, cs.jit_resources_type, NULL, cs.jit_cs_thread_data_type,
|
type, sample_key, 0, 0, cs.jit_resources_type, NULL, cs.jit_cs_thread_data_type,
|
||||||
@@ -501,7 +506,12 @@ compile_sample_function(struct llvmpipe_context *ctx, struct lp_static_texture_s
|
|||||||
lp_build_sample_nop(gallivm, lp_build_texel_type(type, util_format_description(texture->format)), coords, texel_out);
|
lp_build_sample_nop(gallivm, lp_build_texel_type(type, util_format_description(texture->format)), coords, texel_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMBuildAggregateRet(gallivm->builder, texel_out, 4);
|
if (texel_out[4])
|
||||||
|
texel_out[4] = LLVMBuildZExt(gallivm->builder, texel_out[4], lp_build_int_vec_type(gallivm, lp_int_type(type)), "");
|
||||||
|
else
|
||||||
|
texel_out[4] = lp_build_one(gallivm, lp_int_type(type));
|
||||||
|
|
||||||
|
LLVMBuildAggregateRet(gallivm->builder, texel_out, 5);
|
||||||
|
|
||||||
LLVMDisposeBuilder(gallivm->builder);
|
LLVMDisposeBuilder(gallivm->builder);
|
||||||
gallivm->builder = old_builder;
|
gallivm->builder = old_builder;
|
||||||
|
@@ -31,8 +31,6 @@
|
|||||||
#include "gallivm/lp_bld_sample.h"
|
#include "gallivm/lp_bld_sample.h"
|
||||||
#include "gallivm/lp_bld_jit_sample.h"
|
#include "gallivm/lp_bld_jit_sample.h"
|
||||||
|
|
||||||
#define LP_SAMPLE_KEY_COUNT (1 << 11)
|
|
||||||
|
|
||||||
struct lp_sampler_matrix {
|
struct lp_sampler_matrix {
|
||||||
struct lp_texture_functions **textures;
|
struct lp_texture_functions **textures;
|
||||||
struct lp_static_sampler_state *samplers;
|
struct lp_static_sampler_state *samplers;
|
||||||
|
@@ -349,6 +349,7 @@ lvp_get_features(const struct lvp_physical_device *pdevice,
|
|||||||
.sparseResidencyImage2D = DETECT_OS_LINUX,
|
.sparseResidencyImage2D = DETECT_OS_LINUX,
|
||||||
.sparseResidencyImage3D = DETECT_OS_LINUX,
|
.sparseResidencyImage3D = DETECT_OS_LINUX,
|
||||||
.sparseResidencyAliased = DETECT_OS_LINUX,
|
.sparseResidencyAliased = DETECT_OS_LINUX,
|
||||||
|
.shaderResourceResidency = DETECT_OS_LINUX,
|
||||||
|
|
||||||
/* Vulkan 1.1 */
|
/* Vulkan 1.1 */
|
||||||
.storageBuffer16BitAccess = true,
|
.storageBuffer16BitAccess = true,
|
||||||
|
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2024 Valve Corporation
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lvp_private.h"
|
||||||
|
|
||||||
|
#include "nir.h"
|
||||||
|
#include "nir_builder.h"
|
||||||
|
|
||||||
|
static bool
|
||||||
|
pass(nir_builder *b, nir_intrinsic_instr *instr, void *data)
|
||||||
|
{
|
||||||
|
b->cursor = nir_before_instr(&instr->instr);
|
||||||
|
|
||||||
|
if (instr->intrinsic == nir_intrinsic_sparse_residency_code_and) {
|
||||||
|
nir_def_rewrite_uses(&instr->def, nir_iand(b, instr->src[0].ssa, instr->src[1].ssa));
|
||||||
|
return true;
|
||||||
|
} else if (instr->intrinsic == nir_intrinsic_is_sparse_texels_resident) {
|
||||||
|
nir_def_rewrite_uses(&instr->def, nir_ine_imm(b, instr->src[0].ssa, 0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
lvp_nir_lower_sparse_residency(struct nir_shader *shader)
|
||||||
|
{
|
||||||
|
return nir_shader_intrinsics_pass(shader, pass, nir_metadata_block_index | nir_metadata_dominance, NULL);
|
||||||
|
}
|
@@ -443,10 +443,17 @@ lvp_shader_lower(struct lvp_device *pdevice, struct lvp_pipeline *pipeline, nir_
|
|||||||
* functions that need to be pre-compiled.
|
* functions that need to be pre-compiled.
|
||||||
*/
|
*/
|
||||||
const nir_lower_tex_options tex_options = {
|
const nir_lower_tex_options tex_options = {
|
||||||
|
/* lower_tg4_offsets can introduce new sparse residency intrinsics
|
||||||
|
* which is why we have to lower everything before calling
|
||||||
|
* lvp_nir_lower_sparse_residency.
|
||||||
|
*/
|
||||||
|
.lower_tg4_offsets = true,
|
||||||
.lower_txd = true,
|
.lower_txd = true,
|
||||||
};
|
};
|
||||||
NIR_PASS(_, nir, nir_lower_tex, &tex_options);
|
NIR_PASS(_, nir, nir_lower_tex, &tex_options);
|
||||||
|
|
||||||
|
NIR_PASS(_, nir, lvp_nir_lower_sparse_residency);
|
||||||
|
|
||||||
lvp_shader_optimize(nir);
|
lvp_shader_optimize(nir);
|
||||||
|
|
||||||
if (nir->info.stage != MESA_SHADER_VERTEX)
|
if (nir->info.stage != MESA_SHADER_VERTEX)
|
||||||
|
@@ -771,6 +771,8 @@ void *
|
|||||||
lvp_shader_compile(struct lvp_device *device, struct lvp_shader *shader, nir_shader *nir, bool locked);
|
lvp_shader_compile(struct lvp_device *device, struct lvp_shader *shader, nir_shader *nir, bool locked);
|
||||||
bool
|
bool
|
||||||
lvp_nir_lower_ray_queries(struct nir_shader *shader);
|
lvp_nir_lower_ray_queries(struct nir_shader *shader);
|
||||||
|
bool
|
||||||
|
lvp_nir_lower_sparse_residency(struct nir_shader *shader);
|
||||||
enum vk_cmd_type
|
enum vk_cmd_type
|
||||||
lvp_nv_dgc_token_to_cmd_type(const VkIndirectCommandsLayoutTokenNV *token);
|
lvp_nv_dgc_token_to_cmd_type(const VkIndirectCommandsLayoutTokenNV *token);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -27,6 +27,7 @@ liblvp_files = files(
|
|||||||
'lvp_lower_vulkan_resource.h',
|
'lvp_lower_vulkan_resource.h',
|
||||||
'lvp_lower_input_attachments.c',
|
'lvp_lower_input_attachments.c',
|
||||||
'lvp_nir_lower_ray_queries.c',
|
'lvp_nir_lower_ray_queries.c',
|
||||||
|
'lvp_nir_lower_sparse_residency.c',
|
||||||
'lvp_nir_ray_tracing.c',
|
'lvp_nir_ray_tracing.c',
|
||||||
'lvp_nir_ray_tracing.h',
|
'lvp_nir_ray_tracing.h',
|
||||||
'lvp_pipe_sync.c',
|
'lvp_pipe_sync.c',
|
||||||
|
Reference in New Issue
Block a user