v3dv: implement support for depth testing

This ignores stencil for now and focuses on depth testing without
support for early depth testing.

To implement this we need to start considering how many of our
framebuffer attachments are color attachments, since some of the
computations we use to determine tile sizes and binning configuration
depend on this.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Iago Toral Quiroga 2020-01-28 13:03:41 +01:00 committed by Marge Bot
parent c005a18a56
commit 4d0e497a3e
7 changed files with 142 additions and 30 deletions

View File

@ -24,6 +24,7 @@
#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 = {
@ -238,7 +239,9 @@ cmd_buffer_can_merge_subpass(struct v3dv_cmd_buffer *cmd_buffer)
/* FIXME: resolve attachments */
/* FIXME: also check depth/stencil attachment */
if (subpass->ds_attachment.attachment !=
prev_subpass->ds_attachment.attachment)
return false;
return true;
}
@ -295,7 +298,8 @@ v3dv_cmd_buffer_start_frame(struct v3dv_cmd_buffer *cmd_buffer,
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;
}
@ -562,6 +566,23 @@ cmd_buffer_state_set_attachment_clear_color(struct v3dv_cmd_buffer *cmd_buffer,
}
}
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)
@ -577,9 +598,18 @@ cmd_buffer_state_set_clear_values(struct v3dv_cmd_buffer *cmd_buffer,
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);
}
}
}
@ -701,6 +731,7 @@ setup_render_target(struct v3dv_cmd_buffer *cmd_buffer, int rt,
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;
@ -788,6 +819,25 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer,
}
}
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);
}
@ -869,7 +919,7 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer,
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
@ -882,6 +932,25 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer,
* 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) {
@ -889,6 +958,14 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer,
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
@ -1054,13 +1131,23 @@ cmd_buffer_emit_render_pass_rcl(struct v3dv_cmd_buffer *cmd_buffer)
* 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++) {
@ -1143,10 +1230,19 @@ cmd_buffer_emit_render_pass_rcl(struct v3dv_cmd_buffer *cmd_buffer)
}
/* 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.

View File

@ -1659,7 +1659,9 @@ compute_internal_bpp_from_attachments(struct v3dv_framebuffer *framebuffer)
uint8_t max_bpp = RENDER_TARGET_MAXIMUM_32BPP;
for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
const struct v3dv_image_view *att = framebuffer->attachments[i];
if (att)
assert(att);
if (att->aspects & VK_IMAGE_ASPECT_COLOR_BIT)
max_bpp = MAX2(max_bpp, att->internal_bpp);
}
framebuffer->internal_bpp = max_bpp;
@ -1680,9 +1682,9 @@ v3dv_framebuffer_compute_tiling_params(struct v3dv_framebuffer *framebuffer)
/* FIXME: MSAA */
if (framebuffer->attachment_count > 2)
if (framebuffer->color_attachment_count > 2)
tile_size_index += 2;
else if (framebuffer->attachment_count > 1)
else if (framebuffer->color_attachment_count > 1)
tile_size_index += 1;
tile_size_index += framebuffer->internal_bpp;
@ -1739,9 +1741,12 @@ v3dv_CreateFramebuffer(VkDevice _device,
framebuffer->height = pCreateInfo->height;
framebuffer->layers = pCreateInfo->layers;
framebuffer->attachment_count = pCreateInfo->attachmentCount;
framebuffer->color_attachment_count = 0;
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
framebuffer->attachments[i] =
v3dv_image_view_from_handle(pCreateInfo->pAttachments[i]);
if (framebuffer->attachments[i]->aspects & VK_IMAGE_ASPECT_COLOR_BIT)
framebuffer->color_attachment_count++;
}
compute_internal_bpp_from_attachments(framebuffer);

View File

@ -60,11 +60,18 @@
#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 *
@ -228,7 +235,9 @@ image_format_features(VkFormat vk_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 =
@ -239,9 +248,13 @@ image_format_features(VkFormat vk_format,
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;

View File

@ -411,10 +411,6 @@ v3dv_CreateImageView(VkDevice _device,
assert(range->layerCount > 0);
assert(range->baseMipLevel < image->levels);
/* FIXME: we don't handle depth/stencil yet */
assert((range->aspectMask &
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0);
#ifdef DEBUG
switch (image->type) {
case VK_IMAGE_TYPE_1D:

View File

@ -285,6 +285,7 @@ setup_framebuffer_params(struct v3dv_framebuffer *fb,
* only the framebuffer size and the internal bpp.
*/
fb->attachment_count = 0;
fb->color_attachment_count = 0;
v3dv_framebuffer_compute_tiling_params(fb);
}

View File

@ -963,10 +963,10 @@ pack_cfg_bits(struct v3dv_pipeline *pipeline,
/* Note: ez state may update based on the compiled FS, along with zsa
* (FIXME: not done)
*/
config.early_z_updates_enable = true;
config.early_z_updates_enable = false;
if (ds_info && ds_info->depthTestEnable) {
config.z_updates_enable = false;
config.early_z_enable = config.early_z_enable;
config.z_updates_enable = true;
config.early_z_enable = false;
config.depth_test_function = ds_info->depthCompareOp;
} else {
config.depth_test_function = VK_COMPARE_OP_ALWAYS;

View File

@ -386,6 +386,7 @@ struct v3dv_framebuffer {
uint32_t frame_height_in_supertiles;
uint32_t attachment_count;
uint32_t color_attachment_count;
struct v3dv_image_view *attachments[0];
};