mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 15:10:10 +01:00
gallivm: add indirect texture switch statement builder.
This adds the apis to add an indirect accessor for arrays of textures, using an LLVM switch statement and per-texture sampler functions. It also adds the indexer to the sampler parameters Reviewed-by: Roland Scheidegger <sroland@vmware.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3778>
This commit is contained in:
parent
8b15a08ebd
commit
28f906ad91
2 changed files with 119 additions and 0 deletions
|
|
@ -105,6 +105,7 @@ struct lp_sampler_params
|
|||
struct lp_type type;
|
||||
unsigned texture_index;
|
||||
unsigned sampler_index;
|
||||
LLVMValueRef texture_index_offset;
|
||||
unsigned sample_key;
|
||||
LLVMValueRef context_ptr;
|
||||
LLVMValueRef thread_data_ptr;
|
||||
|
|
@ -120,6 +121,7 @@ struct lp_sampler_size_query_params
|
|||
{
|
||||
struct lp_type int_type;
|
||||
unsigned texture_unit;
|
||||
LLVMValueRef texture_unit_offset;
|
||||
unsigned target;
|
||||
LLVMValueRef context_ptr;
|
||||
boolean is_sviewinfo;
|
||||
|
|
@ -442,6 +444,20 @@ struct lp_build_sample_context
|
|||
LLVMValueRef context_ptr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Indirect texture access context
|
||||
*
|
||||
* This is used to store info across building
|
||||
* and indirect texture switch statement.
|
||||
*/
|
||||
struct lp_build_sample_array_switch {
|
||||
struct gallivm_state *gallivm;
|
||||
struct lp_sampler_params params;
|
||||
unsigned base, range;
|
||||
LLVMValueRef switch_ref;
|
||||
LLVMBasicBlockRef merge_ref;
|
||||
LLVMValueRef phi;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -693,6 +709,21 @@ lp_build_img_op_soa(const struct lp_static_texture_state *static_texture_state,
|
|||
struct gallivm_state *gallivm,
|
||||
const struct lp_img_params *params);
|
||||
|
||||
void
|
||||
lp_build_sample_array_init_soa(struct lp_build_sample_array_switch *switch_info,
|
||||
struct gallivm_state *gallivm,
|
||||
const struct lp_sampler_params *params,
|
||||
LLVMValueRef idx,
|
||||
unsigned base, unsigned range);
|
||||
|
||||
void
|
||||
lp_build_sample_array_case_soa(struct lp_build_sample_array_switch *switch_info,
|
||||
int idx,
|
||||
const struct lp_static_texture_state *static_texture_state,
|
||||
const struct lp_static_sampler_state *static_sampler_state,
|
||||
struct lp_sampler_dynamic_state *dynamic_texture_state);
|
||||
|
||||
void lp_build_sample_array_fini_soa(struct lp_build_sample_array_switch *switch_info);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4228,3 +4228,91 @@ lp_build_img_op_soa(const struct lp_static_texture_state *static_texture_state,
|
|||
params->img_op, params->op, params->indata, params->indata2, params->outdata);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions are for indirect texture access suppoort.
|
||||
*
|
||||
* Indirect textures are implemented using a switch statement, that
|
||||
* takes the texture index and jumps to the sampler functions for
|
||||
* that texture unit.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialise an indexed sampler switch block.
|
||||
*
|
||||
* This sets up the switch_info state and adds the LLVM flow control pieces.
|
||||
*/
|
||||
void
|
||||
lp_build_sample_array_init_soa(struct lp_build_sample_array_switch *switch_info,
|
||||
struct gallivm_state *gallivm,
|
||||
const struct lp_sampler_params *params,
|
||||
LLVMValueRef idx,
|
||||
unsigned base, unsigned range)
|
||||
{
|
||||
switch_info->gallivm = gallivm;
|
||||
switch_info->params = *params;
|
||||
switch_info->base = base;
|
||||
switch_info->range = range;
|
||||
|
||||
/* for generating the switch functions we don't want the texture index offset */
|
||||
switch_info->params.texture_index_offset = 0;
|
||||
|
||||
LLVMBasicBlockRef initial_block = LLVMGetInsertBlock(gallivm->builder);
|
||||
switch_info->merge_ref = lp_build_insert_new_block(gallivm, "texmerge");
|
||||
|
||||
switch_info->switch_ref = LLVMBuildSwitch(gallivm->builder, idx,
|
||||
switch_info->merge_ref, range - base);
|
||||
|
||||
LLVMTypeRef val_type[4];
|
||||
val_type[0] = val_type[1] = val_type[2] = val_type[3] =
|
||||
lp_build_vec_type(gallivm, params->type);
|
||||
LLVMTypeRef ret_type = LLVMStructTypeInContext(gallivm->context, val_type, 4, 0);
|
||||
|
||||
LLVMValueRef undef_val = LLVMGetUndef(ret_type);
|
||||
|
||||
LLVMPositionBuilderAtEnd(gallivm->builder, switch_info->merge_ref);
|
||||
|
||||
switch_info->phi = LLVMBuildPhi(gallivm->builder, ret_type, "");
|
||||
LLVMAddIncoming(switch_info->phi, &undef_val, &initial_block, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an individual entry to the indirect texture switch.
|
||||
*
|
||||
* This builds the sample function and links a case for it into the switch statement.
|
||||
*/
|
||||
void
|
||||
lp_build_sample_array_case_soa(struct lp_build_sample_array_switch *switch_info,
|
||||
int idx,
|
||||
const struct lp_static_texture_state *static_texture_state,
|
||||
const struct lp_static_sampler_state *static_sampler_state,
|
||||
struct lp_sampler_dynamic_state *dynamic_texture_state)
|
||||
{
|
||||
struct gallivm_state *gallivm = switch_info->gallivm;
|
||||
LLVMBasicBlockRef this_block = lp_build_insert_new_block(gallivm, "texblock");
|
||||
LLVMValueRef tex_ret;
|
||||
|
||||
LLVMAddCase(switch_info->switch_ref, LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), idx, 0), this_block);
|
||||
LLVMPositionBuilderAtEnd(gallivm->builder, this_block);
|
||||
|
||||
lp_build_sample_soa_func(gallivm, static_texture_state,
|
||||
static_sampler_state, dynamic_texture_state, &switch_info->params, idx, idx,
|
||||
&tex_ret);
|
||||
|
||||
LLVMAddIncoming(switch_info->phi, &tex_ret, &this_block, 1);
|
||||
LLVMBuildBr(gallivm->builder, switch_info->merge_ref);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish a switch statement.
|
||||
*
|
||||
* This handles extract the results from the switch.
|
||||
*/
|
||||
void lp_build_sample_array_fini_soa(struct lp_build_sample_array_switch *switch_info)
|
||||
{
|
||||
struct gallivm_state *gallivm = switch_info->gallivm;
|
||||
|
||||
LLVMPositionBuilderAtEnd(gallivm->builder, switch_info->merge_ref);
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
switch_info->params.texel[i] = LLVMBuildExtractValue(gallivm->builder, switch_info->phi, i, "");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue