diff options
Diffstat (limited to 'src/gallium/drivers/radeonsi')
-rw-r--r-- | src/gallium/drivers/radeonsi/radeonsi_shader.c | 60 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/radeonsi_shader.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.c | 9 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state_draw.c | 19 |
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); |