On Fri, Feb 23, 2018 at 10:22:57PM -0800, Jason Ekstrand wrote: > This is a bit complicated because we have to get the indirect clear > color in there somehow. In order to not do any more work in the shader > than needed, we set it up as it's own vertex binding which points > directly at the clear color address specified by the client. > --- > src/intel/blorp/blorp_clear.c | 25 +++++++++++++++++- > src/intel/blorp/blorp_genX_exec.h | 54 > ++++++++++++++++++++++++++++++++------- > src/intel/blorp/blorp_priv.h | 1 + > 3 files changed, 70 insertions(+), 10 deletions(-) > > diff --git a/src/intel/blorp/blorp_clear.c b/src/intel/blorp/blorp_clear.c > index dde116f..832e8ee 100644 > --- a/src/intel/blorp/blorp_clear.c > +++ b/src/intel/blorp/blorp_clear.c > @@ -833,9 +833,18 @@ blorp_ccs_resolve(struct blorp_batch *batch, > batch->blorp->exec(batch, ¶ms); > } > > +static nir_ssa_def * > +blorp_nir_bit(nir_builder *b, nir_ssa_def *src, unsigned bit) > +{ > + return nir_iand(b, nir_ushr(b, src, nir_imm_int(b, bit)), > + nir_imm_int(b, 1)); > +} > + > struct blorp_mcs_partial_resolve_key > { > enum blorp_shader_type shader_type; > + bool indirect_clear_color; > + bool int_format; > uint32_t num_samples; > }; > > @@ -845,6 +854,8 @@ blorp_params_get_mcs_partial_resolve_kernel(struct > blorp_context *blorp, > { > const struct blorp_mcs_partial_resolve_key blorp_key = { > .shader_type = BLORP_SHADER_TYPE_MCS_PARTIAL_RESOLVE, > + .indirect_clear_color = params->dst.clear_color_addr.buffer != NULL, > + .int_format = isl_format_has_int_channel(params->dst.view.format), > .num_samples = params->num_samples, > }; > > @@ -879,7 +890,18 @@ blorp_params_get_mcs_partial_resolve_kernel(struct > blorp_context *blorp, > discard->src[0] = nir_src_for_ssa(nir_inot(&b, is_clear)); > nir_builder_instr_insert(&b, &discard->instr); > > - nir_copy_var(&b, frag_color, v_color); > + nir_ssa_def *clear_color = nir_load_var(&b, v_color); > + if (blorp_key.indirect_clear_color && blorp->isl_dev->info->gen <= 8) { > + /* Gen7-8 clear colors are stored as single 0/1 bits */ > + clear_color = nir_vec4(&b, blorp_nir_bit(&b, clear_color, 31), > + blorp_nir_bit(&b, clear_color, 30), > + blorp_nir_bit(&b, clear_color, 29), > + blorp_nir_bit(&b, clear_color, 28));
I was expecting to see right hand side in the form: blorp_nir_bit(&b nir_channel(&b, clear_color, 0), 31) and so on. So omitting the channel selection defaults to first or am I missing something else? In addition I was suprised to see that we can treat it as integer in expressions even though it is always defined as float - it gets its type after v_color, right? And that in turn is unconditionally declared as: nir_variable *v_color = BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type()); > + > + if (!blorp_key.int_format) > + clear_color = nir_i2f32(&b, clear_color); > + } > + nir_store_var(&b, frag_color, clear_color, 0xf); > > struct brw_wm_prog_key wm_key; > brw_blorp_init_wm_prog_key(&wm_key); > @@ -925,6 +947,7 @@ blorp_mcs_partial_resolve(struct blorp_batch *batch, > > params.num_samples = params.dst.surf.samples; > params.num_layers = num_layers; > + params.dst_clear_color_as_input = surf->clear_color_addr.buffer != NULL; > > memcpy(¶ms.wm_inputs.clear_color, > surf->clear_color.f32, sizeof(float) * 4); > diff --git a/src/intel/blorp/blorp_genX_exec.h > b/src/intel/blorp/blorp_genX_exec.h > index cea514e..cc408ca 100644 > --- a/src/intel/blorp/blorp_genX_exec.h > +++ b/src/intel/blorp/blorp_genX_exec.h > @@ -297,7 +297,7 @@ static void > blorp_emit_vertex_buffers(struct blorp_batch *batch, > const struct blorp_params *params) > { > - struct GENX(VERTEX_BUFFER_STATE) vb[2]; > + struct GENX(VERTEX_BUFFER_STATE) vb[3]; > memset(vb, 0, sizeof(vb)); > > struct blorp_address addr; > @@ -308,12 +308,20 @@ blorp_emit_vertex_buffers(struct blorp_batch *batch, > blorp_emit_input_varying_data(batch, params, &addr, &size); > blorp_fill_vertex_buffer_state(batch, vb, 1, addr, size, 0); > > - const unsigned num_dwords = 1 + GENX(VERTEX_BUFFER_STATE_length) * 2; > + uint32_t num_vbs = 2; > + if (params->dst_clear_color_as_input) { > + blorp_fill_vertex_buffer_state(batch, vb, num_vbs++, > + params->dst.clear_color_addr, > + > batch->blorp->isl_dev->ss.clear_value_size, > + 0); > + } > + > + const unsigned num_dwords = 1 + num_vbs * > GENX(VERTEX_BUFFER_STATE_length); > uint32_t *dw = blorp_emitn(batch, GENX(3DSTATE_VERTEX_BUFFERS), > num_dwords); > if (!dw) > return; > > - for (unsigned i = 0; i < 2; i++) { > + for (unsigned i = 0; i < num_vbs; i++) { > GENX(VERTEX_BUFFER_STATE_pack)(batch, dw, &vb[i]); > dw += GENX(VERTEX_BUFFER_STATE_length); > } > @@ -440,21 +448,49 @@ blorp_emit_vertex_elements(struct blorp_batch *batch, > }; > slot++; > > - for (unsigned i = 0; i < num_varyings; ++i) { > + if (params->dst_clear_color_as_input) { > + /* If the caller wants the destination indirect clear color, redirect > + * to vertex buffer 2 where we stored it earlier. The only users of > + * an indirect clear color source have that as their only vertex > + * attribute. > + */ > + assert(num_varyings == 1); > ve[slot] = (struct GENX(VERTEX_ELEMENT_STATE)) { > - .VertexBufferIndex = 1, > + .VertexBufferIndex = 2, > .Valid = true, > - .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) > ISL_FORMAT_R32G32B32A32_FLOAT, > - .SourceElementOffset = 16 + i * 4 * sizeof(float), > + .SourceElementOffset = 0, > .Component0Control = VFCOMP_STORE_SRC, > +#if GEN_GEN >= 9 > + .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) > ISL_FORMAT_R32G32B32A32_FLOAT, > .Component1Control = VFCOMP_STORE_SRC, > .Component2Control = VFCOMP_STORE_SRC, > .Component3Control = VFCOMP_STORE_SRC, > -#if GEN_GEN <= 5 > - .DestinationElementOffset = slot * 4, > +#else > + /* Clear colors on gen7-8 are for bits out of one dword */ > + .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) > ISL_FORMAT_R32_FLOAT, > + .Component1Control = VFCOMP_STORE_0, > + .Component2Control = VFCOMP_STORE_0, > + .Component3Control = VFCOMP_STORE_0, > #endif > }; > slot++; > + } else { > + for (unsigned i = 0; i < num_varyings; ++i) { > + ve[slot] = (struct GENX(VERTEX_ELEMENT_STATE)) { > + .VertexBufferIndex = 1, > + .Valid = true, > + .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) > ISL_FORMAT_R32G32B32A32_FLOAT, > + .SourceElementOffset = 16 + i * 4 * sizeof(float), > + .Component0Control = VFCOMP_STORE_SRC, > + .Component1Control = VFCOMP_STORE_SRC, > + .Component2Control = VFCOMP_STORE_SRC, > + .Component3Control = VFCOMP_STORE_SRC, > +#if GEN_GEN <= 5 > + .DestinationElementOffset = slot * 4, > +#endif > + }; > + slot++; > + } > } > > const unsigned num_dwords = > diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h > index 3fd2203..3811ec6 100644 > --- a/src/intel/blorp/blorp_priv.h > +++ b/src/intel/blorp/blorp_priv.h > @@ -196,6 +196,7 @@ struct blorp_params > bool color_write_disable[4]; > struct brw_blorp_wm_inputs wm_inputs; > struct blorp_vs_inputs vs_inputs; > + bool dst_clear_color_as_input; > unsigned num_samples; > unsigned num_draw_buffers; > unsigned num_layers; > -- > 2.5.0.400.gff86faf > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev