From d52791a708760dd114a53137caad211dc7cc4dfc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 21 Nov 2013 15:21:38 +0100 Subject: [PATCH] radeonsi: add driver support for layered rendering and AMD_vertex_shader_layer MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Michel Dänzer --- .../drivers/radeonsi/radeonsi_shader.c | 14 ++++++++++- .../drivers/radeonsi/radeonsi_shader.h | 1 + src/gallium/drivers/radeonsi/si_state.c | 23 ++++++++++--------- src/gallium/drivers/radeonsi/si_state_draw.c | 1 + 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c index ebe9125c3ea..96cc1aaa6e6 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_shader.c +++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c @@ -890,6 +890,7 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base) unsigned semantic_name; unsigned param_count = 0; int depth_index = -1, stencil_index = -1, psize_index = -1, edgeflag_index = -1; + int layer_index = -1; int i; if (si_shader_ctx->shader->selector->so.num_outputs) { @@ -949,6 +950,11 @@ handle_semantic: shader->vs_out_edgeflag = true; edgeflag_index = index; continue; + case TGSI_SEMANTIC_LAYER: + shader->vs_out_misc_write = true; + shader->vs_out_layer = true; + layer_index = index; + continue; case TGSI_SEMANTIC_POSITION: if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) { target = V_008DFC_SQ_EXP_POS; @@ -1100,7 +1106,8 @@ handle_semantic: if (shader->vs_out_misc_write) { pos_args[1][0] = lp_build_const_int32(base->gallivm, /* writemask */ shader->vs_out_point_size | - (shader->vs_out_edgeflag << 1)); + (shader->vs_out_edgeflag << 1) | + (shader->vs_out_layer << 2)); pos_args[1][1] = uint->zero; /* EXEC mask */ pos_args[1][2] = uint->zero; /* last export? */ pos_args[1][3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_POS + 1); @@ -1130,6 +1137,11 @@ handle_semantic: pos_args[1][6] = LLVMBuildBitCast(base->gallivm->builder, output, base->elem_type, ""); } + + if (shader->vs_out_layer) { + pos_args[1][7] = LLVMBuildLoad(base->gallivm->builder, + si_shader_ctx->radeon_bld.soa.outputs[layer_index][0], ""); + } } for (i = 0; i < 4; i++) diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.h b/src/gallium/drivers/radeonsi/radeonsi_shader.h index 5432a878d5d..174035d870e 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_shader.h +++ b/src/gallium/drivers/radeonsi/radeonsi_shader.h @@ -114,6 +114,7 @@ struct si_shader { bool vs_out_misc_write; bool vs_out_point_size; bool vs_out_edgeflag; + bool vs_out_layer; unsigned nr_cbufs; unsigned nr_pos_exports; unsigned clip_dist_write; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index fd5d2c699f1..7bae72a4c0c 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -1571,7 +1571,7 @@ static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4, struct r600_surface *surf; unsigned level = state->cbufs[cb]->u.tex.level; unsigned pitch, slice; - unsigned color_info, color_attrib, color_pitch; + unsigned color_info, color_attrib, color_pitch, color_view; unsigned tile_mode_index; unsigned format, swap, ntype, endian; uint64_t offset; @@ -1584,10 +1584,19 @@ static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4, rtex = (struct r600_texture*)state->cbufs[cb]->texture; offset = rtex->surface.level[level].offset; - if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) { + + /* Layered rendering doesn't work with LINEAR_GENERAL. + * (LINEAR_ALIGNED and others work) */ + if (rtex->surface.level[level].mode == RADEON_SURF_MODE_LINEAR) { + assert(state->cbufs[cb]->u.tex.first_layer == state->cbufs[cb]->u.tex.last_layer); offset += rtex->surface.level[level].slice_size * state->cbufs[cb]->u.tex.first_layer; + color_view = 0; + } else { + color_view = S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) | + S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer); } + pitch = (rtex->surface.level[level].nblk_x) / 8 - 1; slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64; if (slice) { @@ -1697,14 +1706,7 @@ static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4, si_pm4_set_reg(pm4, R_028C60_CB_COLOR0_BASE + cb * 0x3C, offset); si_pm4_set_reg(pm4, R_028C64_CB_COLOR0_PITCH + cb * 0x3C, color_pitch); si_pm4_set_reg(pm4, R_028C68_CB_COLOR0_SLICE + cb * 0x3C, S_028C68_TILE_MAX(slice)); - - if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) { - si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C, 0x00000000); - } else { - si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C, - S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) | - S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer)); - } + si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C, color_view); si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + cb * 0x3C, color_info); si_pm4_set_reg(pm4, R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C, color_attrib); @@ -2993,7 +2995,6 @@ static struct pipe_surface *r600_create_surface(struct pipe_context *pipe, assert(surf_tmpl->u.tex.first_layer <= util_max_layer(texture, surf_tmpl->u.tex.level)); assert(surf_tmpl->u.tex.last_layer <= util_max_layer(texture, surf_tmpl->u.tex.level)); - assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer); pipe_reference_init(&surface->base.reference, 1); pipe_resource_reference(&surface->base.texture, texture); diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index d2c8e4c0985..be5a5c8e030 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -370,6 +370,7 @@ static bool si_update_draw_info_state(struct r600_context *rctx, si_pm4_set_reg(pm4, R_02881C_PA_CL_VS_OUT_CNTL, S_02881C_USE_VTX_POINT_SIZE(vs->vs_out_point_size) | S_02881C_USE_VTX_EDGE_FLAG(vs->vs_out_edgeflag) | + S_02881C_USE_VTX_RENDER_TARGET_INDX(vs->vs_out_layer) | S_02881C_VS_OUT_CCDIST0_VEC_ENA((vs->clip_dist_write & 0x0F) != 0) | S_02881C_VS_OUT_CCDIST1_VEC_ENA((vs->clip_dist_write & 0xF0) != 0) | S_02881C_VS_OUT_MISC_VEC_ENA(vs->vs_out_misc_write) | -- 2.30.2