summaryrefslogtreecommitdiff
path: root/src/intel/vulkan
diff options
context:
space:
mode:
authorJason Ekstrand <jason@jlekstrand.net>2021-03-30 21:32:46 -0500
committerMarge Bot <emma+marge@anholt.net>2023-01-16 14:10:21 +0000
commitb39958a3a1862f07ab5dae18c8160906e653a3a6 (patch)
tree333a65ff2bd46302a5fc47d8d273fb08d420f7f4 /src/intel/vulkan
parentf02a11e4e4cb78da491780efc1db9b2429275168 (diff)
anv,nir: Move the ANV YCbCr lowering pass to common code
Nir changes: Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com> Anv changes: Acked-by: Alejandro Piñeiro <apinheiro@igalia.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19950>
Diffstat (limited to 'src/intel/vulkan')
-rw-r--r--src/intel/vulkan/anv_nir_lower_ycbcr_textures.c338
-rw-r--r--src/intel/vulkan/anv_pipeline.c25
-rw-r--r--src/intel/vulkan/meson.build1
3 files changed, 24 insertions, 340 deletions
diff --git a/src/intel/vulkan/anv_nir_lower_ycbcr_textures.c b/src/intel/vulkan/anv_nir_lower_ycbcr_textures.c
deleted file mode 100644
index 92109df1e6b..00000000000
--- a/src/intel/vulkan/anv_nir_lower_ycbcr_textures.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright © 2017 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "anv_nir.h"
-#include "anv_private.h"
-#include "nir/nir.h"
-#include "nir/nir_builder.h"
-#include "nir/nir_vulkan.h"
-#include "vk_format.h"
-
-struct ycbcr_state {
- nir_builder *builder;
- nir_ssa_def *image_size;
- nir_tex_instr *origin_tex;
- nir_deref_instr *tex_deref;
- const struct vk_ycbcr_conversion *conversion;
- const struct vk_format_ycbcr_info *format_ycbcr_info;
-};
-
-/* TODO: we should probably replace this with a push constant/uniform. */
-static nir_ssa_def *
-get_texture_size(struct ycbcr_state *state, nir_deref_instr *texture)
-{
- if (state->image_size)
- return state->image_size;
-
- nir_builder *b = state->builder;
- const struct glsl_type *type = texture->type;
- nir_tex_instr *tex = nir_tex_instr_create(b->shader, 1);
-
- tex->op = nir_texop_txs;
- tex->sampler_dim = glsl_get_sampler_dim(type);
- tex->is_array = glsl_sampler_type_is_array(type);
- tex->is_shadow = glsl_sampler_type_is_shadow(type);
- tex->dest_type = nir_type_int32;
-
- tex->src[0].src_type = nir_tex_src_texture_deref;
- tex->src[0].src = nir_src_for_ssa(&texture->dest.ssa);
-
- nir_ssa_dest_init(&tex->instr, &tex->dest,
- nir_tex_instr_dest_size(tex), 32, NULL);
- nir_builder_instr_insert(b, &tex->instr);
-
- state->image_size = nir_i2f32(b, &tex->dest.ssa);
-
- return state->image_size;
-}
-
-static nir_ssa_def *
-implicit_downsampled_coord(nir_builder *b,
- nir_ssa_def *value,
- nir_ssa_def *max_value,
- int div_scale)
-{
- return nir_fadd(b,
- value,
- nir_fdiv(b,
- nir_imm_float(b, 1.0f),
- nir_fmul(b,
- nir_imm_float(b, div_scale),
- max_value)));
-}
-
-static nir_ssa_def *
-implicit_downsampled_coords(struct ycbcr_state *state,
- nir_ssa_def *old_coords,
- const struct vk_format_ycbcr_plane *format_plane)
-{
- nir_builder *b = state->builder;
- const struct vk_ycbcr_conversion *conversion = state->conversion;
- nir_ssa_def *image_size = get_texture_size(state, state->tex_deref);
- nir_ssa_def *comp[4] = { NULL, };
- int c;
-
- for (c = 0; c < ARRAY_SIZE(conversion->chroma_offsets); c++) {
- if (format_plane->denominator_scales[c] > 1 &&
- conversion->chroma_offsets[c] == VK_CHROMA_LOCATION_COSITED_EVEN) {
- comp[c] = implicit_downsampled_coord(b,
- nir_channel(b, old_coords, c),
- nir_channel(b, image_size, c),
- format_plane->denominator_scales[c]);
- } else {
- comp[c] = nir_channel(b, old_coords, c);
- }
- }
-
- /* Leave other coordinates untouched */
- for (; c < old_coords->num_components; c++)
- comp[c] = nir_channel(b, old_coords, c);
-
- return nir_vec(b, comp, old_coords->num_components);
-}
-
-static nir_ssa_def *
-create_plane_tex_instr_implicit(struct ycbcr_state *state,
- uint32_t plane)
-{
- nir_builder *b = state->builder;
- const struct vk_ycbcr_conversion *conversion = state->conversion;
- const struct vk_format_ycbcr_plane *format_plane =
- &state->format_ycbcr_info->planes[plane];
- nir_tex_instr *old_tex = state->origin_tex;
- nir_tex_instr *tex = nir_tex_instr_create(b->shader, old_tex->num_srcs + 1);
-
- for (uint32_t i = 0; i < old_tex->num_srcs; i++) {
- tex->src[i].src_type = old_tex->src[i].src_type;
-
- switch (old_tex->src[i].src_type) {
- case nir_tex_src_coord:
- if (format_plane->has_chroma && conversion->chroma_reconstruction) {
- assert(old_tex->src[i].src.is_ssa);
- tex->src[i].src =
- nir_src_for_ssa(implicit_downsampled_coords(state,
- old_tex->src[i].src.ssa,
- format_plane));
- break;
- }
- FALLTHROUGH;
- default:
- nir_src_copy(&tex->src[i].src, &old_tex->src[i].src, &tex->instr);
- break;
- }
- }
- tex->src[tex->num_srcs - 1].src = nir_src_for_ssa(nir_imm_int(b, plane));
- tex->src[tex->num_srcs - 1].src_type = nir_tex_src_plane;
-
- tex->sampler_dim = old_tex->sampler_dim;
- tex->dest_type = old_tex->dest_type;
-
- tex->op = old_tex->op;
- tex->coord_components = old_tex->coord_components;
- tex->is_new_style_shadow = old_tex->is_new_style_shadow;
- tex->component = old_tex->component;
-
- tex->texture_index = old_tex->texture_index;
- tex->sampler_index = old_tex->sampler_index;
- tex->is_array = old_tex->is_array;
-
- nir_ssa_dest_init(&tex->instr, &tex->dest,
- old_tex->dest.ssa.num_components,
- nir_dest_bit_size(old_tex->dest), NULL);
- nir_builder_instr_insert(b, &tex->instr);
-
- return &tex->dest.ssa;
-}
-
-static unsigned
-swizzle_to_component(VkComponentSwizzle swizzle)
-{
- switch (swizzle) {
- case VK_COMPONENT_SWIZZLE_R:
- return 0;
- case VK_COMPONENT_SWIZZLE_G:
- return 1;
- case VK_COMPONENT_SWIZZLE_B:
- return 2;
- case VK_COMPONENT_SWIZZLE_A:
- return 3;
- default:
- unreachable("invalid channel");
- return 0;
- }
-}
-
-static bool
-anv_nir_lower_ycbcr_textures_instr(nir_builder *builder,
- nir_instr *instr,
- void *cb_data)
-{
- const struct anv_pipeline_layout *layout = cb_data;
-
- if (instr->type != nir_instr_type_tex)
- return false;
-
- nir_tex_instr *tex = nir_instr_as_tex(instr);
-
- int deref_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);
- assert(deref_src_idx >= 0);
- nir_deref_instr *deref = nir_src_as_deref(tex->src[deref_src_idx].src);
-
- nir_variable *var = nir_deref_instr_get_variable(deref);
- const struct anv_descriptor_set_layout *set_layout =
- layout->set[var->data.descriptor_set].layout;
- const struct anv_descriptor_set_binding_layout *binding =
- &set_layout->binding[var->data.binding];
-
- /* For the following instructions, we don't apply any change and let the
- * instruction apply to the first plane.
- */
- if (tex->op == nir_texop_txs ||
- tex->op == nir_texop_query_levels ||
- tex->op == nir_texop_lod)
- return false;
-
- if (binding->immutable_samplers == NULL)
- return false;
-
- assert(tex->texture_index == 0);
- unsigned array_index = 0;
- if (deref->deref_type != nir_deref_type_var) {
- assert(deref->deref_type == nir_deref_type_array);
- if (!nir_src_is_const(deref->arr.index))
- return false;
- array_index = nir_src_as_uint(deref->arr.index);
- array_index = MIN2(array_index, binding->array_size - 1);
- }
- const struct anv_sampler *sampler = binding->immutable_samplers[array_index];
-
- if (sampler->conversion == NULL)
- return false;
-
- const struct vk_format_ycbcr_info *format_ycbcr_info =
- vk_format_get_ycbcr_info(sampler->conversion->format);
-
- struct ycbcr_state state = {
- .builder = builder,
- .origin_tex = tex,
- .tex_deref = deref,
- .conversion = sampler->conversion,
- .format_ycbcr_info = format_ycbcr_info,
- };
-
- builder->cursor = nir_before_instr(&tex->instr);
-
- VkFormat y_format = VK_FORMAT_UNDEFINED;
- for (uint32_t p = 0; p < format_ycbcr_info->n_planes; p++) {
- if (!format_ycbcr_info->planes[p].has_chroma)
- y_format = format_ycbcr_info->planes[p].format;
- }
- assert(y_format != VK_FORMAT_UNDEFINED);
- const struct util_format_description *y_format_desc =
- util_format_description(vk_format_to_pipe_format(y_format));
- uint8_t y_bpc = y_format_desc->channel[0].size;
-
- /* |ycbcr_comp| holds components in the order : Cr-Y-Cb */
- nir_ssa_def *zero = nir_imm_float(builder, 0.0f);
- nir_ssa_def *one = nir_imm_float(builder, 1.0f);
- /* Use extra 2 channels for following swizzle */
- nir_ssa_def *ycbcr_comp[5] = { zero, zero, zero, one, zero };
-
- uint8_t ycbcr_bpcs[5];
- memset(ycbcr_bpcs, y_bpc, sizeof(ycbcr_bpcs));
-
- /* Go through all the planes and gather the samples into a |ycbcr_comp|
- * while applying a swizzle required by the spec:
- *
- * R, G, B should respectively map to Cr, Y, Cb
- */
- for (uint32_t p = 0; p < format_ycbcr_info->n_planes; p++) {
- const struct vk_format_ycbcr_plane *format_plane =
- &format_ycbcr_info->planes[p];
- nir_ssa_def *plane_sample = create_plane_tex_instr_implicit(&state, p);
-
- for (uint32_t pc = 0; pc < 4; pc++) {
- VkComponentSwizzle ycbcr_swizzle = format_plane->ycbcr_swizzle[pc];
- if (ycbcr_swizzle == VK_COMPONENT_SWIZZLE_ZERO)
- continue;
-
- unsigned ycbcr_component = swizzle_to_component(ycbcr_swizzle);
- ycbcr_comp[ycbcr_component] = nir_channel(builder, plane_sample, pc);
-
- /* Also compute the number of bits for each component. */
- const struct util_format_description *plane_format_desc =
- util_format_description(vk_format_to_pipe_format(format_plane->format));
- ycbcr_bpcs[ycbcr_component] = plane_format_desc->channel[pc].size;
- }
- }
-
- /* Now remaps components to the order specified by the conversion. */
- nir_ssa_def *swizzled_comp[4] = { NULL, };
- uint32_t swizzled_bpcs[4] = { 0, };
-
- for (uint32_t i = 0; i < ARRAY_SIZE(state.conversion->mapping); i++) {
- /* Maps to components in |ycbcr_comp| */
- static const uint32_t swizzle_mapping[] = {
- [VK_COMPONENT_SWIZZLE_ZERO] = 4,
- [VK_COMPONENT_SWIZZLE_ONE] = 3,
- [VK_COMPONENT_SWIZZLE_R] = 0,
- [VK_COMPONENT_SWIZZLE_G] = 1,
- [VK_COMPONENT_SWIZZLE_B] = 2,
- [VK_COMPONENT_SWIZZLE_A] = 3,
- };
- const VkComponentSwizzle m = state.conversion->mapping[i];
-
- if (m == VK_COMPONENT_SWIZZLE_IDENTITY) {
- swizzled_comp[i] = ycbcr_comp[i];
- swizzled_bpcs[i] = ycbcr_bpcs[i];
- } else {
- swizzled_comp[i] = ycbcr_comp[swizzle_mapping[m]];
- swizzled_bpcs[i] = ycbcr_bpcs[swizzle_mapping[m]];
- }
- }
-
- nir_ssa_def *result = nir_vec(builder, swizzled_comp, 4);
- if (state.conversion->ycbcr_model != VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY) {
- result = nir_convert_ycbcr_to_rgb(builder,
- state.conversion->ycbcr_model,
- state.conversion->ycbcr_range,
- result,
- swizzled_bpcs);
- }
-
- nir_ssa_def_rewrite_uses(&tex->dest.ssa, result);
- nir_instr_remove(&tex->instr);
-
- return true;
-}
-
-bool
-anv_nir_lower_ycbcr_textures(nir_shader *shader,
- const struct anv_pipeline_layout *layout)
-{
- return nir_shader_instructions_pass(shader,
- anv_nir_lower_ycbcr_textures_instr,
- nir_metadata_block_index |
- nir_metadata_dominance,
- (void *)layout);
-}
diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
index d6d798c5d02..a4845f76360 100644
--- a/src/intel/vulkan/anv_pipeline.c
+++ b/src/intel/vulkan/anv_pipeline.c
@@ -36,6 +36,7 @@
#include "compiler/brw_nir.h"
#include "compiler/brw_nir_rt.h"
#include "anv_nir.h"
+#include "nir/nir_vulkan.h"
#include "nir/nir_xfb_info.h"
#include "spirv/nir_spirv.h"
#include "vk_pipeline.h"
@@ -765,6 +766,28 @@ anv_pipeline_stage_get_nir(struct anv_pipeline *pipeline,
return NULL;
}
+static const struct vk_ycbcr_conversion *
+lookup_ycbcr_conversion(const void *_pipeline_layout, uint32_t set,
+ uint32_t binding, uint32_t array_index)
+{
+ const struct anv_pipeline_layout *pipeline_layout = _pipeline_layout;
+
+ assert(set < MAX_SETS);
+ assert(binding < pipeline_layout->set[set].layout->binding_count);
+ const struct anv_descriptor_set_binding_layout *bind_layout =
+ &pipeline_layout->set[set].layout->binding[binding];
+
+ if (bind_layout->immutable_samplers == NULL)
+ return NULL;
+
+ array_index = MIN2(array_index, bind_layout->array_size - 1);
+
+ const struct anv_sampler *sampler =
+ bind_layout->immutable_samplers[array_index];
+
+ return sampler ? sampler->conversion : NULL;
+}
+
static void
shared_type_info(const struct glsl_type *type, unsigned *size, unsigned *align)
{
@@ -815,7 +838,7 @@ anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
NIR_PASS(_, nir, nir_lower_compute_system_values, &options);
}
- NIR_PASS(_, nir, anv_nir_lower_ycbcr_textures, layout);
+ NIR_PASS(_, nir, nir_vk_lower_ycbcr_tex, lookup_ycbcr_conversion, layout);
if (pipeline->type == ANV_PIPELINE_GRAPHICS) {
struct anv_graphics_pipeline *gfx_pipeline =
diff --git a/src/intel/vulkan/meson.build b/src/intel/vulkan/meson.build
index d09960a4b8c..b0c217b5db3 100644
--- a/src/intel/vulkan/meson.build
+++ b/src/intel/vulkan/meson.build
@@ -153,7 +153,6 @@ libanv_files = files(
'anv_nir_compute_push_layout.c',
'anv_nir_lower_multiview.c',
'anv_nir_lower_ubo_loads.c',
- 'anv_nir_lower_ycbcr_textures.c',
'anv_nir_push_descriptor_analysis.c',
'anv_perf.c',
'anv_pipeline.c',