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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35843>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user