From dc25a83a7a0b71548d0d7b6f0021f73450ce0c6d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 2 Oct 2017 16:43:33 -0700 Subject: [PATCH] broadcom/vc5: Start hooking up multiple render targets support. We now emit as many TLB color writes as there are color buffers. --- src/broadcom/compiler/nir_to_vir.c | 48 ++++++++++++++++++++------- src/broadcom/compiler/v3d_compiler.h | 5 +-- src/gallium/drivers/vc5/vc5_program.c | 12 +++++-- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c index acfeba4cb71..642173e3ad3 100644 --- a/src/broadcom/compiler/nir_to_vir.c +++ b/src/broadcom/compiler/nir_to_vir.c @@ -1070,24 +1070,26 @@ emit_frag_end(struct v3d_compile *c) * uniform setup */ - if (c->output_color_var) { - nir_variable *var = c->output_color_var; + for (int rt = 0; rt < c->fs_key->nr_cbufs; rt++) { + if (!c->output_color_var[rt]) + continue; + + nir_variable *var = c->output_color_var[rt]; struct qreg *color = &c->outputs[var->data.driver_location * 4]; int num_components = glsl_get_vector_elements(var->type); - uint32_t conf = ~0; + uint32_t conf = 0xffffff00; struct qinst *inst; + conf |= TLB_SAMPLE_MODE_PER_PIXEL; + conf |= (7 - rt) << TLB_RENDER_TARGET_SHIFT; + assert(num_components != 0); switch (glsl_get_base_type(var->type)) { case GLSL_TYPE_UINT: case GLSL_TYPE_INT: - conf = (TLB_TYPE_I32_COLOR | - TLB_SAMPLE_MODE_PER_PIXEL | - ((7 - 0) << TLB_RENDER_TARGET_SHIFT) | - ((num_components - 1) << - TLB_VEC_SIZE_MINUS_1_SHIFT) | - 0xffffff00); - + conf |= TLB_TYPE_I32_COLOR; + conf |= ((num_components - 1) << + TLB_VEC_SIZE_MINUS_1_SHIFT); inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), color[0]); vir_set_cond(inst, discard_cond); @@ -1107,13 +1109,26 @@ emit_frag_end(struct v3d_compile *c) struct qreg b = color[2]; struct qreg a = color[3]; - if (c->fs_key->swap_color_rb) { + conf |= TLB_TYPE_F16_COLOR; + conf |= TLB_F16_SWAP_HI_LO; + if (num_components >= 3) + conf |= TLB_VEC_SIZE_4_F16; + else + conf |= TLB_VEC_SIZE_2_F16; + + if (c->fs_key->swap_color_rb & (1 << rt)) { r = color[2]; b = color[0]; } inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), r, g); + if (conf != ~0) { + inst->dst.file = QFILE_TLBU; + inst->src[vir_get_implicit_uniform_src(inst)] = + vir_uniform_ui(c, conf); + } vir_set_cond(inst, discard_cond); + inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), b, a); vir_set_cond(inst, discard_cond); break; @@ -1421,8 +1436,17 @@ ntq_setup_outputs(struct v3d_compile *c) if (c->s->stage == MESA_SHADER_FRAGMENT) { switch (var->data.location) { case FRAG_RESULT_COLOR: + c->output_color_var[0] = var; + c->output_color_var[1] = var; + c->output_color_var[2] = var; + c->output_color_var[3] = var; + break; case FRAG_RESULT_DATA0: - c->output_color_var = var; + case FRAG_RESULT_DATA1: + case FRAG_RESULT_DATA2: + case FRAG_RESULT_DATA3: + c->output_color_var[var->data.location - + FRAG_RESULT_DATA0] = var; break; case FRAG_RESULT_DEPTH: c->output_position_index = loc; diff --git a/src/broadcom/compiler/v3d_compiler.h b/src/broadcom/compiler/v3d_compiler.h index a29b08ac1ab..bdd505ee9ba 100644 --- a/src/broadcom/compiler/v3d_compiler.h +++ b/src/broadcom/compiler/v3d_compiler.h @@ -318,7 +318,8 @@ struct v3d_fs_key { bool sample_alpha_to_coverage; bool sample_alpha_to_one; bool clamp_color; - bool swap_color_rb; + uint8_t nr_cbufs; + uint8_t swap_color_rb; uint8_t alpha_test_func; uint8_t logicop_func; uint32_t point_sprite_mask; @@ -490,7 +491,7 @@ struct v3d_compile { uint32_t num_uniforms; uint32_t num_outputs; uint32_t output_position_index; - nir_variable *output_color_var; + nir_variable *output_color_var[4]; uint32_t output_point_size_index; uint32_t output_sample_mask_index; diff --git a/src/gallium/drivers/vc5/vc5_program.c b/src/gallium/drivers/vc5/vc5_program.c index f22f474954c..d5634c7a7d3 100644 --- a/src/gallium/drivers/vc5/vc5_program.c +++ b/src/gallium/drivers/vc5/vc5_program.c @@ -357,12 +357,18 @@ vc5_update_compiled_fs(struct vc5_context *vc5, uint8_t prim_mode) key->alpha_test_func = vc5->zsa->base.alpha.func; } - if (vc5->framebuffer.cbufs[0]) { - struct pipe_surface *cbuf = vc5->framebuffer.cbufs[0]; + /* gl_FragColor's propagation to however many bound color buffers + * there are means that the buffer count needs to be in the key. + */ + key->nr_cbufs = vc5->framebuffer.nr_cbufs; + + for (int i = 0; i < key->nr_cbufs; i++) { + struct pipe_surface *cbuf = vc5->framebuffer.cbufs[i]; const struct util_format_description *desc = util_format_description(cbuf->format); - key->swap_color_rb = desc->swizzle[0] == PIPE_SWIZZLE_Z; + if (desc->swizzle[0] == PIPE_SWIZZLE_Z) + key->swap_color_rb |= 1 << i; } if (key->is_points) { -- 2.30.2