On Fri, Oct 6, 2017 at 6:31 AM, Lionel Landwerlin < [email protected]> wrote:
> Signed-off-by: Lionel Landwerlin <[email protected]> > Reviewed-by: Jason Ekstrand <[email protected]> > --- > src/intel/vulkan/anv_descriptor_set.c | 13 +++ > src/intel/vulkan/anv_nir_apply_pipeline_layout.c | 113 > ++++++++++++++++++----- > src/intel/vulkan/anv_private.h | 7 ++ > src/intel/vulkan/genX_state.c | 2 + > 4 files changed, 113 insertions(+), 22 deletions(-) > > diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_ > descriptor_set.c > index 84077982307..629c041eedf 100644 > --- a/src/intel/vulkan/anv_descriptor_set.c > +++ b/src/intel/vulkan/anv_descriptor_set.c > @@ -400,6 +400,19 @@ anv_descriptor_set_layout_size(const struct > anv_descriptor_set_layout *layout) > layout->buffer_count * sizeof(struct anv_buffer_view); > } > > +size_t > +anv_descriptor_set_binding_layout_get_hw_size(const struct > anv_descriptor_set_binding_layout *binding) > +{ > + if (!binding->immutable_samplers) > + return binding->array_size; > + > + uint32_t total_plane_count = 0; > + for (uint32_t i = 0; i < binding->array_size; i++) > + total_plane_count += binding->immutable_samplers[i]->n_planes; > + > + return total_plane_count; > +} > + > struct surface_state_free_list_entry { > void *next; > struct anv_state state; > diff --git a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c > b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c > index 67bcf5e29ef..02323fba31a 100644 > --- a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c > +++ b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c > @@ -131,7 +131,7 @@ lower_res_index_intrinsic(nir_intrinsic_instr *intrin, > static void > lower_tex_deref(nir_tex_instr *tex, nir_deref_var *deref, > unsigned *const_index, unsigned array_size, > - nir_tex_src_type src_type, > + nir_tex_src_type src_type, bool allow_indirect, > struct apply_pipeline_layout_state *state) > { > nir_builder *b = &state->builder; > @@ -141,6 +141,15 @@ lower_tex_deref(nir_tex_instr *tex, nir_deref_var > *deref, > nir_deref_array *deref_array = nir_deref_as_array(deref-> > deref.child); > > if (deref_array->deref_array_type == nir_deref_array_type_indirect) > { > + /* From VK_KHR_sampler_ycbcr_conversion: > + * > + * If sampler Y’CBCR conversion is enabled, the combined image > + * sampler must be indexed only by constant integral expressions > when > + * aggregated into arrays in shader code, irrespective of the > + * shaderSampledImageArrayDynamicIndexing feature. > + */ > + assert(allow_indirect); > + > nir_ssa_def *index = > nir_iadd(b, nir_imm_int(b, deref_array->base_offset), > nir_ssa_for_src(b, deref_array->indirect, 1)); > @@ -186,6 +195,46 @@ cleanup_tex_deref(nir_tex_instr *tex, nir_deref_var > *deref) > nir_instr_rewrite_src(&tex->instr, &deref_array->indirect, > NIR_SRC_INIT); > } > > +static bool > +has_tex_src_plane(nir_tex_instr *tex) > +{ > + for (unsigned i = 0; i < tex->num_srcs; i++) { > + if (tex->src[i].src_type == nir_tex_src_plane) > + return true; > + } > + > + return false; > +} > + > +static uint32_t > +extract_tex_src_plane(nir_tex_instr *tex) > +{ > + nir_tex_src *new_srcs = rzalloc_array(tex, nir_tex_src, tex->num_srcs > - 1); > + unsigned plane = 0; > + > + for (unsigned i = 0, w = 0; i < tex->num_srcs; i++) { > + if (tex->src[i].src_type == nir_tex_src_plane) { > + nir_const_value *const_plane = > + nir_src_as_const_value(tex->src[i].src); > + > + /* Our color conversion lowering pass should only ever insert > + * constants. */ > + assert(const_plane); > + plane = const_plane->u32[0]; > As I mentioned on IRC today, we need to do nir_instr_rewrite_src(&tex->instr, &tex->src[i].src, NIR_SRC_INIT); here to get rid of the reference that he source carries to the load_const SSA def. Sorry that's not terribly intuitive. > + } else { > + new_srcs[w].src_type = tex->src[i].src_type; > + nir_instr_move_src(&tex->instr, &new_srcs[w].src, > &tex->src[i].src); > + w++; > + } > + } > + > + ralloc_free(tex->src); > + tex->src = new_srcs; > + tex->num_srcs--; > + > + return plane; > +} > + > static void > lower_tex(nir_tex_instr *tex, struct apply_pipeline_layout_state *state) > { > @@ -198,9 +247,13 @@ lower_tex(nir_tex_instr *tex, struct > apply_pipeline_layout_state *state) > unsigned binding = tex->texture->var->data.binding; > unsigned array_size = > state->layout->set[set].layout->binding[binding].array_size; > + bool has_plane = has_tex_src_plane(tex); > + unsigned plane = has_plane ? extract_tex_src_plane(tex) : 0; > + > tex->texture_index = state->set[set].surface_offsets[binding]; > lower_tex_deref(tex, tex->texture, &tex->texture_index, array_size, > - nir_tex_src_texture_offset, state); > + nir_tex_src_texture_offset, !has_plane, state); > + tex->texture_index += plane; > > if (tex->sampler) { > unsigned set = tex->sampler->var->data.descriptor_set; > @@ -209,7 +262,8 @@ lower_tex(nir_tex_instr *tex, struct > apply_pipeline_layout_state *state) > state->layout->set[set].layout->binding[binding].array_size; > tex->sampler_index = state->set[set].sampler_offsets[binding]; > lower_tex_deref(tex, tex->sampler, &tex->sampler_index, array_size, > - nir_tex_src_sampler_offset, state); > + nir_tex_src_sampler_offset, !has_plane, state); > + tex->sampler_index += plane; > } > > /* The backend only ever uses this to mark used surfaces. We don't > care > @@ -299,10 +353,14 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline > *pipeline, > BITSET_WORD b, _tmp; > BITSET_FOREACH_SET(b, _tmp, state.set[set].used, > set_layout->binding_count) { > - if (set_layout->binding[b].stage[shader->stage].surface_index > >= 0) > - map->surface_count += set_layout->binding[b].array_size; > - if (set_layout->binding[b].stage[shader->stage].sampler_index > >= 0) > - map->sampler_count += set_layout->binding[b].array_size; > + if (set_layout->binding[b].stage[shader->stage].surface_index > >= 0) { > + map->surface_count += > + anv_descriptor_set_binding_layout_get_hw_size(&set_ > layout->binding[b]); > + } > + if (set_layout->binding[b].stage[shader->stage].sampler_index > >= 0) { > + map->sampler_count += > + anv_descriptor_set_binding_layout_get_hw_size(&set_ > layout->binding[b]); > + } > if (set_layout->binding[b].stage[shader->stage].image_index >= > 0) > map->image_count += set_layout->binding[b].array_size; > } > @@ -317,31 +375,42 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline > *pipeline, > BITSET_WORD b, _tmp; > BITSET_FOREACH_SET(b, _tmp, state.set[set].used, > set_layout->binding_count) { > - unsigned array_size = set_layout->binding[b].array_size; > + struct anv_descriptor_set_binding_layout *binding = > + &set_layout->binding[b]; > > - if (set_layout->binding[b].stage[shader->stage].surface_index > >= 0) { > + if (binding->stage[shader->stage].surface_index >= 0) { > state.set[set].surface_offsets[b] = surface; > - for (unsigned i = 0; i < array_size; i++) { > - map->surface_to_descriptor[surface + i].set = set; > - map->surface_to_descriptor[surface + i].binding = b; > - map->surface_to_descriptor[surface + i].index = i; > + struct anv_sampler **samplers = binding->immutable_samplers; > + for (unsigned i = 0; i < binding->array_size; i++) { > + uint8_t planes = samplers ? samplers[i]->n_planes : 1; > + for (uint8_t p = 0; p < planes; p++) { > + map->surface_to_descriptor[surface].set = set; > + map->surface_to_descriptor[surface].binding = b; > + map->surface_to_descriptor[surface].index = i; > + map->surface_to_descriptor[surface].plane = p; > + surface++; > + } > } > - surface += array_size; > } > > - if (set_layout->binding[b].stage[shader->stage].sampler_index > >= 0) { > + if (binding->stage[shader->stage].sampler_index >= 0) { > state.set[set].sampler_offsets[b] = sampler; > - for (unsigned i = 0; i < array_size; i++) { > - map->sampler_to_descriptor[sampler + i].set = set; > - map->sampler_to_descriptor[sampler + i].binding = b; > - map->sampler_to_descriptor[sampler + i].index = i; > + struct anv_sampler **samplers = binding->immutable_samplers; > + for (unsigned i = 0; i < binding->array_size; i++) { > + uint8_t planes = samplers ? samplers[i]->n_planes : 1; > + for (uint8_t p = 0; p < planes; p++) { > + map->sampler_to_descriptor[sampler].set = set; > + map->sampler_to_descriptor[sampler].binding = b; > + map->sampler_to_descriptor[sampler].index = i; > + map->sampler_to_descriptor[sampler].plane = p; > + sampler++; > + } > } > - sampler += array_size; > } > > - if (set_layout->binding[b].stage[shader->stage].image_index >= > 0) { > + if (binding->stage[shader->stage].image_index >= 0) { > state.set[set].image_offsets[b] = image; > - image += array_size; > + image += binding->array_size; > } > } > } > diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_ > private.h > index 36aa86141fc..ff1b1cc8a80 100644 > --- a/src/intel/vulkan/anv_private.h > +++ b/src/intel/vulkan/anv_private.h > @@ -1323,6 +1323,9 @@ struct anv_descriptor_update_template { > struct anv_descriptor_template_entry entries[0]; > }; > > +size_t > +anv_descriptor_set_binding_layout_get_hw_size(const struct > anv_descriptor_set_binding_layout *binding); > + > size_t > anv_descriptor_set_layout_size(const struct anv_descriptor_set_layout > *layout); > > @@ -1385,6 +1388,9 @@ struct anv_pipeline_binding { > /* Index in the binding */ > uint32_t index; > > + /* Plane in the binding index */ > + uint8_t plane; > + > /* Input attachment index (relative to the subpass) */ > uint8_t input_attachment_index; > > @@ -2540,6 +2546,7 @@ void anv_fill_buffer_surface_state(struct > anv_device *device, > > struct anv_sampler { > uint32_t state[4]; > + uint32_t n_planes; > }; > > struct anv_framebuffer { > diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c > index d016aff4a54..81570825a54 100644 > --- a/src/intel/vulkan/genX_state.c > +++ b/src/intel/vulkan/genX_state.c > @@ -171,6 +171,8 @@ VkResult genX(CreateSampler)( > if (!sampler) > return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); > > + sampler->n_planes = 1; > + > uint32_t border_color_offset = device->border_colors.offset + > pCreateInfo->borderColor * 64; > > -- > 2.14.2 > > _______________________________________________ > mesa-dev mailing list > [email protected] > https://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
