#include "v3dv_private.h"
#include "broadcom/cle/v3dx_pack.h"
#include "util/u_pack_color.h"
+#include "vk_format_info.h"
const struct v3dv_dynamic_state default_dynamic_state = {
.viewport = {
/* FIXME: resolve attachments */
- /* FIXME: also check depth/stencil attachment */
+ if (subpass->ds_attachment.attachment !=
+ prev_subpass->ds_attachment.attachment)
+ return false;
return true;
}
cl_emit(&job->bcl, TILE_BINNING_MODE_CFG, config) {
config.width_in_pixels = framebuffer->width;
config.height_in_pixels = framebuffer->height;
- config.number_of_render_targets = MAX2(framebuffer->attachment_count, 1);
+ config.number_of_render_targets =
+ MAX2(framebuffer->color_attachment_count, 1);
config.multisample_mode_4x = false; /* FIXME */
config.maximum_bpp_of_all_render_targets = framebuffer->internal_bpp;
}
}
static void
+cmd_buffer_state_set_attachment_clear_depth_stencil(
+ struct v3dv_cmd_buffer *cmd_buffer,
+ uint32_t attachment_idx,
+ bool clear_depth, bool clear_stencil,
+ const VkClearDepthStencilValue *ds)
+{
+ struct v3dv_cmd_buffer_attachment_state *attachment_state =
+ &cmd_buffer->state.attachments[attachment_idx];
+
+ if (clear_depth)
+ attachment_state->clear_value.z = ds->depth;
+
+ if (clear_stencil)
+ attachment_state->clear_value.s = ds->stencil;
+}
+
+static void
cmd_buffer_state_set_clear_values(struct v3dv_cmd_buffer *cmd_buffer,
uint32_t count, const VkClearValue *values)
{
if (attachment->desc.loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR)
continue;
- /* FIXME: support depth/stencil */
- cmd_buffer_state_set_attachment_clear_color(cmd_buffer, i,
- &values[i].color);
+ VkImageAspectFlags aspects = vk_format_aspects(attachment->desc.format);
+ if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
+ cmd_buffer_state_set_attachment_clear_color(cmd_buffer, i,
+ &values[i].color);
+ } else if (aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
+ VK_IMAGE_ASPECT_STENCIL_BIT)) {
+ cmd_buffer_state_set_attachment_clear_depth_stencil(
+ cmd_buffer, i,
+ aspects & VK_IMAGE_ASPECT_DEPTH_BIT,
+ aspects & VK_IMAGE_ASPECT_STENCIL_BIT,
+ &values[i].depthStencil);
+ }
}
}
const struct v3dv_framebuffer *framebuffer = state->framebuffer;
assert(attachment_idx < framebuffer->attachment_count);
struct v3dv_image_view *iview = framebuffer->attachments[attachment_idx];
+ assert(iview->aspects & VK_IMAGE_ASPECT_COLOR_BIT);
*rt_bpp = iview->internal_bpp;
*rt_type = iview->internal_type;
}
}
+ uint32_t ds_attachment_idx = subpass->ds_attachment.attachment;
+ if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
+ const struct v3dv_render_pass_attachment *ds_attachment =
+ &state->pass->attachments[ds_attachment_idx];
+ const struct v3dv_cmd_buffer_attachment_state *ds_attachment_state =
+ &state->attachments[ds_attachment_idx];
+
+ assert(state->job->first_subpass >= ds_attachment_state->first_subpass);
+ bool needs_load =
+ state->job->first_subpass > ds_attachment_state->first_subpass ||
+ ds_attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_LOAD;
+
+ if (needs_load) {
+ struct v3dv_image_view *iview =
+ framebuffer->attachments[ds_attachment_idx];
+ cmd_buffer_render_pass_emit_load(cmd_buffer, cl, iview, layer, Z);
+ }
+ }
+
cl_emit(cl, END_OF_LOADS, end);
}
has_stores = true;
}
- /* FIXME: depth/stencil store
+ /* FIXME: separate stencil
*
* GFXH-1461/GFXH-1689: The per-buffer store command's clear
* buffer bit is broken for depth/stencil. In addition, the
* not want to do that. We might want to consider emitting clears for
* all RTs needing clearing just once ahead of the first subpass.
*/
+ bool needs_ds_clear = false;
+ uint32_t ds_attachment_idx = subpass->ds_attachment.attachment;
+ if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
+ const struct v3dv_render_pass_attachment *ds_attachment =
+ &state->pass->attachments[ds_attachment_idx];
+ const struct v3dv_cmd_buffer_attachment_state *ds_attachment_state =
+ &state->attachments[ds_attachment_idx];
+
+ /* Only clear once on the first subpass that uses the attachment */
+ assert(state->job->first_subpass >= ds_attachment_state->first_subpass);
+ needs_ds_clear =
+ state->job->first_subpass == ds_attachment_state->first_subpass &&
+ ds_attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR;
+
+ cmd_buffer_render_pass_emit_store(cmd_buffer, cl,
+ ds_attachment_idx, layer,
+ Z, needs_ds_clear);
+ has_stores = true;
+ }
/* We always need to emit at least one dummy store */
if (!has_stores) {
store.buffer_to_store = NONE;
}
}
+
+ /* FIXME: see fixme remark for depth/stencil above */
+ if (needs_ds_clear) {
+ cl_emit(cl, CLEAR_TILE_BUFFERS, clear) {
+ clear.clear_z_stencil_buffer = true;
+ clear.clear_all_render_targets = true;
+ }
+ }
}
static void
* Z_STENCIL_CLEAR_VALUES must be last. The ones in between are optional
* updates to the previous HW state.
*/
+ const uint32_t ds_attachment_idx = subpass->ds_attachment.attachment;
+
cl_emit(rcl, TILE_RENDERING_MODE_CFG_COMMON, config) {
- config.early_z_disable = true; /* FIXME */
config.image_width_pixels = framebuffer->width;
config.image_height_pixels = framebuffer->height;
config.number_of_render_targets = MAX2(subpass->color_count, 1);
config.multisample_mode_4x = false; /* FIXME */
config.maximum_bpp_of_all_render_targets = framebuffer->internal_bpp;
+
+ if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
+ const struct v3dv_image_view *iview =
+ framebuffer->attachments[ds_attachment_idx];
+ config.internal_depth_type = iview->internal_type;
+ config.early_z_disable = true; /* FIXME */
+ } else {
+ config.early_z_disable = true;
+ }
}
for (uint32_t i = 0; i < subpass->color_count; i++) {
}
/* Ends rendering mode config. */
- cl_emit(rcl, TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES, clear) {
- clear.z_clear_value = 0; /* FIXME */
- clear.stencil_clear_value = 0; /* FIXME */
- };
+ if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
+ cl_emit(rcl, TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES, clear) {
+ clear.z_clear_value =
+ state->attachments[ds_attachment_idx].clear_value.z;
+ clear.stencil_clear_value =
+ state->attachments[ds_attachment_idx].clear_value.s;
+ };
+ } else {
+ cl_emit(rcl, TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES, clear) {
+ clear.z_clear_value = 1.0f;
+ clear.stencil_clear_value = 0;
+ };
+ }
/* Always set initial block size before the first branch, which needs
* to match the value from binning mode config.
#define SWIZ_000X SWIZ(0, 0, 0, X)
static const struct v3dv_format format_table[] = {
- FORMAT(R8G8B8A8_SRGB, SRGB8_ALPHA8, RGBA8, SWIZ_XYZW, 16),
- FORMAT(B8G8R8A8_SRGB, SRGB8_ALPHA8, RGBA8, SWIZ_ZYXW, 16),
- FORMAT(R8G8B8A8_UNORM, RGBA8, RGBA8, SWIZ_XYZW, 16),
- FORMAT(B8G8R8A8_UNORM, RGBA8, RGBA8, SWIZ_ZYXW, 16),
- FORMAT(R32G32B32A32_SFLOAT, RGBA32F, RGBA32F, SWIZ_XYZW, 32),
+ /* Color */
+ FORMAT(R8G8B8A8_SRGB, SRGB8_ALPHA8, RGBA8, SWIZ_XYZW, 16),
+ FORMAT(B8G8R8A8_SRGB, SRGB8_ALPHA8, RGBA8, SWIZ_ZYXW, 16),
+ FORMAT(R8G8B8A8_UNORM, RGBA8, RGBA8, SWIZ_XYZW, 16),
+ FORMAT(B8G8R8A8_UNORM, RGBA8, RGBA8, SWIZ_ZYXW, 16),
+ FORMAT(R32G32B32A32_SFLOAT, RGBA32F, RGBA32F, SWIZ_XYZW, 32),
+ FORMAT(R32G32B32A32_SFLOAT, RGBA32F, RGBA32F, SWIZ_XYZW, 32),
+
+ /* Depth */
+ FORMAT(D16_UNORM, D16, DEPTH_COMP16, SWIZ_XXXX, 32),
+ FORMAT(D32_SFLOAT, D32F, DEPTH_COMP32F, SWIZ_XXXX, 32),
+ FORMAT(X8_D24_UNORM_PACK32, D24S8, DEPTH24_X8, SWIZ_XXXX, 32),
};
const struct v3dv_format *
const VkImageAspectFlags aspects = vk_format_aspects(vk_format);
- if (aspects != VK_IMAGE_ASPECT_COLOR_BIT)
+ const uint32_t supported_aspects =
+ VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
+ if ((aspects & supported_aspects) != aspects)
return 0;
VkFormatFeatureFlags flags =
VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
if (v3dv_format->rt_type != V3D_OUTPUT_IMAGE_FORMAT_NO) {
- flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
- VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT |
- VK_FORMAT_FEATURE_BLIT_DST_BIT;
+ flags |= VK_FORMAT_FEATURE_BLIT_DST_BIT;
+ if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
+ flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
+ } else if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
+ flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ }
}
return flags;