summaryrefslogtreecommitdiff
path: root/src/broadcom/vulkan/v3dvx_image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/broadcom/vulkan/v3dvx_image.c')
-rw-r--r--src/broadcom/vulkan/v3dvx_image.c249
1 files changed, 145 insertions, 104 deletions
diff --git a/src/broadcom/vulkan/v3dvx_image.c b/src/broadcom/vulkan/v3dvx_image.c
index a9aa0fb9797..de984e81220 100644
--- a/src/broadcom/vulkan/v3dvx_image.c
+++ b/src/broadcom/vulkan/v3dvx_image.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2021 Raspberry Pi
+ * Copyright © 2021 Raspberry Pi Ltd
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -26,32 +26,6 @@
#include "broadcom/cle/v3dx_pack.h"
#include "broadcom/compiler/v3d_compiler.h"
-#include "vk_format_info.h"
-
-/*
- * This method translates pipe_swizzle to the swizzle values used at the
- * packet TEXTURE_SHADER_STATE
- *
- * FIXME: C&P from v3d, common place?
- */
-static uint32_t
-translate_swizzle(unsigned char pipe_swizzle)
-{
- switch (pipe_swizzle) {
- case PIPE_SWIZZLE_0:
- return 0;
- case PIPE_SWIZZLE_1:
- return 1;
- case PIPE_SWIZZLE_X:
- case PIPE_SWIZZLE_Y:
- case PIPE_SWIZZLE_Z:
- case PIPE_SWIZZLE_W:
- return 2 + pipe_swizzle;
- default:
- unreachable("unknown swizzle");
- }
-}
-
/*
* Packs and ensure bo for the shader state (the latter can be temporal).
*/
@@ -71,78 +45,125 @@ pack_texture_shader_state_helper(struct v3dv_device *device,
image->vk.samples == VK_SAMPLE_COUNT_4_BIT);
const uint32_t msaa_scale = image->vk.samples == VK_SAMPLE_COUNT_1_BIT ? 1 : 2;
- v3dvx_pack(image_view->texture_shader_state[index], TEXTURE_SHADER_STATE, tex) {
-
- tex.level_0_is_strictly_uif =
- (image->slices[0].tiling == V3D_TILING_UIF_XOR ||
- image->slices[0].tiling == V3D_TILING_UIF_NO_XOR);
-
- tex.level_0_xor_enable = (image->slices[0].tiling == V3D_TILING_UIF_XOR);
-
- if (tex.level_0_is_strictly_uif)
- tex.level_0_ub_pad = image->slices[0].ub_pad;
-
- /* FIXME: v3d never sets uif_xor_disable, but uses it on the following
- * check so let's set the default value
- */
- tex.uif_xor_disable = false;
- if (tex.uif_xor_disable ||
- tex.level_0_is_strictly_uif) {
- tex.extended = true;
- }
-
- tex.base_level = image_view->vk.base_mip_level;
- tex.max_level = image_view->vk.base_mip_level +
- image_view->vk.level_count - 1;
-
- tex.swizzle_r = translate_swizzle(image_view->swizzle[0]);
- tex.swizzle_g = translate_swizzle(image_view->swizzle[1]);
- tex.swizzle_b = translate_swizzle(image_view->swizzle[2]);
- tex.swizzle_a = translate_swizzle(image_view->swizzle[3]);
-
- tex.texture_type = image_view->format->tex_type;
-
- if (image->vk.image_type == VK_IMAGE_TYPE_3D) {
- tex.image_depth = image->vk.extent.depth;
- } else {
- tex.image_depth = image_view->vk.layer_count;
+ for (uint8_t plane = 0; plane < image_view->plane_count; plane++) {
+ uint8_t iplane = image_view->planes[plane].image_plane;
+ v3dvx_pack(image_view->planes[plane].texture_shader_state[index], TEXTURE_SHADER_STATE, tex) {
+
+ tex.level_0_is_strictly_uif =
+ (image->planes[iplane].slices[0].tiling == V3D_TILING_UIF_XOR ||
+ image->planes[iplane].slices[0].tiling == V3D_TILING_UIF_NO_XOR);
+
+ tex.level_0_xor_enable = (image->planes[iplane].slices[0].tiling == V3D_TILING_UIF_XOR);
+
+ if (tex.level_0_is_strictly_uif)
+ tex.level_0_ub_pad = image->planes[iplane].slices[0].ub_pad;
+
+ /* FIXME: v3d never sets uif_xor_disable, but uses it on the following
+ * check so let's set the default value
+ */
+ tex.uif_xor_disable = false;
+ if (tex.uif_xor_disable ||
+ tex.level_0_is_strictly_uif) {
+ tex.extended = true;
+ }
+
+ tex.base_level = image_view->vk.base_mip_level;
+ tex.max_level = image_view->vk.base_mip_level +
+ image_view->vk.level_count - 1;
+
+ tex.swizzle_r = v3d_translate_pipe_swizzle(image_view->planes[plane].swizzle[0]);
+ tex.swizzle_g = v3d_translate_pipe_swizzle(image_view->planes[plane].swizzle[1]);
+ tex.swizzle_b = v3d_translate_pipe_swizzle(image_view->planes[plane].swizzle[2]);
+ tex.swizzle_a = v3d_translate_pipe_swizzle(image_view->planes[plane].swizzle[3]);
+
+ tex.texture_type = image_view->format->planes[plane].tex_type;
+
+ if (image->vk.image_type == VK_IMAGE_TYPE_3D) {
+ tex.image_depth = image->vk.extent.depth;
+ } else {
+ tex.image_depth = image_view->vk.layer_count;
+ }
+
+ /* Empirical testing with CTS shows that when we are sampling from cube
+ * arrays we want to set image depth to layers / 6, but not when doing
+ * image load/store.
+ */
+ if (image_view->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY &&
+ !for_cube_map_array_storage) {
+ assert(tex.image_depth % 6 == 0);
+ tex.image_depth /= 6;
+ }
+
+ tex.image_height = image->planes[iplane].height * msaa_scale;
+ tex.image_width = image->planes[iplane].width * msaa_scale;
+
+ /* On 4.x, the height of a 1D texture is redefined to be the
+ * upper 14 bits of the width (which is only usable with txf).
+ */
+ if (image->vk.image_type == VK_IMAGE_TYPE_1D)
+ tex.image_height = tex.image_width >> 14;
+
+ tex.image_width &= (1 << 14) - 1;
+ tex.image_height &= (1 << 14) - 1;
+
+ tex.array_stride_64_byte_aligned = image->planes[iplane].cube_map_stride / 64;
+
+ /* At this point we don't have the job. That's the reason the first
+ * parameter is NULL, to avoid a crash when cl_pack_emit_reloc tries to
+ * add the bo to the job. This also means that we need to add manually
+ * the image bo to the job using the texture.
+ */
+ const uint32_t base_offset =
+ image->planes[iplane].mem->bo->offset +
+ v3dv_layer_offset(image, 0, image_view->vk.base_array_layer,
+ iplane);
+ tex.texture_base_pointer = v3dv_cl_address(NULL, base_offset);
+
+ bool is_srgb = vk_format_is_srgb(image_view->vk.format);
+
+ /* V3D 4.x doesn't have the reverse and swap_r/b bits, so we compose
+ * the reverse and/or swap_r/b swizzle from the format table with the
+ * image view swizzle. This, however, doesn't work for border colors,
+ * for that there is the reverse_standard_border_color.
+ *
+ * In v3d 7.x, however, there is no reverse_standard_border_color bit,
+ * since the reverse and swap_r/b bits also affect border colors. It is
+ * because of this that we absolutely need to use these bits with
+ * reversed and swpaped formats, since that's the only way to ensure
+ * correct border colors. In that case we don't want to program the
+ * swizzle to the composition of the format swizzle and the view
+ * swizzle like we do in v3d 4.x, since the format swizzle is applied
+ * via the reverse and swap_r/b bits.
+ */
+#if V3D_VERSION == 42
+ tex.srgb = is_srgb;
+ tex.reverse_standard_border_color =
+ image_view->planes[plane].channel_reverse;
+#endif
+#if V3D_VERSION >= 71
+ tex.transfer_func = is_srgb ? TRANSFER_FUNC_SRGB : TRANSFER_FUNC_NONE;
+
+ tex.reverse = image_view->planes[plane].channel_reverse;
+ tex.r_b_swap = image_view->planes[plane].swap_rb;
+
+ if (tex.reverse || tex.r_b_swap) {
+ tex.swizzle_r =
+ v3d_translate_pipe_swizzle(image_view->view_swizzle[0]);
+ tex.swizzle_g =
+ v3d_translate_pipe_swizzle(image_view->view_swizzle[1]);
+ tex.swizzle_b =
+ v3d_translate_pipe_swizzle(image_view->view_swizzle[2]);
+ tex.swizzle_a =
+ v3d_translate_pipe_swizzle(image_view->view_swizzle[3]);
+ }
+
+ tex.chroma_offset_x = 1;
+ tex.chroma_offset_y = 1;
+ /* See comment in XML field definition for rationale of the shifts */
+ tex.texture_base_pointer_cb = base_offset >> 6;
+ tex.texture_base_pointer_cr = base_offset >> 6;
+#endif
}
-
- /* Empirical testing with CTS shows that when we are sampling from cube
- * arrays we want to set image depth to layers / 6, but not when doing
- * image load/store.
- */
- if (image_view->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY &&
- !for_cube_map_array_storage) {
- assert(tex.image_depth % 6 == 0);
- tex.image_depth /= 6;
- }
-
- tex.image_height = image->vk.extent.height * msaa_scale;
- tex.image_width = image->vk.extent.width * msaa_scale;
-
- /* On 4.x, the height of a 1D texture is redefined to be the
- * upper 14 bits of the width (which is only usable with txf).
- */
- if (image->vk.image_type == VK_IMAGE_TYPE_1D) {
- tex.image_height = tex.image_width >> 14;
- }
- tex.image_width &= (1 << 14) - 1;
- tex.image_height &= (1 << 14) - 1;
-
- tex.array_stride_64_byte_aligned = image->cube_map_stride / 64;
-
- tex.srgb = vk_format_is_srgb(image_view->vk.format);
-
- /* At this point we don't have the job. That's the reason the first
- * parameter is NULL, to avoid a crash when cl_pack_emit_reloc tries to
- * add the bo to the job. This also means that we need to add manually
- * the image bo to the job using the texture.
- */
- const uint32_t base_offset =
- image->mem->bo->offset +
- v3dv_layer_offset(image, 0, image_view->vk.base_array_layer);
- tex.texture_base_pointer = v3dv_cl_address(NULL, base_offset);
}
}
@@ -163,10 +184,14 @@ v3dX(pack_texture_shader_state_from_buffer_view)(struct v3dv_device *device,
const struct v3dv_buffer *buffer = buffer_view->buffer;
v3dvx_pack(buffer_view->texture_shader_state, TEXTURE_SHADER_STATE, tex) {
- tex.swizzle_r = translate_swizzle(PIPE_SWIZZLE_X);
- tex.swizzle_g = translate_swizzle(PIPE_SWIZZLE_Y);
- tex.swizzle_b = translate_swizzle(PIPE_SWIZZLE_Z);
- tex.swizzle_a = translate_swizzle(PIPE_SWIZZLE_W);
+ tex.swizzle_r =
+ v3d_translate_pipe_swizzle(buffer_view->format->planes[0].swizzle[0]);
+ tex.swizzle_g =
+ v3d_translate_pipe_swizzle(buffer_view->format->planes[0].swizzle[1]);
+ tex.swizzle_b =
+ v3d_translate_pipe_swizzle(buffer_view->format->planes[0].swizzle[2]);
+ tex.swizzle_a =
+ v3d_translate_pipe_swizzle(buffer_view->format->planes[0].swizzle[3]);
tex.image_depth = 1;
@@ -180,8 +205,16 @@ v3dX(pack_texture_shader_state_from_buffer_view)(struct v3dv_device *device,
tex.image_width &= (1 << 14) - 1;
tex.image_height &= (1 << 14) - 1;
- tex.texture_type = buffer_view->format->tex_type;
- tex.srgb = vk_format_is_srgb(buffer_view->vk_format);
+ assert(buffer_view->format->plane_count == 1);
+ tex.texture_type = buffer_view->format->planes[0].tex_type;
+
+ bool is_srgb = vk_format_is_srgb(buffer_view->vk_format);
+#if V3D_VERSION == 42
+ tex.srgb = is_srgb;
+#endif
+#if V3D_VERSION >= 71
+ tex.transfer_func = is_srgb ? TRANSFER_FUNC_SRGB : TRANSFER_FUNC_NONE;
+#endif
/* At this point we don't have the job. That's the reason the first
* parameter is NULL, to avoid a crash when cl_pack_emit_reloc tries to
@@ -194,5 +227,13 @@ v3dX(pack_texture_shader_state_from_buffer_view)(struct v3dv_device *device,
buffer_view->offset;
tex.texture_base_pointer = v3dv_cl_address(NULL, base_offset);
+
+#if V3D_VERSION >= 71
+ tex.chroma_offset_x = 1;
+ tex.chroma_offset_y = 1;
+ /* See comment in XML field definition for rationale of the shifts */
+ tex.texture_base_pointer_cb = base_offset >> 6;
+ tex.texture_base_pointer_cr = base_offset >> 6;
+#endif
}
}