llvmpipe: Remove the static interpolation.

No longer used.

If we ever want the old behavior we can run a loop unroller pass.

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
This commit is contained in:
José Fonseca 2013-04-18 10:33:09 +01:00
parent 6e833d4d09
commit b191be52f2
3 changed files with 19 additions and 384 deletions

View file

@ -237,7 +237,6 @@ coeffs_init_simple(struct lp_build_interp_soa_context *bld,
static void
attribs_update_simple(struct lp_build_interp_soa_context *bld,
struct gallivm_state *gallivm,
int quad_start_index,
LLVMValueRef loop_iter,
int start,
int end)
@ -249,20 +248,15 @@ attribs_update_simple(struct lp_build_interp_soa_context *bld,
unsigned attrib;
LLVMValueRef pixoffx;
LLVMValueRef pixoffy;
LLVMValueRef ptr;
/* could do this with code-generated passed in pixel offsets too */
if (bld->dynamic_offsets) {
LLVMValueRef ptr;
assert(loop_iter);
ptr = LLVMBuildGEP(builder, bld->xoffset_store, &loop_iter, 1, "");
pixoffx = LLVMBuildLoad(builder, ptr, "");
ptr = LLVMBuildGEP(builder, bld->yoffset_store, &loop_iter, 1, "");
pixoffy = LLVMBuildLoad(builder, ptr, "");
}
else {
calc_offsets(coeff_bld, quad_start_index, &pixoffx, &pixoffy);
}
assert(loop_iter);
ptr = LLVMBuildGEP(builder, bld->xoffset_store, &loop_iter, 1, "");
pixoffx = LLVMBuildLoad(builder, ptr, "");
ptr = LLVMBuildGEP(builder, bld->yoffset_store, &loop_iter, 1, "");
pixoffy = LLVMBuildLoad(builder, ptr, "");
pixoffx = LLVMBuildFAdd(builder, pixoffx,
lp_build_broadcast_scalar(coeff_bld, bld->x), "");
@ -527,14 +521,9 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
attrib_name(a, attrib, chan, ".a");
attrib_name(dadq, attrib, chan, ".dadq");
if (bld->dynamic_offsets) {
bld->a[attrib][chan] = lp_build_alloca(gallivm,
LLVMTypeOf(a), "");
LLVMBuildStore(builder, a, bld->a[attrib][chan]);
}
else {
bld->a[attrib][chan] = a;
}
bld->a[attrib][chan] = lp_build_alloca(gallivm,
LLVMTypeOf(a), "");
LLVMBuildStore(builder, a, bld->a[attrib][chan]);
bld->dadq[attrib][chan] = dadq;
}
}
@ -549,20 +538,16 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
static void
attribs_update(struct lp_build_interp_soa_context *bld,
struct gallivm_state *gallivm,
int quad_start_index,
LLVMValueRef loop_iter,
int start,
int end)
{
LLVMBuilderRef builder = gallivm->builder;
struct lp_build_context *coeff_bld = &bld->coeff_bld;
LLVMValueRef shuffle = lp_build_const_int_vec(gallivm, coeff_bld->type, quad_start_index);
LLVMValueRef oow = NULL;
unsigned attrib;
unsigned chan;
assert(quad_start_index < 4);
for(attrib = start; attrib < end; ++attrib) {
const unsigned mask = bld->mask[attrib];
const unsigned interp = bld->interp[attrib];
@ -571,10 +556,7 @@ attribs_update(struct lp_build_interp_soa_context *bld,
LLVMValueRef a;
if (interp == LP_INTERP_CONSTANT ||
interp == LP_INTERP_FACING) {
a = bld->a[attrib][chan];
if (bld->dynamic_offsets) {
a = LLVMBuildLoad(builder, a, "");
}
a = LLVMBuildLoad(builder, bld->a[attrib][chan], "");
}
else if (interp == LP_INTERP_POSITION) {
assert(attrib > 0);
@ -589,7 +571,7 @@ attribs_update(struct lp_build_interp_soa_context *bld,
* Broadcast the attribute value for this quad into all elements
*/
if (bld->dynamic_offsets) {
{
/* stored as vector load as float */
LLVMTypeRef ptr_type = LLVMPointerType(LLVMFloatTypeInContext(
gallivm->context), 0);
@ -599,10 +581,6 @@ attribs_update(struct lp_build_interp_soa_context *bld,
a = LLVMBuildLoad(builder, ptr, "");
a = lp_build_broadcast_scalar(&bld->coeff_bld, a);
}
else {
a = LLVMBuildShuffleVector(builder,
a, coeff_bld->undef, shuffle, "");
}
/*
* Get the derivatives.
@ -691,7 +669,6 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
const struct lp_shader_input *inputs,
LLVMBuilderRef builder,
struct lp_type type,
boolean dynamic_offsets,
LLVMValueRef a0_ptr,
LLVMValueRef dadx_ptr,
LLVMValueRef dady_ptr,
@ -750,14 +727,13 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
if (coeff_type.length > 4) {
bld->simple_interp = TRUE;
if (dynamic_offsets) {
/* XXX this should use a global static table */
{
/* XXX this should use a global static table */
unsigned i;
unsigned num_loops = 16 / type.length;
LLVMValueRef pixoffx, pixoffy, index;
LLVMValueRef ptr;
bld->dynamic_offsets = TRUE;
bld->xoffset_store = lp_build_array_alloca(gallivm,
lp_build_vec_type(gallivm, type),
lp_build_const_int32(gallivm, num_loops),
@ -779,47 +755,15 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
}
else {
bld->simple_interp = FALSE;
if (dynamic_offsets) {
bld->dynamic_offsets = TRUE;
}
coeffs_init(bld, a0_ptr, dadx_ptr, dady_ptr);
}
}
/**
/*
* Advance the position and inputs to the given quad within the block.
*/
void
lp_build_interp_soa_update_inputs(struct lp_build_interp_soa_context *bld,
struct gallivm_state *gallivm,
int quad_start_index)
{
assert(quad_start_index < 4);
if (bld->simple_interp) {
attribs_update_simple(bld, gallivm, quad_start_index, NULL, 1, bld->num_attribs);
}
else {
attribs_update(bld, gallivm, quad_start_index, NULL, 1, bld->num_attribs);
}
}
void
lp_build_interp_soa_update_pos(struct lp_build_interp_soa_context *bld,
struct gallivm_state *gallivm,
int quad_start_index)
{
assert(quad_start_index < 4);
if (bld->simple_interp) {
attribs_update_simple(bld, gallivm, quad_start_index, NULL, 0, 1);
}
else {
attribs_update(bld, gallivm, quad_start_index, NULL, 0, 1);
}
}
void
lp_build_interp_soa_update_inputs_dyn(struct lp_build_interp_soa_context *bld,
@ -827,10 +771,10 @@ lp_build_interp_soa_update_inputs_dyn(struct lp_build_interp_soa_context *bld,
LLVMValueRef quad_start_index)
{
if (bld->simple_interp) {
attribs_update_simple(bld, gallivm, 0, quad_start_index, 1, bld->num_attribs);
attribs_update_simple(bld, gallivm, quad_start_index, 1, bld->num_attribs);
}
else {
attribs_update(bld, gallivm, 0, quad_start_index, 1, bld->num_attribs);
attribs_update(bld, gallivm, quad_start_index, 1, bld->num_attribs);
}
}
@ -840,10 +784,10 @@ lp_build_interp_soa_update_pos_dyn(struct lp_build_interp_soa_context *bld,
LLVMValueRef quad_start_index)
{
if (bld->simple_interp) {
attribs_update_simple(bld, gallivm, 0, quad_start_index, 0, 1);
attribs_update_simple(bld, gallivm, quad_start_index, 0, 1);
}
else {
attribs_update(bld, gallivm, 0, quad_start_index, 0, 1);
attribs_update(bld, gallivm, quad_start_index, 0, 1);
}
}

View file

@ -85,7 +85,6 @@ struct lp_build_interp_soa_context
unsigned mask[1 + PIPE_MAX_SHADER_INPUTS]; /**< TGSI_WRITE_MASK_x */
enum lp_interp interp[1 + PIPE_MAX_SHADER_INPUTS];
boolean simple_interp;
boolean dynamic_offsets;
LLVMValueRef x;
LLVMValueRef y;
@ -96,8 +95,6 @@ struct lp_build_interp_soa_context
LLVMValueRef dadxaos[1 + PIPE_MAX_SHADER_INPUTS];
LLVMValueRef dadyaos[1 + PIPE_MAX_SHADER_INPUTS];
LLVMValueRef oow;
LLVMValueRef attribs[1 + PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS];
LLVMValueRef xoffset_store;
@ -118,23 +115,12 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
const struct lp_shader_input *inputs,
LLVMBuilderRef builder,
struct lp_type type,
boolean dynamic_offsets,
LLVMValueRef a0_ptr,
LLVMValueRef dadx_ptr,
LLVMValueRef dady_ptr,
LLVMValueRef x,
LLVMValueRef y);
void
lp_build_interp_soa_update_inputs(struct lp_build_interp_soa_context *bld,
struct gallivm_state *gallivm,
int quad_start_index);
void
lp_build_interp_soa_update_pos(struct lp_build_interp_soa_context *bld,
struct gallivm_state *gallivm,
int quad__start_index);
void
lp_build_interp_soa_update_inputs_dyn(struct lp_build_interp_soa_context *bld,
struct gallivm_state *gallivm,

View file

@ -213,245 +213,6 @@ find_output_by_semantic( const struct tgsi_shader_info *info,
}
/**
* Generate the fragment shader, depth/stencil test, and alpha tests.
* \param i which quad in the tile, in range [0,3]
* \param partial_mask if 1, do mask_input testing
*/
static void
generate_fs(struct gallivm_state *gallivm,
struct lp_fragment_shader *shader,
const struct lp_fragment_shader_variant_key *key,
LLVMBuilderRef builder,
struct lp_type type,
LLVMValueRef context_ptr,
unsigned i,
struct lp_build_interp_soa_context *interp,
struct lp_build_sampler_soa *sampler,
LLVMValueRef *pmask,
LLVMValueRef (*color)[4],
LLVMValueRef depth_ptr,
LLVMValueRef facing,
unsigned partial_mask,
LLVMValueRef mask_input,
LLVMValueRef thread_data_ptr)
{
const struct util_format_description *zs_format_desc = NULL;
const struct tgsi_token *tokens = shader->base.tokens;
LLVMTypeRef vec_type;
LLVMValueRef consts_ptr;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS];
LLVMValueRef z;
LLVMValueRef zs_value = NULL;
LLVMValueRef stencil_refs[2];
struct lp_build_mask_context mask;
boolean simple_shader = (shader->info.base.file_count[TGSI_FILE_SAMPLER] == 0 &&
shader->info.base.num_inputs < 3 &&
shader->info.base.num_instructions < 8);
const boolean dual_source_blend = key->blend.rt[0].blend_enable &&
util_blend_state_is_dual(&key->blend, 0);
unsigned attrib;
unsigned chan;
unsigned cbuf;
unsigned depth_mode;
struct lp_bld_tgsi_system_values system_values;
memset(&system_values, 0, sizeof(system_values));
if (key->depth.enabled ||
key->stencil[0].enabled ||
key->stencil[1].enabled) {
zs_format_desc = util_format_description(key->zsbuf_format);
assert(zs_format_desc);
if (!shader->info.base.writes_z) {
if (key->alpha.enabled || shader->info.base.uses_kill)
/* With alpha test and kill, can do the depth test early
* and hopefully eliminate some quads. But need to do a
* special deferred depth write once the final mask value
* is known.
*/
depth_mode = EARLY_DEPTH_TEST | LATE_DEPTH_WRITE;
else
depth_mode = EARLY_DEPTH_TEST | EARLY_DEPTH_WRITE;
}
else {
depth_mode = LATE_DEPTH_TEST | LATE_DEPTH_WRITE;
}
if (!(key->depth.enabled && key->depth.writemask) &&
!(key->stencil[0].enabled && key->stencil[0].writemask))
depth_mode &= ~(LATE_DEPTH_WRITE | EARLY_DEPTH_WRITE);
}
else {
depth_mode = 0;
}
assert(i < 4);
stencil_refs[0] = lp_jit_context_stencil_ref_front_value(gallivm, context_ptr);
stencil_refs[1] = lp_jit_context_stencil_ref_back_value(gallivm, context_ptr);
vec_type = lp_build_vec_type(gallivm, type);
consts_ptr = lp_jit_context_constants(gallivm, context_ptr);
memset(outputs, 0, sizeof outputs);
/* Declare the color and z variables */
for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
for(chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
color[cbuf][chan] = lp_build_alloca(gallivm, vec_type, "color");
}
}
if (dual_source_blend) {
assert(key->nr_cbufs <= 1);
for(chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
color[1][chan] = lp_build_alloca(gallivm, vec_type, "color1");
}
}
/* do triangle edge testing */
if (partial_mask) {
*pmask = generate_quad_mask(gallivm, type,
i*type.length/4, mask_input);
}
else {
*pmask = lp_build_const_int_vec(gallivm, type, ~0);
}
/* 'mask' will control execution based on quad's pixel alive/killed state */
lp_build_mask_begin(&mask, gallivm, type, *pmask);
if (!(depth_mode & EARLY_DEPTH_TEST) && !simple_shader)
lp_build_mask_check(&mask);
lp_build_interp_soa_update_pos(interp, gallivm, i*type.length/4);
z = interp->pos[2];
if (depth_mode & EARLY_DEPTH_TEST) {
lp_build_depth_stencil_test(gallivm,
&key->depth,
key->stencil,
type,
zs_format_desc,
&mask,
stencil_refs,
z,
depth_ptr, facing,
&zs_value,
!simple_shader);
if (depth_mode & EARLY_DEPTH_WRITE) {
lp_build_depth_write(gallivm, type, zs_format_desc, depth_ptr, zs_value);
}
}
lp_build_interp_soa_update_inputs(interp, gallivm, i*type.length/4);
/* Build the actual shader */
lp_build_tgsi_soa(gallivm, tokens, type, &mask,
consts_ptr, &system_values,
interp->inputs,
outputs, sampler, &shader->info.base, NULL);
/* Alpha test */
if (key->alpha.enabled) {
int color0 = find_output_by_semantic(&shader->info.base,
TGSI_SEMANTIC_COLOR,
0);
if (color0 != -1 && outputs[color0][3]) {
const struct util_format_description *cbuf_format_desc;
LLVMValueRef alpha = LLVMBuildLoad(builder, outputs[color0][3], "alpha");
LLVMValueRef alpha_ref_value;
alpha_ref_value = lp_jit_context_alpha_ref_value(gallivm, context_ptr);
alpha_ref_value = lp_build_broadcast(gallivm, vec_type, alpha_ref_value);
cbuf_format_desc = util_format_description(key->cbuf_format[0]);
lp_build_alpha_test(gallivm, key->alpha.func, type, cbuf_format_desc,
&mask, alpha, alpha_ref_value,
(depth_mode & LATE_DEPTH_TEST) != 0);
}
}
/* Late Z test */
if (depth_mode & LATE_DEPTH_TEST) {
int pos0 = find_output_by_semantic(&shader->info.base,
TGSI_SEMANTIC_POSITION,
0);
if (pos0 != -1 && outputs[pos0][2]) {
z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z");
}
lp_build_depth_stencil_test(gallivm,
&key->depth,
key->stencil,
type,
zs_format_desc,
&mask,
stencil_refs,
z,
depth_ptr, facing,
&zs_value,
!simple_shader);
/* Late Z write */
if (depth_mode & LATE_DEPTH_WRITE) {
lp_build_depth_write(gallivm, type, zs_format_desc, depth_ptr, zs_value);
}
}
else if ((depth_mode & EARLY_DEPTH_TEST) &&
(depth_mode & LATE_DEPTH_WRITE))
{
/* Need to apply a reduced mask to the depth write. Reload the
* depth value, update from zs_value with the new mask value and
* write that out.
*/
lp_build_deferred_depth_write(gallivm,
type,
zs_format_desc,
&mask,
depth_ptr,
zs_value);
}
/* Color write */
for (attrib = 0; attrib < shader->info.base.num_outputs; ++attrib)
{
unsigned cbuf = shader->info.base.output_semantic_index[attrib];
if ((shader->info.base.output_semantic_name[attrib] == TGSI_SEMANTIC_COLOR) &&
((cbuf < key->nr_cbufs) || (cbuf == 1 && dual_source_blend)))
{
unsigned cbuf = shader->info.base.output_semantic_index[attrib];
for(chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
if(outputs[attrib][chan]) {
/* XXX: just initialize outputs to point at colors[] and
* skip this.
*/
LLVMValueRef out = LLVMBuildLoad(builder, outputs[attrib][chan], "");
lp_build_name(out, "color%u.%u.%c", i, attrib, "rgba"[chan]);
LLVMBuildStore(builder, out, color[cbuf][chan]);
}
}
}
}
if (key->occlusion_count) {
LLVMValueRef counter = lp_jit_thread_data_counter(gallivm, thread_data_ptr);
lp_build_name(counter, "counter");
lp_build_occlusion_count(gallivm, type,
lp_build_mask_value(&mask), counter);
}
*pmask = lp_build_mask_end(&mask);
}
/**
* Generate the fragment shader, depth/stencil test, and alpha tests.
*/
@ -2017,7 +1778,6 @@ generate_fragment(struct llvmpipe_context *lp,
unsigned chan;
unsigned cbuf;
boolean cbuf0_write_all;
boolean try_loop = TRUE;
const boolean dual_source_blend = key->blend.rt[0].blend_enable &&
util_blend_state_is_dual(&key->blend, 0);
@ -2142,61 +1902,7 @@ generate_fragment(struct llvmpipe_context *lp,
zs_format_desc = util_format_description(key->zsbuf_format);
if (!try_loop) {
/*
* The shader input interpolation info is not explicitely baked in the
* shader key, but everything it derives from (TGSI, and flatshade) is
* already included in the shader key.
*/
lp_build_interp_soa_init(&interp,
gallivm,
shader->info.base.num_inputs,
inputs,
builder, fs_type,
FALSE,
a0_ptr, dadx_ptr, dady_ptr,
x, y);
/* loop over quads in the block */
for(i = 0; i < num_fs; ++i) {
LLVMValueRef depth_offset = LLVMConstInt(int32_type,
i*fs_type.length*zs_format_desc->block.bits/8,
0);
LLVMValueRef out_color[PIPE_MAX_COLOR_BUFS][TGSI_NUM_CHANNELS];
LLVMValueRef depth_ptr_i;
depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &depth_offset, 1, "");
generate_fs(gallivm,
shader, key,
builder,
fs_type,
context_ptr,
i,
&interp,
sampler,
&fs_mask[i], /* output */
out_color,
depth_ptr_i,
facing,
partial_mask,
mask_input,
thread_data_ptr);
for (cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan)
fs_out_color[cbuf][chan][i] =
out_color[cbuf * !cbuf0_write_all][chan];
}
if (dual_source_blend) {
/* only support one dual source blend target hence always use output 1 */
for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan)
fs_out_color[1][chan][i] =
out_color[1][chan];
}
}
}
else {
{
unsigned depth_bits = zs_format_desc->block.bits/8;
LLVMValueRef num_loop = lp_build_const_int32(gallivm, num_fs);
LLVMTypeRef mask_type = lp_build_int_vec_type(gallivm, fs_type);
@ -2214,7 +1920,6 @@ generate_fragment(struct llvmpipe_context *lp,
shader->info.base.num_inputs,
inputs,
builder, fs_type,
TRUE,
a0_ptr, dadx_ptr, dady_ptr,
x, y);