From f6bdb8cd06d0198a37069bf456262c64af64d0ff Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Fri, 27 Jun 2025 17:23:52 -0400 Subject: [PATCH] nvk/copy: Set the gob_kind for tiled copies on Blackwell+ This is needed on blackwell to deal with kind/bpp interactions. Part-of: --- src/nouveau/vulkan/nvk_cmd_copy.c | 59 ++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/src/nouveau/vulkan/nvk_cmd_copy.c b/src/nouveau/vulkan/nvk_cmd_copy.c index ee0fe61f88d..e8f58ecb2bc 100644 --- a/src/nouveau/vulkan/nvk_cmd_copy.c +++ b/src/nouveau/vulkan/nvk_cmd_copy.c @@ -19,6 +19,7 @@ #include "nv_push_cl902d.h" #include "nv_push_cl90b5.h" #include "nv_push_clc1b5.h" +#include "nv_push_clc9b5.h" static inline uint16_t nvk_cmd_buffer_copy_cls(struct nvk_cmd_buffer *cmd) @@ -169,6 +170,19 @@ to_90b5_remap_num_comps(uint8_t num_comps) return num_comps_90b5; } +static uint32_t +nil_to_nvc9b5_gob_type(enum nil_gob_type gob_type) +{ + switch (gob_type) { + case NIL_GOB_TYPE_TURING_COLOR2_D: return 0; + case NIL_GOB_TYPE_BLACKWELL8_BIT: return 1; + case NIL_GOB_TYPE_BLACKWELL16_BIT: return 2; + case NIL_GOB_TYPE_BLACKWELL_Z24: return 3; + default: + unreachable("Invalid GOB type on Blackwell+"); + } +} + static void nouveau_copy_rect(struct nvk_cmd_buffer *cmd, struct nouveau_copy *copy) { @@ -242,12 +256,23 @@ nouveau_copy_rect(struct nvk_cmd_buffer *cmd, struct nouveau_copy *copy) if (copy->src.tiling.gob_type != NIL_GOB_TYPE_LINEAR) { P_MTHD(p, NV90B5, SET_SRC_BLOCK_SIZE); assert(nil_gob_type_height(copy->src.tiling.gob_type) == 8); - P_NV90B5_SET_SRC_BLOCK_SIZE(p, { - .width = 0, /* Tiles are always 1 GOB wide */ - .height = copy->src.tiling.y_log2, - .depth = copy->src.tiling.z_log2, - .gob_height = GOB_HEIGHT_GOB_HEIGHT_FERMI_8, - }); + + if (nvk_cmd_buffer_copy_cls(cmd) >= BLACKWELL_DMA_COPY_A) { + P_NVC9B5_SET_SRC_BLOCK_SIZE(p, { + .width = 0, /* Tiles are always 1 GOB wide */ + .height = copy->src.tiling.y_log2, + .depth = copy->src.tiling.z_log2, + .gob_height = GOB_HEIGHT_GOB_HEIGHT_FERMI_8, + .gob_kind = nil_to_nvc9b5_gob_type(copy->src.tiling.gob_type), + }); + } else { + P_NV90B5_SET_SRC_BLOCK_SIZE(p, { + .width = 0, /* Tiles are always 1 GOB wide */ + .height = copy->src.tiling.y_log2, + .depth = copy->src.tiling.z_log2, + .gob_height = GOB_HEIGHT_GOB_HEIGHT_FERMI_8, + }); + } /* We use the stride for copies because the copy hardware has no * concept of a tile width. Instead, we just set the width to the * stride divided by bpp. @@ -282,12 +307,22 @@ nouveau_copy_rect(struct nvk_cmd_buffer *cmd, struct nouveau_copy *copy) if (copy->dst.tiling.gob_type != NIL_GOB_TYPE_LINEAR) { P_MTHD(p, NV90B5, SET_DST_BLOCK_SIZE); assert(nil_gob_type_height(copy->dst.tiling.gob_type) == 8); - P_NV90B5_SET_DST_BLOCK_SIZE(p, { - .width = 0, /* Tiles are always 1 GOB wide */ - .height = copy->dst.tiling.y_log2, - .depth = copy->dst.tiling.z_log2, - .gob_height = GOB_HEIGHT_GOB_HEIGHT_FERMI_8, - }); + if (nvk_cmd_buffer_copy_cls(cmd) >= BLACKWELL_DMA_COPY_A) { + P_NVC9B5_SET_DST_BLOCK_SIZE(p, { + .width = 0, /* Tiles are always 1 GOB wide */ + .height = copy->dst.tiling.y_log2, + .depth = copy->dst.tiling.z_log2, + .gob_height = GOB_HEIGHT_GOB_HEIGHT_FERMI_8, + .gob_kind = nil_to_nvc9b5_gob_type(copy->dst.tiling.gob_type), + }); + } else { + P_NV90B5_SET_DST_BLOCK_SIZE(p, { + .width = 0, /* Tiles are always 1 GOB wide */ + .height = copy->dst.tiling.y_log2, + .depth = copy->dst.tiling.z_log2, + .gob_height = GOB_HEIGHT_GOB_HEIGHT_FERMI_8, + }); + } /* We use the stride for copies because the copy hardware has no * concept of a tile width. Instead, we just set the width to the * stride divided by bpp.