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