On Tue, Nov 14, 2017 at 9:25 PM, Jason Ekstrand <[email protected]> wrote:
> On Tue, Nov 14, 2017 at 3:28 PM, Lionel Landwerlin < > [email protected]> wrote: > >> On 13/11/17 16:12, 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 8e7bc9f..ac582e7 100644 >>> --- a/src/intel/blorp/blorp_clear.c >>> +++ b/src/intel/blorp/blorp_clear.c >>> @@ -780,9 +780,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; >>> }; >>> @@ -792,6 +801,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(par >>> ams->dst.view.format), >>> .num_samples = params->num_samples, >>> }; >>> @@ -826,7 +837,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)); >>> >> >> Won't this need some swizzling somewhere? >> Either when storing the color in the fast clear colors (behind the aux >> surface) or here in the shader? >> > > Good question... I'll have to think on it more but we probably do. > No, we don't. The clear color is, I believe, simply storred in the format-specified channel order. We're just taking that clear color and committing it to the surface so we don't care about any swizzling. > --Jason > > >> + >>> + 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); >>> @@ -872,6 +894,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 7548392..c3df2d5 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.cle >>> ar_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 faa0af1..cd11765 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; >>> >> >> >> >
_______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
