From 3f641538d3f1bd607c3832ae787be7ea510d8a1a Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Wed, 3 May 2023 11:18:52 -0700 Subject: [PATCH] dzn: Augment blit resolve to support min/max/sample-zero modes Part-of: --- src/microsoft/vulkan/dzn_cmd_buffer.c | 24 +++++++++++--- src/microsoft/vulkan/dzn_meta.c | 8 +++-- src/microsoft/vulkan/dzn_nir.c | 48 +++++++++++++++++++++------ src/microsoft/vulkan/dzn_nir.h | 11 ++++-- src/microsoft/vulkan/dzn_private.h | 4 +-- 5 files changed, 73 insertions(+), 22 deletions(-) diff --git a/src/microsoft/vulkan/dzn_cmd_buffer.c b/src/microsoft/vulkan/dzn_cmd_buffer.c index 39cf2a6d888..6abaf0e534d 100644 --- a/src/microsoft/vulkan/dzn_cmd_buffer.c +++ b/src/microsoft/vulkan/dzn_cmd_buffer.c @@ -2774,7 +2774,8 @@ dzn_cmd_buffer_blit_set_pipeline(struct dzn_cmd_buffer *cmdbuf, const struct dzn_image *src, const struct dzn_image *dst, VkImageAspectFlagBits aspect, - VkFilter filter, bool resolve) + VkFilter filter, + enum dzn_blit_resolve_mode resolve_mode) { struct dzn_device *device = container_of(cmdbuf->vk.base.device, struct dzn_device, vk); struct dzn_physical_device *pdev = container_of(device->vk.physical, struct dzn_physical_device, vk); @@ -2800,7 +2801,7 @@ dzn_cmd_buffer_blit_set_pipeline(struct dzn_cmd_buffer *cmdbuf, src->vk.image_type == VK_IMAGE_TYPE_2D && src->vk.samples > 1 ? GLSL_SAMPLER_DIM_MS : GLSL_SAMPLER_DIM_3D), .src_is_array = src->vk.array_layers > 1, - .resolve = resolve, + .resolve_mode = resolve_mode, .linear_filter = filter == VK_FILTER_LINEAR, .padding = 0, }; @@ -2951,7 +2952,7 @@ dzn_cmd_buffer_blit_region(struct dzn_cmd_buffer *cmdbuf, dzn_foreach_aspect(aspect, region->srcSubresource.aspectMask) { D3D12_BARRIER_LAYOUT restore_dst_layout = D3D12_BARRIER_LAYOUT_COMMON; - dzn_cmd_buffer_blit_set_pipeline(cmdbuf, src, dst, aspect, info->filter, false); + dzn_cmd_buffer_blit_set_pipeline(cmdbuf, src, dst, aspect, info->filter, dzn_blit_resolve_none); dzn_cmd_buffer_blit_issue_barriers(cmdbuf, src, info->srcImageLayout, ®ion->srcSubresource, dst, info->dstImageLayout, ®ion->dstSubresource, @@ -3011,9 +3012,22 @@ dzn_cmd_buffer_blit_region(struct dzn_cmd_buffer *cmdbuf, } } +static enum dzn_blit_resolve_mode +get_blit_resolve_mode(VkResolveModeFlagBits mode) +{ + switch (mode) { + case VK_RESOLVE_MODE_AVERAGE_BIT: return dzn_blit_resolve_average; + case VK_RESOLVE_MODE_MIN_BIT: return dzn_blit_resolve_min; + case VK_RESOLVE_MODE_MAX_BIT: return dzn_blit_resolve_max; + case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT: return dzn_blit_resolve_sample_zero; + default: unreachable("Unexpected resolve mode"); + } +} + static void dzn_cmd_buffer_resolve_region(struct dzn_cmd_buffer *cmdbuf, const VkResolveImageInfo2 *info, + VkResolveModeFlags mode, struct dzn_descriptor_heap *heap, uint32_t *heap_slot, uint32_t r) @@ -3025,7 +3039,7 @@ dzn_cmd_buffer_resolve_region(struct dzn_cmd_buffer *cmdbuf, dzn_foreach_aspect(aspect, region->srcSubresource.aspectMask) { D3D12_BARRIER_LAYOUT restore_dst_layout = D3D12_BARRIER_LAYOUT_COMMON; - dzn_cmd_buffer_blit_set_pipeline(cmdbuf, src, dst, aspect, VK_FILTER_NEAREST, true); + dzn_cmd_buffer_blit_set_pipeline(cmdbuf, src, dst, aspect, VK_FILTER_NEAREST, get_blit_resolve_mode(mode)); dzn_cmd_buffer_blit_issue_barriers(cmdbuf, src, info->srcImageLayout, ®ion->srcSubresource, dst, info->dstImageLayout, ®ion->dstSubresource, @@ -4263,7 +4277,7 @@ dzn_CmdResolveImage2(VkCommandBuffer commandBuffer, ID3D12GraphicsCommandList1_IASetPrimitiveTopology(cmdbuf->cmdlist, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); for (uint32_t r = 0; r < info->regionCount; r++) - dzn_cmd_buffer_resolve_region(cmdbuf, info, heap, &heap_slot, r); + dzn_cmd_buffer_resolve_region(cmdbuf, info, VK_RESOLVE_MODE_AVERAGE_BIT, heap, &heap_slot, r); cmdbuf->state.pipeline = NULL; cmdbuf->state.dirty |= DZN_CMD_DIRTY_VIEWPORTS | DZN_CMD_DIRTY_SCISSORS; diff --git a/src/microsoft/vulkan/dzn_meta.c b/src/microsoft/vulkan/dzn_meta.c index 394252e6f60..878abc5cb71 100644 --- a/src/microsoft/vulkan/dzn_meta.c +++ b/src/microsoft/vulkan/dzn_meta.c @@ -603,8 +603,10 @@ dzn_meta_blit_create(struct dzn_device *device, const struct dzn_meta_blit_key * }, }; + uint32_t samples = key->resolve_mode == dzn_blit_resolve_none ? + key->samples : 1; D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = { - .SampleMask = key->resolve ? 1 : (1ULL << key->samples) - 1, + .SampleMask = (1ULL << samples) - 1, .RasterizerState = { .FillMode = D3D12_FILL_MODE_SOLID, .CullMode = D3D12_CULL_MODE_NONE, @@ -612,7 +614,7 @@ dzn_meta_blit_create(struct dzn_device *device, const struct dzn_meta_blit_key * }, .PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, .SampleDesc = { - .Count = key->resolve ? 1 : key->samples, + .Count = samples, .Quality = 0, }, .Flags = D3D12_PIPELINE_STATE_FLAG_NONE, @@ -624,7 +626,7 @@ dzn_meta_blit_create(struct dzn_device *device, const struct dzn_meta_blit_key * .out_type = key->out_type, .sampler_dim = key->sampler_dim, .src_is_array = key->src_is_array, - .resolve = key->resolve, + .resolve_mode = key->resolve_mode, .padding = 0, }; diff --git a/src/microsoft/vulkan/dzn_nir.c b/src/microsoft/vulkan/dzn_nir.c index 2945bd84645..f241d19c84e 100644 --- a/src/microsoft/vulkan/dzn_nir.c +++ b/src/microsoft/vulkan/dzn_nir.c @@ -658,15 +658,43 @@ dzn_nir_blit_fs(const struct dzn_nir_blit_info *info) nir_ssa_def *res = NULL; - if (info->resolve) { - /* When resolving a float type, we need to calculate the average of all - * samples. For integer resolve, Vulkan says that one sample should be - * chosen without telling which. Let's just pick the first one in that - * case. - */ + if (info->resolve_mode != dzn_blit_resolve_none) { + enum dzn_blit_resolve_mode resolve_mode = info->resolve_mode; - unsigned nsamples = info->out_type == GLSL_TYPE_FLOAT ? - info->src_samples : 1; + nir_op resolve_op = nir_op_mov; + switch (resolve_mode) { + case dzn_blit_resolve_average: + /* When resolving a float type, we need to calculate the average of all + * samples. For integer resolve, Vulkan says that one sample should be + * chosen without telling which. Let's just pick the first one in that + * case. + */ + if (info->out_type == GLSL_TYPE_FLOAT) + resolve_op = nir_op_fadd; + else + resolve_mode = dzn_blit_resolve_sample_zero; + break; + case dzn_blit_resolve_min: + switch (info->out_type) { + case GLSL_TYPE_FLOAT: resolve_op = nir_op_fmin; break; + case GLSL_TYPE_INT: resolve_op = nir_op_imin; break; + case GLSL_TYPE_UINT: resolve_op = nir_op_umin; break; + } + break; + case dzn_blit_resolve_max: + switch (info->out_type) { + case GLSL_TYPE_FLOAT: resolve_op = nir_op_fmax; break; + case GLSL_TYPE_INT: resolve_op = nir_op_imax; break; + case GLSL_TYPE_UINT: resolve_op = nir_op_umax; break; + } + break; + case dzn_blit_resolve_none: + case dzn_blit_resolve_sample_zero: + break; + } + + unsigned nsamples = resolve_mode == dzn_blit_resolve_sample_zero ? + 1 : info->src_samples; for (unsigned s = 0; s < nsamples; s++) { nir_tex_instr *tex = nir_tex_instr_create(b.shader, 4); @@ -692,10 +720,10 @@ dzn_nir_blit_fs(const struct dzn_nir_blit_info *info) nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL); nir_builder_instr_insert(&b, &tex->instr); - res = res ? nir_fadd(&b, res, &tex->dest.ssa) : &tex->dest.ssa; + res = res ? nir_build_alu2(&b, resolve_op, res, &tex->dest.ssa) : &tex->dest.ssa; } - if (nsamples > 1) { + if (resolve_mode == dzn_blit_resolve_average) { unsigned type_sz = nir_alu_type_get_type_size(nir_out_type); res = nir_fmul(&b, res, nir_imm_floatN_t(&b, 1.0f / nsamples, type_sz)); } diff --git a/src/microsoft/vulkan/dzn_nir.h b/src/microsoft/vulkan/dzn_nir.h index 176e0194265..c236e0fd0fd 100644 --- a/src/microsoft/vulkan/dzn_nir.h +++ b/src/microsoft/vulkan/dzn_nir.h @@ -137,6 +137,13 @@ dzn_nir_triangle_fan_rewrite_index_shader(uint8_t old_index_size); nir_shader * dzn_nir_triangle_fan_prim_restart_rewrite_index_shader(uint8_t old_index_size); +enum dzn_blit_resolve_mode { + dzn_blit_resolve_none, + dzn_blit_resolve_average, + dzn_blit_resolve_min, + dzn_blit_resolve_max, + dzn_blit_resolve_sample_zero, +}; struct dzn_nir_blit_info { union { struct { @@ -145,8 +152,8 @@ struct dzn_nir_blit_info { uint32_t out_type : 4; uint32_t sampler_dim : 4; uint32_t src_is_array : 1; - uint32_t resolve : 1; - uint32_t padding : 12; + uint32_t resolve_mode : 3; + uint32_t padding : 10; }; const uint32_t hash_key; }; diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index 50193c5f80b..3629b5a2144 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -150,9 +150,9 @@ struct dzn_meta_blit_key { uint32_t out_type : 4; uint32_t sampler_dim : 4; uint32_t src_is_array : 1; - uint32_t resolve : 1; + uint32_t resolve_mode : 3; uint32_t linear_filter : 1; - uint32_t padding : 11; + uint32_t padding : 9; }; const uint64_t u64; };