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:

committed by
Marge Bot

parent
357720c5a7
commit
7604697ec6
@@ -114,6 +114,11 @@ write_storage_image_view_desc(struct nvk_descriptor_set *set,
|
|||||||
assert(view->planes[plane].storage_desc_index < (1 << 20));
|
assert(view->planes[plane].storage_desc_index < (1 << 20));
|
||||||
|
|
||||||
desc.image_index = view->planes[plane].storage_desc_index;
|
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));
|
write_desc(set, binding, elem, &desc, sizeof(desc));
|
||||||
|
@@ -26,7 +26,9 @@ static_assert(sizeof(struct nvk_sampled_image_descriptor) == 4,
|
|||||||
|
|
||||||
struct nvk_storage_image_descriptor {
|
struct nvk_storage_image_descriptor {
|
||||||
unsigned image_index:20;
|
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,
|
static_assert(sizeof(struct nvk_storage_image_descriptor) == 4,
|
||||||
"nvk_storage_image_descriptor has no holes");
|
"nvk_storage_image_descriptor has no holes");
|
||||||
|
@@ -294,8 +294,7 @@ nvk_GetPhysicalDeviceImageFormatProperties2(
|
|||||||
ycbcr_info == NULL &&
|
ycbcr_info == NULL &&
|
||||||
(features & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
|
(features & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
|
||||||
VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
|
VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
|
||||||
!(pImageFormatInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
|
!(pImageFormatInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)) {
|
||||||
!(pImageFormatInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
|
|
||||||
sampleCounts = VK_SAMPLE_COUNT_1_BIT |
|
sampleCounts = VK_SAMPLE_COUNT_1_BIT |
|
||||||
VK_SAMPLE_COUNT_2_BIT |
|
VK_SAMPLE_COUNT_2_BIT |
|
||||||
VK_SAMPLE_COUNT_4_BIT |
|
VK_SAMPLE_COUNT_4_BIT |
|
||||||
|
@@ -172,6 +172,8 @@ nvk_image_view_init(struct nvk_device *dev,
|
|||||||
nil_view.type != NIL_VIEW_TYPE_3D)
|
nil_view.type != NIL_VIEW_TYPE_3D)
|
||||||
image_3d_view_as_2d_array(&nil_image, &nil_view, &base_addr);
|
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 |
|
if (view->vk.usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||||
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
|
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
|
||||||
uint32_t tic[8];
|
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];
|
uint32_t tic[8];
|
||||||
nil_image_fill_tic(&nvk_device_physical(dev)->info,
|
nil_image_fill_tic(&nvk_device_physical(dev)->info,
|
||||||
&nil_image, &nil_view, base_addr, tic);
|
&nil_image, &nil_view, base_addr, tic);
|
||||||
|
@@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include "vk_image.h"
|
#include "vk_image.h"
|
||||||
|
|
||||||
|
#include "nil_image.h"
|
||||||
|
|
||||||
struct nvk_device;
|
struct nvk_device;
|
||||||
|
|
||||||
struct nvk_image_view {
|
struct nvk_image_view {
|
||||||
@@ -18,6 +20,8 @@ struct nvk_image_view {
|
|||||||
struct {
|
struct {
|
||||||
uint8_t image_plane;
|
uint8_t image_plane;
|
||||||
|
|
||||||
|
enum nil_sample_layout sample_layout;
|
||||||
|
|
||||||
/** Index in the image descriptor table for the sampled image descriptor */
|
/** Index in the image descriptor table for the sampled image descriptor */
|
||||||
uint32_t sampled_desc_index;
|
uint32_t sampled_desc_index;
|
||||||
|
|
||||||
|
@@ -800,6 +800,80 @@ load_resource_deref_desc(nir_builder *b,
|
|||||||
set, binding, index, offset_B, ctx);
|
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
|
static bool
|
||||||
lower_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
|
lower_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
|
||||||
const struct lower_descriptors_ctx *ctx)
|
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_def *desc = load_resource_deref_desc(b, 1, 32, deref, 0, ctx);
|
||||||
nir_rewrite_image_intrinsic(intrin, desc, true);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -266,7 +266,7 @@ nvk_get_device_features(const struct nv_device_info *info,
|
|||||||
.shaderTessellationAndGeometryPointSize = true,
|
.shaderTessellationAndGeometryPointSize = true,
|
||||||
.shaderImageGatherExtended = true,
|
.shaderImageGatherExtended = true,
|
||||||
.shaderStorageImageExtendedFormats = true,
|
.shaderStorageImageExtendedFormats = true,
|
||||||
/* TODO: shaderStorageImageMultisample */
|
.shaderStorageImageMultisample = true,
|
||||||
.shaderStorageImageReadWithoutFormat = info->cls_eng3d >= MAXWELL_A,
|
.shaderStorageImageReadWithoutFormat = info->cls_eng3d >= MAXWELL_A,
|
||||||
.shaderStorageImageWriteWithoutFormat = true,
|
.shaderStorageImageWriteWithoutFormat = true,
|
||||||
.shaderUniformBufferArrayDynamicIndexing = true,
|
.shaderUniformBufferArrayDynamicIndexing = true,
|
||||||
@@ -693,7 +693,7 @@ nvk_get_device_properties(const struct nvk_instance *instance,
|
|||||||
.sampledImageIntegerSampleCounts = sample_counts,
|
.sampledImageIntegerSampleCounts = sample_counts,
|
||||||
.sampledImageDepthSampleCounts = sample_counts,
|
.sampledImageDepthSampleCounts = sample_counts,
|
||||||
.sampledImageStencilSampleCounts = sample_counts,
|
.sampledImageStencilSampleCounts = sample_counts,
|
||||||
.storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT,
|
.storageImageSampleCounts = sample_counts,
|
||||||
.maxSampleMaskWords = 1,
|
.maxSampleMaskWords = 1,
|
||||||
.timestampComputeAndGraphics = true,
|
.timestampComputeAndGraphics = true,
|
||||||
.timestampPeriod = 1,
|
.timestampPeriod = 1,
|
||||||
|
@@ -133,6 +133,7 @@ nvk_get_spirv_options(struct vk_physical_device *vk_pdev,
|
|||||||
.fragment_barycentric = true,
|
.fragment_barycentric = true,
|
||||||
.geometry_streams = true,
|
.geometry_streams = true,
|
||||||
.image_atomic_int64 = true,
|
.image_atomic_int64 = true,
|
||||||
|
.image_ms_array = true,
|
||||||
.image_read_without_format = true,
|
.image_read_without_format = true,
|
||||||
.image_write_without_format = true,
|
.image_write_without_format = true,
|
||||||
.int8 = true,
|
.int8 = true,
|
||||||
@@ -149,6 +150,7 @@ nvk_get_spirv_options(struct vk_physical_device *vk_pdev,
|
|||||||
.sparse_residency = true,
|
.sparse_residency = true,
|
||||||
.storage_8bit = true,
|
.storage_8bit = true,
|
||||||
.storage_16bit = true,
|
.storage_16bit = true,
|
||||||
|
.storage_image_ms = true,
|
||||||
.subgroup_arithmetic = true,
|
.subgroup_arithmetic = true,
|
||||||
.subgroup_ballot = true,
|
.subgroup_ballot = true,
|
||||||
.subgroup_basic = true,
|
.subgroup_basic = true,
|
||||||
|
Reference in New Issue
Block a user