nvk: Implement shaderStorageImageMultisample

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9660
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28159>
This commit is contained in:
Faith Ekstrand
2024-03-12 12:20:13 -05:00
committed by Marge Bot
parent 357720c5a7
commit 7604697ec6
8 changed files with 99 additions and 5 deletions

View File

@@ -114,6 +114,11 @@ write_storage_image_view_desc(struct nvk_descriptor_set *set,
assert(view->planes[plane].storage_desc_index < (1 << 20));
desc.image_index = view->planes[plane].storage_desc_index;
const struct nil_extent4d px_extent_sa =
nil_px_extent_sa(view->planes[plane].sample_layout);
desc.sw_log2 = util_logbase2(px_extent_sa.w);
desc.sh_log2 = util_logbase2(px_extent_sa.h);
}
write_desc(set, binding, elem, &desc, sizeof(desc));

View File

@@ -26,7 +26,9 @@ static_assert(sizeof(struct nvk_sampled_image_descriptor) == 4,
struct nvk_storage_image_descriptor {
unsigned image_index:20;
unsigned pad:12;
unsigned sw_log2:2;
unsigned sh_log2:2;
unsigned pad:8;
};
static_assert(sizeof(struct nvk_storage_image_descriptor) == 4,
"nvk_storage_image_descriptor has no holes");

View File

@@ -294,8 +294,7 @@ nvk_GetPhysicalDeviceImageFormatProperties2(
ycbcr_info == NULL &&
(features & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
!(pImageFormatInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
!(pImageFormatInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
!(pImageFormatInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)) {
sampleCounts = VK_SAMPLE_COUNT_1_BIT |
VK_SAMPLE_COUNT_2_BIT |
VK_SAMPLE_COUNT_4_BIT |

View File

@@ -172,6 +172,8 @@ nvk_image_view_init(struct nvk_device *dev,
nil_view.type != NIL_VIEW_TYPE_3D)
image_3d_view_as_2d_array(&nil_image, &nil_view, &base_addr);
view->planes[view_plane].sample_layout = nil_image.sample_layout;
if (view->vk.usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
uint32_t tic[8];
@@ -209,6 +211,9 @@ nvk_image_view_init(struct nvk_device *dev,
}
}
if (image->vk.samples != VK_SAMPLE_COUNT_1_BIT)
nil_msaa_image_as_sa(&nil_image, &nil_image);
uint32_t tic[8];
nil_image_fill_tic(&nvk_device_physical(dev)->info,
&nil_image, &nil_view, base_addr, tic);

View File

@@ -9,6 +9,8 @@
#include "vk_image.h"
#include "nil_image.h"
struct nvk_device;
struct nvk_image_view {
@@ -18,6 +20,8 @@ struct nvk_image_view {
struct {
uint8_t image_plane;
enum nil_sample_layout sample_layout;
/** Index in the image descriptor table for the sampled image descriptor */
uint32_t sampled_desc_index;

View File

@@ -800,6 +800,80 @@ load_resource_deref_desc(nir_builder *b,
set, binding, index, offset_B, ctx);
}
static void
lower_msaa_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin)
{
assert(nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_MS);
b->cursor = nir_before_instr(&intrin->instr);
nir_def *desc = intrin->src[0].ssa;
nir_def *sw_log2 = nir_ubitfield_extract_imm(b, desc, 20, 2);
nir_def *sh_log2 = nir_ubitfield_extract_imm(b, desc, 22, 2);
nir_def *sw = nir_ishl(b, nir_imm_int(b, 1), sw_log2);
nir_def *sh = nir_ishl(b, nir_imm_int(b, 1), sh_log2);
nir_def *num_samples = nir_imul(b, sw, sh);
switch (intrin->intrinsic) {
case nir_intrinsic_bindless_image_load:
case nir_intrinsic_bindless_image_store:
case nir_intrinsic_bindless_image_atomic:
case nir_intrinsic_bindless_image_atomic_swap: {
nir_def *x = nir_channel(b, intrin->src[1].ssa, 0);
nir_def *y = nir_channel(b, intrin->src[1].ssa, 1);
nir_def *z = nir_channel(b, intrin->src[1].ssa, 2);
nir_def *w = nir_channel(b, intrin->src[1].ssa, 3);
nir_def *s = intrin->src[2].ssa;
nir_def *sw_mask = nir_iadd_imm(b, sw, -1);
nir_def *sx = nir_iand(b, s, sw_mask);
nir_def *sy = nir_ishr(b, s, sw_log2);
x = nir_imad(b, x, sw, sx);
y = nir_imad(b, y, sh, sy);
/* Make OOB sample indices OOB X/Y indices */
x = nir_bcsel(b, nir_ult(b, s, num_samples), x, nir_imm_int(b, -1));
nir_src_rewrite(&intrin->src[1], nir_vec4(b, x, y, z, w));
nir_src_rewrite(&intrin->src[2], nir_undef(b, 1, 32));
break;
}
case nir_intrinsic_bindless_image_size: {
b->cursor = nir_after_instr(&intrin->instr);
nir_def *size = &intrin->def;
nir_def *w = nir_channel(b, size, 0);
nir_def *h = nir_channel(b, size, 1);
w = nir_ushr(b, w, sw_log2);
h = nir_ushr(b, h, sh_log2);
size = nir_vector_insert_imm(b, size, w, 0);
size = nir_vector_insert_imm(b, size, h, 1);
nir_def_rewrite_uses_after(&intrin->def, size, size->parent_instr);
break;
}
case nir_intrinsic_bindless_image_samples: {
/* We need to handle NULL descriptors explicitly */
nir_def *samples =
nir_bcsel(b, nir_ieq(b, desc, nir_imm_int(b, 0)),
nir_imm_int(b, 0), num_samples);
nir_def_rewrite_uses(&intrin->def, samples);
break;
}
default:
unreachable("Unknown image intrinsic");
}
nir_intrinsic_set_image_dim(intrin, GLSL_SAMPLER_DIM_2D);
}
static bool
lower_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
const struct lower_descriptors_ctx *ctx)
@@ -809,6 +883,9 @@ lower_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
nir_def *desc = load_resource_deref_desc(b, 1, 32, deref, 0, ctx);
nir_rewrite_image_intrinsic(intrin, desc, true);
if (nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_MS)
lower_msaa_image_intrin(b, intrin);
return true;
}

View File

@@ -266,7 +266,7 @@ nvk_get_device_features(const struct nv_device_info *info,
.shaderTessellationAndGeometryPointSize = true,
.shaderImageGatherExtended = true,
.shaderStorageImageExtendedFormats = true,
/* TODO: shaderStorageImageMultisample */
.shaderStorageImageMultisample = true,
.shaderStorageImageReadWithoutFormat = info->cls_eng3d >= MAXWELL_A,
.shaderStorageImageWriteWithoutFormat = true,
.shaderUniformBufferArrayDynamicIndexing = true,
@@ -693,7 +693,7 @@ nvk_get_device_properties(const struct nvk_instance *instance,
.sampledImageIntegerSampleCounts = sample_counts,
.sampledImageDepthSampleCounts = sample_counts,
.sampledImageStencilSampleCounts = sample_counts,
.storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT,
.storageImageSampleCounts = sample_counts,
.maxSampleMaskWords = 1,
.timestampComputeAndGraphics = true,
.timestampPeriod = 1,

View File

@@ -133,6 +133,7 @@ nvk_get_spirv_options(struct vk_physical_device *vk_pdev,
.fragment_barycentric = true,
.geometry_streams = true,
.image_atomic_int64 = true,
.image_ms_array = true,
.image_read_without_format = true,
.image_write_without_format = true,
.int8 = true,
@@ -149,6 +150,7 @@ nvk_get_spirv_options(struct vk_physical_device *vk_pdev,
.sparse_residency = true,
.storage_8bit = true,
.storage_16bit = true,
.storage_image_ms = true,
.subgroup_arithmetic = true,
.subgroup_ballot = true,
.subgroup_basic = true,