#define LP_SAMPLER_LOD_PROPERTY_MASK (3 << 6)
#define LP_SAMPLER_GATHER_COMP_SHIFT 8
#define LP_SAMPLER_GATHER_COMP_MASK (3 << 8)
+#define LP_SAMPLER_FETCH_MS (1 << 10)
struct lp_sampler_params
{
LLVMValueRef thread_data_ptr;
const LLVMValueRef *coords;
const LLVMValueRef *offsets;
+ LLVMValueRef ms_index;
LLVMValueRef lod;
const struct lp_derivatives *derivs;
LLVMValueRef *texel;
LLVMValueRef context_ptr,
unsigned texture_unit);
+ /** Obtain number of samples (returns int32) */
+ LLVMValueRef
+ (*num_samples)(const struct lp_sampler_dynamic_state *state,
+ struct gallivm_state *gallivm,
+ LLVMValueRef context_ptr,
+ unsigned texture_unit);
+
+ /** Obtain multisample stride (returns int32) */
+ LLVMValueRef
+ (*sample_stride)(const struct lp_sampler_dynamic_state *state,
+ struct gallivm_state *gallivm,
+ LLVMValueRef context_ptr,
+ unsigned texture_unit);
+
/* These are callbacks for sampler state */
/** Obtain texture min lod (returns float) */
boolean no_quad_lod;
boolean no_brilinear;
boolean no_rho_approx;
+ boolean fetch_ms;
/** regular scalar float type */
struct lp_type float_type;
LLVMValueRef base_ptr;
LLVMValueRef mip_offsets;
LLVMValueRef cache;
+ LLVMValueRef sample_stride;
/** Integer vector with texture width, height, depth */
LLVMValueRef int_size;
static void
lp_build_fetch_texel(struct lp_build_sample_context *bld,
unsigned texture_unit,
+ LLVMValueRef ms_index,
const LLVMValueRef *coords,
LLVMValueRef explicit_lod,
const LLVMValueRef *offsets,
lp_build_get_mip_offsets(bld, ilevel));
}
+ if (bld->fetch_ms) {
+ LLVMValueRef num_samples;
+ num_samples = bld->dynamic_state->num_samples(bld->dynamic_state, bld->gallivm,
+ bld->context_ptr, texture_unit);
+ out1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, ms_index, int_coord_bld->zero);
+ out_of_bounds = lp_build_or(int_coord_bld, out_of_bounds, out1);
+ out1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, ms_index, lp_build_broadcast_scalar(int_coord_bld, num_samples));
+ out_of_bounds = lp_build_or(int_coord_bld, out_of_bounds, out1);
+ offset = lp_build_add(int_coord_bld, offset,
+ lp_build_mul(int_coord_bld, bld->sample_stride, ms_index));
+ }
+
offset = lp_build_andnot(int_coord_bld, offset, out_of_bounds);
lp_build_fetch_rgba_soa(bld->gallivm,
const LLVMValueRef *offsets,
const struct lp_derivatives *derivs, /* optional */
LLVMValueRef lod, /* optional */
+ LLVMValueRef ms_index, /* optional */
LLVMValueRef texel_out[4])
{
unsigned target = static_texture_state->target;
enum lp_sampler_op_type op_type;
LLVMValueRef lod_bias = NULL;
LLVMValueRef explicit_lod = NULL;
- boolean op_is_tex, op_is_lodq, op_is_gather;
+ boolean op_is_tex, op_is_lodq, op_is_gather, fetch_ms;
if (0) {
enum pipe_format fmt = static_texture_state->format;
LP_SAMPLER_LOD_CONTROL_SHIFT;
op_type = (sample_key & LP_SAMPLER_OP_TYPE_MASK) >>
LP_SAMPLER_OP_TYPE_SHIFT;
+ fetch_ms = !!(sample_key & LP_SAMPLER_FETCH_MS);
op_is_tex = op_type == LP_SAMPLER_OP_TEXTURE;
op_is_lodq = op_type == LP_SAMPLER_OP_LODQ;
bld.num_lods = num_quads;
}
+ bld.fetch_ms = fetch_ms;
if (op_is_gather)
bld.gather_comp = (sample_key & LP_SAMPLER_GATHER_COMP_MASK) >> LP_SAMPLER_GATHER_COMP_SHIFT;
bld.lodf_type = type;
context_ptr, texture_index);
bld.mip_offsets = dynamic_state->mip_offsets(dynamic_state, gallivm,
context_ptr, texture_index);
+
+ if (fetch_ms)
+ bld.sample_stride = lp_build_broadcast_scalar(&bld.int_coord_bld, dynamic_state->sample_stride(dynamic_state, gallivm,
+ context_ptr, texture_index));
/* Note that mip_offsets is an array[level] of offsets to texture images */
if (dynamic_state->cache_ptr && thread_data_ptr) {
}
else if (op_type == LP_SAMPLER_OP_FETCH) {
- lp_build_fetch_texel(&bld, texture_index, newcoords,
+ lp_build_fetch_texel(&bld, texture_index, ms_index, newcoords,
lod, offsets,
texel_out);
}
LLVMValueRef coords[5];
LLVMValueRef offsets[3] = { NULL };
LLVMValueRef lod = NULL;
+ LLVMValueRef ms_index = NULL;
LLVMValueRef context_ptr;
LLVMValueRef thread_data_ptr = NULL;
LLVMValueRef texel_out[4];
if (sample_key & LP_SAMPLER_SHADOW) {
coords[4] = LLVMGetParam(function, num_param++);
}
+ if (sample_key & LP_SAMPLER_FETCH_MS) {
+ ms_index = LLVMGetParam(function, num_param++);
+ }
if (sample_key & LP_SAMPLER_OFFSETS) {
for (i = 0; i < num_offsets; i++) {
offsets[i] = LLVMGetParam(function, num_param++);
offsets,
deriv_ptr,
lod,
+ ms_index,
texel_out);
LLVMBuildAggregateRet(gallivm->builder, texel_out, 4);
if (sample_key & LP_SAMPLER_SHADOW) {
arg_types[num_param++] = LLVMTypeOf(coords[0]);
}
+ if (sample_key & LP_SAMPLER_FETCH_MS) {
+ arg_types[num_param++] = LLVMTypeOf(params->ms_index);
+ }
if (sample_key & LP_SAMPLER_OFFSETS) {
for (i = 0; i < num_offsets; i++) {
arg_types[num_param++] = LLVMTypeOf(offsets[0]);
if (sample_key & LP_SAMPLER_SHADOW) {
args[num_args++] = coords[4];
}
+ if (sample_key & LP_SAMPLER_FETCH_MS) {
+ args[num_args++] = params->ms_index;
+ }
if (sample_key & LP_SAMPLER_OFFSETS) {
for (i = 0; i < num_offsets; i++) {
args[num_args++] = offsets[i];
params->offsets,
params->derivs,
params->lod,
+ params->ms_index,
params->texel);
}
}