summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_shader.c60
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_shader.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c9
-rw-r--r--src/gallium/drivers/radeonsi/si_state.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_state_draw.c19
5 files changed, 75 insertions, 15 deletions
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c
index 32755127b58..aec5c2ea222 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c
@@ -320,16 +320,59 @@ static void declare_input_fs(
}
/* XXX: Could there be more than TGSI_NUM_CHANNELS (4) ? */
- for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+ if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
+ si_shader_ctx->key.color_two_side) {
LLVMValueRef args[3];
- LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
- unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
- args[0] = llvm_chan;
- args[1] = attr_number;
+ LLVMValueRef face, is_face_positive;
+ LLVMValueRef back_attr_number =
+ lp_build_const_int32(gallivm,
+ shader->input[input_index].param_offset + 1);
+
+ face = build_intrinsic(gallivm->builder,
+ "llvm.SI.fs.read.face",
+ input_type,
+ NULL, 0, LLVMReadNoneAttribute);
+ is_face_positive = LLVMBuildFCmp(gallivm->builder,
+ LLVMRealUGT, face,
+ lp_build_const_float(gallivm, 0.0f),
+ "");
+
args[2] = params;
- si_shader_ctx->radeon_bld.inputs[soa_index] =
- build_intrinsic(base->gallivm->builder, intr_name,
- input_type, args, 3, LLVMReadOnlyAttribute);
+ for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+ LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
+ unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
+ LLVMValueRef front, back;
+
+ args[0] = llvm_chan;
+ args[1] = attr_number;
+ front = build_intrinsic(base->gallivm->builder, intr_name,
+ input_type, args, 3, LLVMReadOnlyAttribute);
+
+ args[1] = back_attr_number;
+ back = build_intrinsic(base->gallivm->builder, intr_name,
+ input_type, args, 3, LLVMReadOnlyAttribute);
+
+ si_shader_ctx->radeon_bld.inputs[soa_index] =
+ LLVMBuildSelect(gallivm->builder,
+ is_face_positive,
+ front,
+ back,
+ "");
+ }
+
+ shader->ninterp++;
+ } else {
+ for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+ LLVMValueRef args[3];
+ LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
+ unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
+ args[0] = llvm_chan;
+ args[1] = attr_number;
+ args[2] = params;
+ si_shader_ctx->radeon_bld.inputs[soa_index] =
+ build_intrinsic(base->gallivm->builder, intr_name,
+ input_type, args, 3, LLVMReadOnlyAttribute);
+ }
}
}
@@ -530,6 +573,7 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
break;
case TGSI_SEMANTIC_COLOR:
if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
+ case TGSI_SEMANTIC_BCOLOR:
target = V_008DFC_SQ_EXP_PARAM + param_count;
shader->output[i].param_offset = param_count;
param_count++;
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.h b/src/gallium/drivers/radeonsi/radeonsi_shader.h
index 9d382d56286..23030bc4f63 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.h
@@ -80,6 +80,7 @@ struct si_shader {
struct si_shader_key {
unsigned export_16bpc:8;
unsigned nr_cbufs:4;
+ unsigned color_two_side:1;
};
struct si_pipe_shader {
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 20f4be3d8f2..66f0bd886fe 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -379,6 +379,8 @@ static void *si_create_rs_state(struct pipe_context *ctx,
return NULL;
}
+ rs->two_side = state->light_twoside;
+
polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
state->fill_back != PIPE_POLYGON_MODE_FILL);
@@ -1841,9 +1843,10 @@ static INLINE struct si_shader_key si_shader_selector_key(struct pipe_context *c
if (sel->fs_write_all)
key.nr_cbufs = rctx->framebuffer.nr_cbufs;
key.export_16bpc = rctx->export_16bpc;
- /*if (rctx->queued.named.rasterizer)
- key.flatshade = rctx->queued.named.rasterizer->flatshade;*/
- /*key.color_two_side |== rctx->two_side;*/
+ if (rctx->queued.named.rasterizer) {
+ key.color_two_side = rctx->queued.named.rasterizer->two_side;
+ /*key.flatshade = rctx->queued.named.rasterizer->flatshade;*/
+ }
}
return key;
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index 136ac861e2f..8f1ab438fff 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -43,6 +43,7 @@ struct si_state_viewport {
struct si_state_rasterizer {
struct si_pm4_state pm4;
bool flatshade;
+ bool two_side;
unsigned sprite_coord_enable;
unsigned pa_sc_line_stipple;
unsigned pa_su_sc_mode_cntl;
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index 629ec03e2fb..3ac80b0a6e4 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -328,11 +328,15 @@ static void si_update_spi_map(struct r600_context *rctx)
unsigned i, j, tmp;
for (i = 0; i < ps->ninput; i++) {
+ unsigned name = ps->input[i].name;
+ unsigned param_offset = ps->input[i].param_offset;
+
+bcolor:
tmp = 0;
#if 0
/* XXX: Flat shading hangs the GPU */
- if (ps->input[i].name == TGSI_SEMANTIC_POSITION ||
+ if (name == TGSI_SEMANTIC_POSITION ||
ps->input[i].interpolate == TGSI_INTERPOLATE_CONSTANT ||
(ps->input[i].interpolate == TGSI_INTERPOLATE_COLOR &&
rctx->rasterizer && rctx->rasterizer->flatshade)) {
@@ -340,13 +344,13 @@ static void si_update_spi_map(struct r600_context *rctx)
}
#endif
- if (ps->input[i].name == TGSI_SEMANTIC_GENERIC &&
+ if (name == TGSI_SEMANTIC_GENERIC &&
rctx->sprite_coord_enable & (1 << ps->input[i].sid)) {
tmp |= S_028644_PT_SPRITE_TEX(1);
}
for (j = 0; j < vs->noutput; j++) {
- if (ps->input[i].name == vs->output[j].name &&
+ if (name == vs->output[j].name &&
ps->input[i].sid == vs->output[j].sid) {
tmp |= S_028644_OFFSET(vs->output[j].param_offset);
break;
@@ -359,8 +363,15 @@ static void si_update_spi_map(struct r600_context *rctx)
}
si_pm4_set_reg(pm4,
- R_028644_SPI_PS_INPUT_CNTL_0 + ps->input[i].param_offset * 4,
+ R_028644_SPI_PS_INPUT_CNTL_0 + param_offset * 4,
tmp);
+
+ if (name == TGSI_SEMANTIC_COLOR &&
+ rctx->ps_shader->current->key.color_two_side) {
+ name = TGSI_SEMANTIC_BCOLOR;
+ param_offset++;
+ goto bcolor;
+ }
}
si_pm4_set_state(rctx, spi, pm4);