From 1f990187ca33f48a9b14ae7acc03a5c67fd08b39 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 12 Jun 2025 07:57:34 +1000 Subject: [PATCH] nvk: add support for separate depth/stencil for blackwell Blackwell uses separate ds storage on blackwell for d32s8, optionally for d24s8, but I've used it here because I could make it work. Part-of: --- src/nouveau/headers/nv_push.h | 1 + src/nouveau/headers/nvidia/classes/clcd97.h | 42 +++++++ src/nouveau/vulkan/nvk_cmd_draw.c | 118 +++++++++++++++----- 3 files changed, 136 insertions(+), 25 deletions(-) diff --git a/src/nouveau/headers/nv_push.h b/src/nouveau/headers/nv_push.h index 98f61210cc1..11eb5fc386b 100644 --- a/src/nouveau/headers/nv_push.h +++ b/src/nouveau/headers/nv_push.h @@ -60,6 +60,7 @@ void vk_push_print(FILE *fp, const struct nv_push *push, #define SUBC_NVC797 0 #define SUBC_NVC86F 0 #define SUBC_NVCB97 0 +#define SUBC_NVCD97 0 #define SUBC_NV90C0 1 #define SUBC_NVA0C0 1 diff --git a/src/nouveau/headers/nvidia/classes/clcd97.h b/src/nouveau/headers/nvidia/classes/clcd97.h index 284300f3724..5ba8b89c832 100644 --- a/src/nouveau/headers/nvidia/classes/clcd97.h +++ b/src/nouveau/headers/nvidia/classes/clcd97.h @@ -3,4 +3,46 @@ #define BLACKWELL_A 0xCD97 +#define NVCD97_SET_ST_A 0x0f00 +#define NVCD97_SET_ST_A_OFFSET_UPPER 7:0 + +#define NVCD97_SET_ST_B 0x0f04 +#define NVCD97_SET_ST_B_OFFSET_LOWER 31:0 + +#define NVCD97_SET_ST_BLOCK_SIZE 0x0f08 +#define NVCD97_SET_ST_BLOCK_SIZE_WIDTH 3:0 +#define NVCD97_SET_ST_BLOCK_SIZE_WIDTH_ONE_GOB 0x00000000 +#define NVCD97_SET_ST_BLOCK_SIZE_HEIGHT 7:4 +#define NVCD97_SET_ST_BLOCK_SIZE_HEIGHT_ONE_GOB 0x00000000 +#define NVCD97_SET_ST_BLOCK_SIZE_HEIGHT_TWO_GOBS 0x00000001 +#define NVCD97_SET_ST_BLOCK_SIZE_HEIGHT_FOUR_GOBS 0x00000002 +#define NVCD97_SET_ST_BLOCK_SIZE_HEIGHT_EIGHT_GOBS 0x00000003 +#define NVCD97_SET_ST_BLOCK_SIZE_HEIGHT_SIXTEEN_GOBS 0x00000004 +#define NVCD97_SET_ST_BLOCK_SIZE_HEIGHT_THIRTYTWO_GOBS 0x00000005 +#define NVCD97_SET_ST_BLOCK_SIZE_DEPTH 11:8 +#define NVCD97_SET_ST_BLOCK_SIZE_DEPTH_ONE_GOB 0x00000000 + +#define NVCD97_SET_ST_ARRAY_PITCH 0x0f0c +#define NVCD97_SET_ST_ARRAY_PITCH_V 31:0 + +#define NVCD97_SET_ZT_FORMAT 0x0fe8 +#define NVCD97_SET_ZT_FORMAT_V 4:0 +#define NVCD97_SET_ZT_FORMAT_V_Z16 0x00000013 +#define NVCD97_SET_ZT_FORMAT_V_Z24S8 0x00000014 +#define NVCD97_SET_ZT_FORMAT_V_X8Z24 0x00000015 +#define NVCD97_SET_ZT_FORMAT_V_S8Z24 0x00000016 +#define NVCD97_SET_ZT_FORMAT_V_S8 0x00000017 +#define NVCD97_SET_ZT_FORMAT_V_ZF32 0x0000000A +#define NVCD97_SET_ZT_FORMAT_V_ZF32_X24S8 0x00000019 +#define NVCD97_SET_ZT_FORMAT_STENCIL_IS_SEPARATE 8:8 +#define NVCD97_SET_ZT_FORMAT_STENCIL_IS_SEPARATE_FALSE 0x00000000 +#define NVCD97_SET_ZT_FORMAT_STENCIL_IS_SEPARATE_TRUE 0x00000001 + +// equivalent of SET_ZT_SIZE_[AB] +#define NVCD97_SET_ST_SIZE_A 0x120c +#define NVCD97_SET_ST_SIZE_A_WIDTH 27:0 + +#define NVCD97_SET_ST_SIZE_B 0x1210 +#define NVCD97_SET_ST_SIZE_B_HEIGHT 17:0 + #endif diff --git a/src/nouveau/vulkan/nvk_cmd_draw.c b/src/nouveau/vulkan/nvk_cmd_draw.c index 03d5aa20cfe..eb7e3b7e33f 100644 --- a/src/nouveau/vulkan/nvk_cmd_draw.c +++ b/src/nouveau/vulkan/nvk_cmd_draw.c @@ -29,6 +29,7 @@ #include "nv_push_clc397.h" #include "nv_push_clc597.h" #include "nv_push_clcb97.h" +#include "nv_push_clcd97.h" #include "clcb97.h" #include "clcd97.h" #include "drf.h" @@ -954,11 +955,51 @@ nvk_rendering_linear(const struct nvk_rendering_state *render) return true; } +static void +get_depth_stencil_plane_params(struct nvk_image_view *iview, + uint32_t plane, + uint32_t layer_count, + uint64_t *addr_out, + uint32_t *base_array_layer_out, + uint32_t *mip_level_out, + struct nil_image *image_out) +{ + const struct nvk_image *image = (struct nvk_image *)iview->vk.image; + struct nil_image nil_image = image->planes[plane].nil; + + uint64_t addr = nvk_image_base_address(image, plane); + uint32_t mip_level = iview->vk.base_mip_level; + uint32_t base_array_layer = iview->vk.base_array_layer; + + if (nil_image.dim == NIL_IMAGE_DIM_3D) { + uint64_t level_offset_B; + nil_image = nil_image_3d_level_as_2d_array(&nil_image, mip_level, + &level_offset_B); + addr += level_offset_B; + mip_level = 0; + base_array_layer = 0; + assert(layer_count <= iview->vk.extent.depth); + } else { + assert(layer_count <= iview->vk.layer_count); + } + + const struct nil_image_level *level = &nil_image.levels[mip_level]; + addr += level->offset_B; + + *addr_out = addr; + *base_array_layer_out = base_array_layer; + *mip_level_out = mip_level; + *image_out = nil_image; +} + + VKAPI_ATTR void VKAPI_CALL nvk_CmdBeginRendering(VkCommandBuffer commandBuffer, const VkRenderingInfo *pRenderingInfo) { VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer); + struct nvk_device *dev = nvk_cmd_buffer_device(cmd); + const struct nvk_physical_device *pdev = nvk_device_physical(dev); struct nvk_rendering_state *render = &cmd->state.gfx.render; memset(render, 0, sizeof(*render)); @@ -1006,7 +1047,7 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer, nvk_cmd_buffer_dirty_render_pass(cmd); - struct nv_push *p = nvk_cmd_buffer_push(cmd, NVK_MAX_RTS * 12 + 34); + struct nv_push *p = nvk_cmd_buffer_push(cmd, NVK_MAX_RTS * 12 + 44); P_IMMD(p, NV9097, SET_MME_SHADOW_SCRATCH(NVK_MME_SCRATCH_VIEW_MASK), render->view_mask); @@ -1161,31 +1202,17 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer, struct nvk_image_view *iview = render->depth_att.iview ? render->depth_att.iview : render->stencil_att.iview; + const struct nvk_image *image = (struct nvk_image *)iview->vk.image; - /* Depth/stencil are always single-plane */ - assert(iview->plane_count == 1); - const uint8_t ip = iview->planes[0].image_plane; - struct nil_image nil_image = image->planes[ip].nil; - uint64_t addr = nvk_image_base_address(image, ip); - uint32_t mip_level = iview->vk.base_mip_level; - uint32_t base_array_layer = iview->vk.base_array_layer; - - if (nil_image.dim == NIL_IMAGE_DIM_3D) { - uint64_t level_offset_B; - nil_image = nil_image_3d_level_as_2d_array(&nil_image, mip_level, - &level_offset_B); - addr += level_offset_B; - mip_level = 0; - base_array_layer = 0; - assert(layer_count <= iview->vk.extent.depth); - } else { - assert(layer_count <= iview->vk.layer_count); - } + uint64_t addr; + uint32_t base_array_layer, mip_level; + struct nil_image nil_image; + get_depth_stencil_plane_params(iview, 0, layer_count, &addr, + &base_array_layer, &mip_level, + &nil_image); const struct nil_image_level *level = &nil_image.levels[mip_level]; - addr += level->offset_B; - assert(sample_layout == NIL_SAMPLE_LAYOUT_INVALID || sample_layout == nil_image.sample_layout); sample_layout = nil_image.sample_layout; @@ -1194,10 +1221,22 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer, P_MTHD(p, NV9097, SET_ZT_A); P_NV9097_SET_ZT_A(p, addr >> 32); P_NV9097_SET_ZT_B(p, addr); - const enum pipe_format p_format = + + /* We want the combined Z/S format for the SET_ZT_FORMAT packet */ + const enum pipe_format zs_p_format = nvk_format_to_pipe_format(iview->vk.format); - const uint8_t zs_format = nil_format_to_depth_stencil(p_format); - P_NV9097_SET_ZT_FORMAT(p, zs_format); + const uint8_t zs_format = nil_format_to_depth_stencil(zs_p_format); + + if (pdev->info.cls_eng3d >= BLACKWELL_A) { + P_NVCD97_SET_ZT_FORMAT(p, { + .v = zs_format, + .stencil_is_separate = image->separate_zs, + }); + } else { + assert(!image->separate_zs); + P_NV9097_SET_ZT_FORMAT(p, zs_format); + } + assert(level->tiling.gob_type != NIL_GOB_TYPE_LINEAR); assert(level->tiling.z_log2 == 0); P_NV9097_SET_ZT_BLOCK_SIZE(p, { @@ -1216,6 +1255,7 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer, * has no concept of a tile width. Instead, we just set the width to * the stride divided by bpp. */ + enum pipe_format p_format = nil_image.format.p_format; const uint32_t row_stride_el = level->row_stride_B / util_format_get_blocksize(p_format); @@ -1236,6 +1276,34 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer, .enable = ENABLE_FALSE, }); } + + if (nvk_cmd_buffer_3d_cls(cmd) >= BLACKWELL_A && + (image->separate_zs || image->vk.format == VK_FORMAT_S8_UINT)) { + get_depth_stencil_plane_params(iview, image->separate_zs, layer_count, + &addr, &base_array_layer, &mip_level, + &nil_image); + struct nil_Extent4D_Samples level_extent_sa = + nil_image_level_extent_sa(&nil_image, mip_level); + p_format = nil_image.format.p_format; + const uint32_t row_stride_el = + level->row_stride_B / util_format_get_blocksize(p_format); + + P_MTHD(p, NVCD97, SET_ST_A); + P_NVCD97_SET_ST_A(p, addr >> 32); + P_NVCD97_SET_ST_B(p, addr); + + P_MTHD(p, NVCD97, SET_ST_BLOCK_SIZE); + P_NVCD97_SET_ST_BLOCK_SIZE(p, { + .width = WIDTH_ONE_GOB, + .height = level->tiling.y_log2, + .depth = DEPTH_ONE_GOB, + }); + P_NVCD97_SET_ST_ARRAY_PITCH(p, nil_image.array_stride_B >> 2); + + P_MTHD(p, NVCD97, SET_ST_SIZE_A); + P_NVCD97_SET_ST_SIZE_A(p, row_stride_el); + P_NVCD97_SET_ST_SIZE_B(p, level_extent_sa.height); + } } else { P_IMMD(p, NV9097, SET_ZT_SELECT, 0 /* target_count */); }