diff --git a/src/broadcom/vulkan/v3dv_image.c b/src/broadcom/vulkan/v3dv_image.c index 395a7f467fa..4afc6437b45 100644 --- a/src/broadcom/vulkan/v3dv_image.c +++ b/src/broadcom/vulkan/v3dv_image.c @@ -551,7 +551,9 @@ v3dv_CreateImageView(VkDevice _device, const uint8_t *format_swizzle = v3dv_get_format_swizzle(device, format); util_format_compose_swizzles(format_swizzle, image_view_swizzle, iview->swizzle); - iview->swap_rb = iview->swizzle[0] == PIPE_SWIZZLE_Z; + + iview->swap_rb = v3dv_format_swizzle_needs_rb_swap(iview->swizzle); + iview->channel_reverse = v3dv_format_swizzle_needs_reverse(iview->swizzle); v3dv_X(device, pack_texture_shader_state)(device, iview); diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index b11b66adad0..36b07de5a08 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -598,6 +598,7 @@ struct v3dv_image_view { const struct v3dv_format *format; bool swap_rb; + bool channel_reverse; uint32_t internal_bpp; uint32_t internal_type; uint32_t offset; diff --git a/src/broadcom/vulkan/v3dvx_cmd_buffer.c b/src/broadcom/vulkan/v3dvx_cmd_buffer.c index 02c24c338be..3ec0c4d0e65 100644 --- a/src/broadcom/vulkan/v3dvx_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dvx_cmd_buffer.c @@ -116,6 +116,7 @@ cmd_buffer_render_pass_emit_load(struct v3dv_cmd_buffer *cmd_buffer, load.input_image_format = iview->format->rt_type; load.r_b_swap = iview->swap_rb; + load.channel_reverse = iview->channel_reverse; load.memory_format = slice->tiling; if (slice->tiling == V3D_TILING_UIF_NO_XOR || @@ -303,6 +304,7 @@ cmd_buffer_render_pass_emit_store(struct v3dv_cmd_buffer *cmd_buffer, store.output_image_format = iview->format->rt_type; store.r_b_swap = iview->swap_rb; + store.channel_reverse = iview->channel_reverse; store.memory_format = slice->tiling; if (slice->tiling == V3D_TILING_UIF_NO_XOR || diff --git a/src/broadcom/vulkan/v3dvx_device.c b/src/broadcom/vulkan/v3dvx_device.c index 0d23688c4dd..0bea6211d76 100644 --- a/src/broadcom/vulkan/v3dvx_device.c +++ b/src/broadcom/vulkan/v3dvx_device.c @@ -58,10 +58,30 @@ static union pipe_color_union encode_border_color( const struct v3dv_format *format = v3dX(get_format)(bc_info->format); + /* We use the swizzle in our format table to determine swizzle configuration + * for sampling as well as to decide if we need to use the Swap R/B and + * Reverse Channels bits for Tile Load/Store operations. The order of the + * R/B swap and Reverse operations matters and gives different swizzles. + * Our format table assumes that Reverse happens first and R/B Swap second. + * This seems to match semantics for texture sampling and Tile load/store, + * however, it seems that the semantics are reversed for custom border + * colors so we need to fix up the swizzle manually for this case. + */ + uint8_t swizzle[4]; + if (v3dv_format_swizzle_needs_reverse(format->swizzle) && + v3dv_format_swizzle_needs_rb_swap(format->swizzle)) { + swizzle[0] = PIPE_SWIZZLE_W; + swizzle[1] = PIPE_SWIZZLE_X; + swizzle[2] = PIPE_SWIZZLE_Y; + swizzle[3] = PIPE_SWIZZLE_Z; + } else { + memcpy(swizzle, format->swizzle, sizeof (swizzle)); + } + union pipe_color_union border; for (int i = 0; i < 4; i++) { if (format->swizzle[i] <= 3) - border.ui[i] = bc_info->customBorderColor.uint32[format->swizzle[i]]; + border.ui[i] = bc_info->customBorderColor.uint32[swizzle[i]]; else border.ui[i] = 0; } diff --git a/src/broadcom/vulkan/v3dvx_image.c b/src/broadcom/vulkan/v3dvx_image.c index 292ac7c9736..06deb25aba7 100644 --- a/src/broadcom/vulkan/v3dvx_image.c +++ b/src/broadcom/vulkan/v3dvx_image.c @@ -98,6 +98,8 @@ pack_texture_shader_state_helper(struct v3dv_device *device, tex.swizzle_b = translate_swizzle(image_view->swizzle[2]); tex.swizzle_a = translate_swizzle(image_view->swizzle[3]); + tex.reverse_standard_border_color = image_view->channel_reverse; + tex.texture_type = image_view->format->tex_type; if (image->vk.image_type == VK_IMAGE_TYPE_3D) { diff --git a/src/broadcom/vulkan/v3dvx_meta_common.c b/src/broadcom/vulkan/v3dvx_meta_common.c index 5c775200234..93a6f0c609a 100644 --- a/src/broadcom/vulkan/v3dvx_meta_common.c +++ b/src/broadcom/vulkan/v3dvx_meta_common.c @@ -307,7 +307,15 @@ format_needs_rb_swap(struct v3dv_device *device, VkFormat format) { const uint8_t *swizzle = v3dv_get_format_swizzle(device, format); - return swizzle[0] == PIPE_SWIZZLE_Z; + return v3dv_format_swizzle_needs_rb_swap(swizzle); +} + +static inline bool +format_needs_reverse(struct v3dv_device *device, + VkFormat format) +{ + const uint8_t *swizzle = v3dv_get_format_swizzle(device, format); + return v3dv_format_swizzle_needs_reverse(swizzle); } static void @@ -373,6 +381,7 @@ emit_image_load(struct v3dv_device *device, * so we need to make sure we respect the format swizzle. */ needs_rb_swap = format_needs_rb_swap(device, framebuffer->vk_format); + needs_chan_reverse = format_needs_reverse(device, framebuffer->vk_format); } load.r_b_swap = needs_rb_swap; @@ -430,6 +439,7 @@ emit_image_store(struct v3dv_device *device, } else if (!is_copy_from_buffer && !is_copy_to_buffer && (aspect & VK_IMAGE_ASPECT_COLOR_BIT)) { needs_rb_swap = format_needs_rb_swap(device, framebuffer->vk_format); + needs_chan_reverse = format_needs_reverse(device, framebuffer->vk_format); } store.r_b_swap = needs_rb_swap;