update parallel rdp

This commit is contained in:
Logan McNaughton committed 2023-07-28 10:26:20 -06:00
1 parent 265932ab6a
commit 299bbfe03f
56 files changed
+51210 -49596

No files matched your search

+2 -1
View File
@@ -35,6 +35,7 @@ add_library(${NAME_PLUGIN_SIMPLE64} SHARED
vulkan/fence.cpp
vulkan/fence_manager.cpp
vulkan/image.cpp
vulkan/indirect_layout.cpp
vulkan/memory_allocator.cpp
vulkan/pipeline_event.cpp
vulkan/query_pool.cpp
@@ -43,7 +44,7 @@ add_library(${NAME_PLUGIN_SIMPLE64} SHARED
vulkan/semaphore.cpp
vulkan/semaphore_manager.cpp
vulkan/shader.cpp
vulkan/texture_format.cpp
vulkan/texture/texture_format.cpp
vulkan/wsi.cpp
util/arena_allocator.cpp
util/logging.cpp
+1 -1
View File
@@ -1 +1 @@
d95cf9b09c31e1b239eb7e90255e048ffa184360
860050d2bf187f1dc215a59df3b2c4f01cada33e
+2 -1
View File
@@ -17,6 +17,7 @@ PARALLEL_RDP_SOURCES_CXX := \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/fence.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/fence_manager.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/image.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/indirect_layout.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/memory_allocator.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/pipeline_event.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/query_pool.cpp \
@@ -25,7 +26,7 @@ PARALLEL_RDP_SOURCES_CXX := \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/semaphore.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/semaphore_manager.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/shader.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/texture_format.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/vulkan/texture/texture_format.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/util/arena_allocator.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/util/logging.cpp \
$(PARALLEL_RDP_IMPLEMENTATION)/util/thread_id.cpp \
@@ -1651,7 +1651,7 @@ void Renderer::update_tmem_instances(Vulkan::CommandBuffer &cmd)
{
end_ts = cmd.write_timestamp(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
device->register_time_interval("RDP GPU", std::move(start_ts), std::move(end_ts),
"tmem-update", std::to_string(stream.tmem_upload_infos.size()));
"tmem-update");
}
cmd.end_region();
}
@@ -2269,10 +2269,7 @@ void Renderer::submit_render_pass(Vulkan::CommandBuffer &cmd)
if (caps.timestamp >= 1)
{
render_pass_end = cmd.write_timestamp(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
std::string tag;
tag = "(" + std::to_string(fb.width) + " x " + std::to_string(fb.deduced_height) + ")";
tag += " (" + std::to_string(stream.triangle_setup.size()) + " triangles)";
device->register_time_interval("RDP GPU", std::move(render_pass_start), std::move(render_pass_end), "render-pass", std::move(tag));
device->register_time_interval("RDP GPU", std::move(render_pass_start), std::move(render_pass_end), "render-pass");
}
}
@@ -3567,7 +3564,7 @@ void Renderer::PipelineExecutor::perform_work(const Vulkan::DeferredPipelineComp
Vulkan::CommandBuffer::build_compute_pipeline(device, compile, Vulkan::CommandBuffer::CompileMode::AsyncThread);
auto end_ts = device->write_calibrated_timestamp();
device->register_time_interval("RDP Pipeline", std::move(start_ts), std::move(end_ts),
"pipeline-compilation", std::to_string(compile.hash));
"pipeline-compilation");
}
bool Renderer::PipelineExecutor::is_sentinel(const Vulkan::DeferredPipelineCompile &compile) const
File diff suppressed because it is too large. Load diff
@@ -503,7 +503,7 @@ i16x4 sample_texture(TileInfo tile, uint tmem_instance, ivec2 st, bool tlut, boo
st.y = clamp_and_shift_coord((tile.flags & TILE_INFO_CLAMP_T_BIT) != 0, st.y, int(tile.tlo), int(tile.thi), int(tile.shift_t));
ivec2 frac;
if (sample_quad)
if (sample_quad || tlut)
frac = st & 31;
else
frac = ivec2(0);
@@ -524,6 +524,7 @@ i16x4 sample_texture(TileInfo tile, uint tmem_instance, ivec2 st, bool tlut, boo
i16x4 t_base, t10, t01, t11;
bool mid_texel = all(bvec4(mid_texel_state, bilerp, equal(frac, ivec2(0x10))));
bool upper_lut = sum_frac >= 0x20;
if (mid_texel)
{
// Ensure we sample all 4 texels.
@@ -536,6 +537,15 @@ i16x4 sample_texture(TileInfo tile, uint tmem_instance, ivec2 st, bool tlut, boo
if (tlut)
{
if (!sample_quad)
{
// Weird mode where we sample a bilinear footprint with the 4 banks of TLUT instead.
// Force the footprint to be sampled, but adjust the input coordinates instead.
base_st = ivec2(s0, t0);
s1 = s0;
t1 = t0;
}
switch (int(tile.fmt))
{
case TEXTURE_FORMAT_RGBA:
@@ -546,13 +556,13 @@ i16x4 sample_texture(TileInfo tile, uint tmem_instance, ivec2 st, bool tlut, boo
// For TLUT, entries in the LUT are duplicated and we must make sure that we sample 3 different banks
// when we look up the TLUT entry. In normal situations, this is irrelevant, but we're trying to be accurate here.
bool upper = sum_frac >= 0x20;
uint addr_xor = upper ? 2 : 1;
uint addr_xor = upper_lut ? 2 : 1;
switch (int(tile.size))
{
case 0:
t_base = sample_texel_ci4_tlut(tile, tmem_instance, base_st, tile.palette, upper ? 3 : 0, addr_xor, tlut_type);
if (sample_quad)
if (bilerp)
{
t10 = sample_texel_ci4_tlut(tile, tmem_instance, ivec2(s1, t0), tile.palette, 1, addr_xor,
tlut_type);
@@ -568,7 +578,7 @@ i16x4 sample_texture(TileInfo tile, uint tmem_instance, ivec2 st, bool tlut, boo
case 1:
t_base = sample_texel_ci8_tlut(tile, tmem_instance, base_st, upper ? 3 : 0, addr_xor, tlut_type);
if (sample_quad)
if (bilerp)
{
t10 = sample_texel_ci8_tlut(tile, tmem_instance, ivec2(s1, t0), 1, addr_xor, tlut_type);
t01 = sample_texel_ci8_tlut(tile, tmem_instance, ivec2(s0, t1), 2, addr_xor, tlut_type);
@@ -579,7 +589,7 @@ i16x4 sample_texture(TileInfo tile, uint tmem_instance, ivec2 st, bool tlut, boo
default:
t_base = sample_texel_ci32_tlut(tile, tmem_instance, base_st, upper ? 3 : 0, addr_xor, tlut_type);
if (sample_quad)
if (bilerp)
{
t10 = sample_texel_ci32_tlut(tile, tmem_instance, ivec2(s1, t0), 1, addr_xor, tlut_type);
t01 = sample_texel_ci32_tlut(tile, tmem_instance, ivec2(s0, t1), 2, addr_xor, tlut_type);
@@ -890,7 +900,7 @@ i16x4 sample_texture(TileInfo tile, uint tmem_instance, ivec2 st, bool tlut, boo
{
accum = (t_base + t01 + t10 + t11 + I16_C(2)) >> I16_C(2);
}
else if (bilerp && sample_quad)
else if (bilerp && (sample_quad || tlut))
{
i16x2 flip_frac = i16x2(sum_frac >= 32 ? (32 - frac.yx) : frac);
accum = (t10 - t_base) * flip_frac.x;
@@ -565,7 +565,7 @@ void main()
bool yuv = info.tmem_fmt == TEXTURE_FMT_YUV;
if (info.tmem_size == 3 || yuv)
update_tmem_32(info, tmem16_index & 0x3ff, upper_tmem, yuv);
else if (info.tmem_fmt != TEXTURE_FMT_YUV)
else
update_tmem_16(info, tmem16_index);
}
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H264STD_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H264STD_DECODE_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H264STD_ENCODE_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -21,9 +21,9 @@ extern "C" {
#define vulkan_video_codec_h264std_encode 1
// Vulkan 0.9 provisional Vulkan video H.264 encode std specification version number
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_8 VK_MAKE_VIDEO_STD_VERSION(0, 9, 8)
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_9 VK_MAKE_VIDEO_STD_VERSION(0, 9, 9)
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_8
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_9
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_encode"
typedef struct StdVideoEncodeH264WeightTableFlags {
uint32_t luma_weight_l0_flag;
@@ -64,10 +64,10 @@ typedef struct StdVideoEncodeH264ReferenceInfoFlags {
uint32_t used_for_long_term_reference : 1;
} StdVideoEncodeH264ReferenceInfoFlags;
typedef struct StdVideoEncodeH264RefMgmtFlags {
uint32_t ref_pic_list_modification_l0_flag : 1;
uint32_t ref_pic_list_modification_l1_flag : 1;
} StdVideoEncodeH264RefMgmtFlags;
typedef struct StdVideoEncodeH264ReferenceListsInfoFlags {
uint32_t ref_pic_list_modification_flag_l0 : 1;
uint32_t ref_pic_list_modification_flag_l1 : 1;
} StdVideoEncodeH264ReferenceListsInfoFlags;
typedef struct StdVideoEncodeH264RefListModEntry {
StdVideoH264ModificationOfPicNumsIdc modification_of_pic_nums_idc;
@@ -83,20 +83,26 @@ typedef struct StdVideoEncodeH264RefPicMarkingEntry {
uint16_t max_long_term_frame_idx_plus1;
} StdVideoEncodeH264RefPicMarkingEntry;
typedef struct StdVideoEncodeH264RefMemMgmtCtrlOperations {
StdVideoEncodeH264RefMgmtFlags flags;
typedef struct StdVideoEncodeH264ReferenceListsInfo {
StdVideoEncodeH264ReferenceListsInfoFlags flags;
uint8_t refPicList0EntryCount;
uint8_t refPicList1EntryCount;
uint8_t refList0ModOpCount;
const StdVideoEncodeH264RefListModEntry* pRefList0ModOperations;
uint8_t refList1ModOpCount;
const StdVideoEncodeH264RefListModEntry* pRefList1ModOperations;
uint8_t refPicMarkingOpCount;
uint8_t reserved1[7];
const uint8_t* pRefPicList0Entries;
const uint8_t* pRefPicList1Entries;
const StdVideoEncodeH264RefListModEntry* pRefList0ModOperations;
const StdVideoEncodeH264RefListModEntry* pRefList1ModOperations;
const StdVideoEncodeH264RefPicMarkingEntry* pRefPicMarkingOperations;
} StdVideoEncodeH264RefMemMgmtCtrlOperations;
} StdVideoEncodeH264ReferenceListsInfo;
typedef struct StdVideoEncodeH264PictureInfo {
StdVideoEncodeH264PictureInfoFlags flags;
uint8_t seq_parameter_set_id;
uint8_t pic_parameter_set_id;
uint16_t reserved1;
StdVideoH264PictureType pictureType;
uint32_t frame_num;
int32_t PicOrderCnt;
@@ -104,6 +110,7 @@ typedef struct StdVideoEncodeH264PictureInfo {
typedef struct StdVideoEncodeH264ReferenceInfo {
StdVideoEncodeH264ReferenceInfoFlags flags;
StdVideoH264PictureType pictureType;
uint32_t FrameNum;
int32_t PicOrderCnt;
uint16_t long_term_pic_num;
@@ -121,6 +128,8 @@ typedef struct StdVideoEncodeH264SliceHeader {
StdVideoH264DisableDeblockingFilterIdc disable_deblocking_filter_idc;
int8_t slice_alpha_c0_offset_div2;
int8_t slice_beta_offset_div2;
uint16_t reserved1;
uint32_t reserved2;
const StdVideoEncodeH264WeightTable* pWeightTable;
} StdVideoEncodeH264SliceHeader;
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H265STD_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H265STD_DECODE_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H265STD_ENCODE_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -21,9 +21,9 @@ extern "C" {
#define vulkan_video_codec_h265std_encode 1
// Vulkan 0.9 provisional Vulkan video H.265 encode std specification version number
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_9 VK_MAKE_VIDEO_STD_VERSION(0, 9, 9)
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_10 VK_MAKE_VIDEO_STD_VERSION(0, 9, 10)
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_9
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_10
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_encode"
typedef struct StdVideoEncodeH265WeightTableFlags {
uint16_t luma_weight_l0_flag;
@@ -96,18 +96,21 @@ typedef struct StdVideoEncodeH265SliceSegmentHeader {
const StdVideoEncodeH265WeightTable* pWeightTable;
} StdVideoEncodeH265SliceSegmentHeader;
typedef struct StdVideoEncodeH265ReferenceModificationFlags {
typedef struct StdVideoEncodeH265ReferenceListsInfoFlags {
uint32_t ref_pic_list_modification_flag_l0 : 1;
uint32_t ref_pic_list_modification_flag_l1 : 1;
} StdVideoEncodeH265ReferenceModificationFlags;
} StdVideoEncodeH265ReferenceListsInfoFlags;
typedef struct StdVideoEncodeH265ReferenceModifications {
StdVideoEncodeH265ReferenceModificationFlags flags;
uint8_t referenceList0ModificationsCount;
const uint8_t* pReferenceList0Modifications;
uint8_t referenceList1ModificationsCount;
const uint8_t* pReferenceList1Modifications;
} StdVideoEncodeH265ReferenceModifications;
typedef struct StdVideoEncodeH265ReferenceListsInfo {
StdVideoEncodeH265ReferenceListsInfoFlags flags;
uint8_t num_ref_idx_l0_active_minus1;
uint8_t num_ref_idx_l1_active_minus1;
uint16_t reserved1;
const uint8_t* pRefPicList0Entries;
const uint8_t* pRefPicList1Entries;
const uint8_t* pRefList0Modifications;
const uint8_t* pRefList1Modifications;
} StdVideoEncodeH265ReferenceListsInfo;
typedef struct StdVideoEncodeH265PictureInfoFlags {
uint32_t is_reference_flag : 1;
@@ -123,8 +126,8 @@ typedef struct StdVideoEncodeH265PictureInfo {
uint8_t sps_video_parameter_set_id;
uint8_t pps_seq_parameter_set_id;
uint8_t pps_pic_parameter_set_id;
int32_t PicOrderCntVal;
uint8_t TemporalId;
int32_t PicOrderCntVal;
} StdVideoEncodeH265PictureInfo;
typedef struct StdVideoEncodeH265ReferenceInfoFlags {
@@ -134,6 +137,7 @@ typedef struct StdVideoEncodeH265ReferenceInfoFlags {
typedef struct StdVideoEncodeH265ReferenceInfo {
StdVideoEncodeH265ReferenceInfoFlags flags;
StdVideoH265PictureType PictureType;
int32_t PicOrderCntVal;
uint8_t TemporalId;
} StdVideoEncodeH265ReferenceInfo;
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODECS_COMMON_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,9 +2,9 @@
// File: vk_icd.h
//
/*
* Copyright (c) 2015-2016, 2022 The Khronos Group Inc.
* Copyright (c) 2015-2016, 2022 Valve Corporation
* Copyright (c) 2015-2016, 2022 LunarG, Inc.
* Copyright (c) 2015-2023 LunarG, Inc.
* Copyright (c) 2015-2023 The Khronos Group Inc.
* Copyright (c) 2015-2023 Valve Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,7 @@
* limitations under the License.
*
*/
#ifndef VKICD_H
#define VKICD_H
#pragma once
#include "vulkan.h"
#include <stdbool.h>
@@ -80,7 +78,7 @@ extern "C" {
#endif
VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pVersion);
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName);
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance isntance, const char* pName);
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName);
#if defined(VK_USE_PLATFORM_WIN32_KHR)
VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices);
@@ -258,5 +256,3 @@ typedef struct {
VkIcdSurfaceBase base;
} VkIcdSurfaceImagePipe;
#endif // VK_USE_PLATFORM_FUCHSIA
#endif // VKICD_H
@@ -2,9 +2,9 @@
// File: vk_layer.h
//
/*
* Copyright (c) 2015-2017 The Khronos Group Inc.
* Copyright (c) 2015-2017 Valve Corporation
* Copyright (c) 2015-2017 LunarG, Inc.
* Copyright (c) 2015-2023 LunarG, Inc.
* Copyright (c) 2015-2023 The Khronos Group Inc.
* Copyright (c) 2015-2023 Valve Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,23 +19,15 @@
* limitations under the License.
*
*/
#pragma once
/* Need to define dispatch table
* Core struct can then have ptr to dispatch table at the top
* Along with object ptrs for current and next OBJ
*/
#pragma once
#include "vulkan_core.h"
#if defined(__GNUC__) && __GNUC__ >= 4
#define VK_LAYER_EXPORT __attribute__((visibility("default")))
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
#define VK_LAYER_EXPORT __attribute__((visibility("default")))
#else
#define VK_LAYER_EXPORT
#endif
#define MAX_NUM_UNKNOWN_EXTS 250
// Loader-Layer version negotiation API. Versions add the following features:
@@ -2,7 +2,7 @@
// File: vk_platform.h
//
/*
** Copyright 2014-2022 The Khronos Group Inc.
** Copyright 2014-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -84,6 +84,14 @@
#include "vulkan_screen.h"
#endif
#ifdef VK_USE_PLATFORM_SCI
#include <nvscisync.h>
#include <nvscibuf.h>
#include "vulkan_sci.h"
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
#include "vulkan_beta.h"
#endif
@@ -2,7 +2,7 @@
#define VULKAN_ANDROID_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_BETA_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -51,7 +51,7 @@ typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR {
#define VK_KHR_video_encode_queue 1
#define VK_KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION 7
#define VK_KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION 8
#define VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME "VK_KHR_video_encode_queue"
typedef enum VkVideoEncodeTuningModeKHR {
@@ -71,13 +71,21 @@ typedef enum VkVideoEncodeCapabilityFlagBitsKHR {
typedef VkFlags VkVideoEncodeCapabilityFlagsKHR;
typedef enum VkVideoEncodeRateControlModeFlagBitsKHR {
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_NONE_BIT_KHR = 0,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR = 1,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR = 2,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR = 0x00000004,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeRateControlModeFlagBitsKHR;
typedef VkFlags VkVideoEncodeRateControlModeFlagsKHR;
typedef enum VkVideoEncodeFeedbackFlagBitsKHR {
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_FEEDBACK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeFeedbackFlagBitsKHR;
typedef VkFlags VkVideoEncodeFeedbackFlagsKHR;
typedef enum VkVideoEncodeUsageFlagBitsKHR {
VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_USAGE_TRANSCODING_BIT_KHR = 0x00000001,
@@ -102,9 +110,9 @@ typedef struct VkVideoEncodeInfoKHR {
const void* pNext;
VkVideoEncodeFlagsKHR flags;
uint32_t qualityLevel;
VkBuffer dstBitstreamBuffer;
VkDeviceSize dstBitstreamBufferOffset;
VkDeviceSize dstBitstreamBufferMaxRange;
VkBuffer dstBuffer;
VkDeviceSize dstBufferOffset;
VkDeviceSize dstBufferRange;
VkVideoPictureResourceInfoKHR srcPictureResource;
const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot;
uint32_t referenceSlotCount;
@@ -117,11 +125,18 @@ typedef struct VkVideoEncodeCapabilitiesKHR {
void* pNext;
VkVideoEncodeCapabilityFlagsKHR flags;
VkVideoEncodeRateControlModeFlagsKHR rateControlModes;
uint8_t rateControlLayerCount;
uint8_t qualityLevelCount;
uint32_t maxRateControlLayers;
uint32_t maxQualityLevels;
VkExtent2D inputImageDataFillAlignment;
VkVideoEncodeFeedbackFlagsKHR supportedEncodeFeedbackFlags;
} VkVideoEncodeCapabilitiesKHR;
typedef struct VkQueryPoolVideoEncodeFeedbackCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeFeedbackFlagsKHR encodeFeedbackFlags;
} VkQueryPoolVideoEncodeFeedbackCreateInfoKHR;
typedef struct VkVideoEncodeUsageInfoKHR {
VkStructureType sType;
const void* pNext;
@@ -133,8 +148,8 @@ typedef struct VkVideoEncodeUsageInfoKHR {
typedef struct VkVideoEncodeRateControlLayerInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t averageBitrate;
uint32_t maxBitrate;
uint64_t averageBitrate;
uint64_t maxBitrate;
uint32_t frameRateNumerator;
uint32_t frameRateDenominator;
uint32_t virtualBufferSizeInMs;
@@ -146,8 +161,8 @@ typedef struct VkVideoEncodeRateControlInfoKHR {
const void* pNext;
VkVideoEncodeRateControlFlagsKHR flags;
VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode;
uint8_t layerCount;
const VkVideoEncodeRateControlLayerInfoKHR* pLayerConfigs;
uint32_t layerCount;
const VkVideoEncodeRateControlLayerInfoKHR* pLayers;
} VkVideoEncodeRateControlInfoKHR;
typedef void (VKAPI_PTR *PFN_vkCmdEncodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR* pEncodeInfo);
@@ -162,7 +177,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR(
#define VK_EXT_video_encode_h264 1
#include "vk_video/vulkan_video_codec_h264std.h"
#include "vk_video/vulkan_video_codec_h264std_encode.h"
#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 9
#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 10
#define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264"
typedef enum VkVideoEncodeH264RateControlStructureEXT {
@@ -198,34 +213,17 @@ typedef enum VkVideoEncodeH264CapabilityFlagBitsEXT {
VK_VIDEO_ENCODE_H264_CAPABILITY_ROW_UNALIGNED_SLICE_BIT_EXT = 0x00400000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_EXT = 0x00800000,
VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x01000000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_REFERENCE_FINAL_LISTS_BIT_EXT = 0x02000000,
VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH264CapabilityFlagBitsEXT;
typedef VkFlags VkVideoEncodeH264CapabilityFlagsEXT;
typedef enum VkVideoEncodeH264InputModeFlagBitsEXT {
VK_VIDEO_ENCODE_H264_INPUT_MODE_FRAME_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H264_INPUT_MODE_SLICE_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H264_INPUT_MODE_NON_VCL_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H264_INPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH264InputModeFlagBitsEXT;
typedef VkFlags VkVideoEncodeH264InputModeFlagsEXT;
typedef enum VkVideoEncodeH264OutputModeFlagBitsEXT {
VK_VIDEO_ENCODE_H264_OUTPUT_MODE_FRAME_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H264_OUTPUT_MODE_SLICE_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H264_OUTPUT_MODE_NON_VCL_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H264_OUTPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH264OutputModeFlagBitsEXT;
typedef VkFlags VkVideoEncodeH264OutputModeFlagsEXT;
typedef struct VkVideoEncodeH264CapabilitiesEXT {
VkStructureType sType;
void* pNext;
VkVideoEncodeH264CapabilityFlagsEXT flags;
VkVideoEncodeH264InputModeFlagsEXT inputModeFlags;
VkVideoEncodeH264OutputModeFlagsEXT outputModeFlags;
uint8_t maxPPictureL0ReferenceCount;
uint8_t maxBPictureL0ReferenceCount;
uint8_t maxL1ReferenceCount;
uint32_t maxPPictureL0ReferenceCount;
uint32_t maxBPictureL0ReferenceCount;
uint32_t maxL1ReferenceCount;
VkBool32 motionVectorsOverPicBoundariesFlag;
uint32_t maxBytesPerPicDenom;
uint32_t maxBitsPerMbDenom;
@@ -250,48 +248,28 @@ typedef struct VkVideoEncodeH264SessionParametersCreateInfoEXT {
const VkVideoEncodeH264SessionParametersAddInfoEXT* pParametersAddInfo;
} VkVideoEncodeH264SessionParametersCreateInfoEXT;
typedef struct VkVideoEncodeH264DpbSlotInfoEXT {
VkStructureType sType;
const void* pNext;
int8_t slotIndex;
const StdVideoEncodeH264ReferenceInfo* pStdReferenceInfo;
} VkVideoEncodeH264DpbSlotInfoEXT;
typedef struct VkVideoEncodeH264ReferenceListsInfoEXT {
VkStructureType sType;
const void* pNext;
uint8_t referenceList0EntryCount;
const VkVideoEncodeH264DpbSlotInfoEXT* pReferenceList0Entries;
uint8_t referenceList1EntryCount;
const VkVideoEncodeH264DpbSlotInfoEXT* pReferenceList1Entries;
const StdVideoEncodeH264RefMemMgmtCtrlOperations* pMemMgmtCtrlOperations;
} VkVideoEncodeH264ReferenceListsInfoEXT;
typedef struct VkVideoEncodeH264NaluSliceInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t mbCount;
const VkVideoEncodeH264ReferenceListsInfoEXT* pReferenceFinalLists;
const StdVideoEncodeH264SliceHeader* pSliceHeaderStd;
VkStructureType sType;
const void* pNext;
uint32_t mbCount;
const StdVideoEncodeH264ReferenceListsInfo* pStdReferenceFinalLists;
const StdVideoEncodeH264SliceHeader* pStdSliceHeader;
} VkVideoEncodeH264NaluSliceInfoEXT;
typedef struct VkVideoEncodeH264VclFrameInfoEXT {
VkStructureType sType;
const void* pNext;
const VkVideoEncodeH264ReferenceListsInfoEXT* pReferenceFinalLists;
uint32_t naluSliceEntryCount;
const VkVideoEncodeH264NaluSliceInfoEXT* pNaluSliceEntries;
const StdVideoEncodeH264PictureInfo* pCurrentPictureInfo;
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH264ReferenceListsInfo* pStdReferenceFinalLists;
uint32_t naluSliceEntryCount;
const VkVideoEncodeH264NaluSliceInfoEXT* pNaluSliceEntries;
const StdVideoEncodeH264PictureInfo* pStdPictureInfo;
} VkVideoEncodeH264VclFrameInfoEXT;
typedef struct VkVideoEncodeH264EmitPictureParametersInfoEXT {
VkStructureType sType;
const void* pNext;
uint8_t spsId;
VkBool32 emitSpsEnable;
uint32_t ppsIdEntryCount;
const uint8_t* ppsIdEntries;
} VkVideoEncodeH264EmitPictureParametersInfoEXT;
typedef struct VkVideoEncodeH264DpbSlotInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH264ReferenceInfo* pStdReferenceInfo;
} VkVideoEncodeH264DpbSlotInfoEXT;
typedef struct VkVideoEncodeH264ProfileInfoEXT {
VkStructureType sType;
@@ -306,7 +284,7 @@ typedef struct VkVideoEncodeH264RateControlInfoEXT {
uint32_t idrPeriod;
uint32_t consecutiveBFrameCount;
VkVideoEncodeH264RateControlStructureEXT rateControlStructure;
uint8_t temporalLayerCount;
uint32_t temporalLayerCount;
} VkVideoEncodeH264RateControlInfoEXT;
typedef struct VkVideoEncodeH264QpEXT {
@@ -324,7 +302,7 @@ typedef struct VkVideoEncodeH264FrameSizeEXT {
typedef struct VkVideoEncodeH264RateControlLayerInfoEXT {
VkStructureType sType;
const void* pNext;
uint8_t temporalLayerId;
uint32_t temporalLayerId;
VkBool32 useInitialRcQp;
VkVideoEncodeH264QpEXT initialRcQp;
VkBool32 useMinQp;
@@ -340,7 +318,7 @@ typedef struct VkVideoEncodeH264RateControlLayerInfoEXT {
#define VK_EXT_video_encode_h265 1
#include "vk_video/vulkan_video_codec_h265std.h"
#include "vk_video/vulkan_video_codec_h265std_encode.h"
#define VK_EXT_VIDEO_ENCODE_H265_SPEC_VERSION 9
#define VK_EXT_VIDEO_ENCODE_H265_SPEC_VERSION 10
#define VK_EXT_VIDEO_ENCODE_H265_EXTENSION_NAME "VK_EXT_video_encode_h265"
typedef enum VkVideoEncodeH265RateControlStructureEXT {
@@ -377,26 +355,11 @@ typedef enum VkVideoEncodeH265CapabilityFlagBitsEXT {
VK_VIDEO_ENCODE_H265_CAPABILITY_DEPENDENT_SLICE_SEGMENT_BIT_EXT = 0x00800000,
VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_EXT = 0x01000000,
VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x02000000,
VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_REFERENCE_FINAL_LISTS_BIT_EXT = 0x04000000,
VK_VIDEO_ENCODE_H265_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265CapabilityFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265CapabilityFlagsEXT;
typedef enum VkVideoEncodeH265InputModeFlagBitsEXT {
VK_VIDEO_ENCODE_H265_INPUT_MODE_FRAME_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_INPUT_MODE_SLICE_SEGMENT_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_INPUT_MODE_NON_VCL_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_INPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265InputModeFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265InputModeFlagsEXT;
typedef enum VkVideoEncodeH265OutputModeFlagBitsEXT {
VK_VIDEO_ENCODE_H265_OUTPUT_MODE_FRAME_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_OUTPUT_MODE_SLICE_SEGMENT_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_OUTPUT_MODE_NON_VCL_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_OUTPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265OutputModeFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265OutputModeFlagsEXT;
typedef enum VkVideoEncodeH265CtbSizeFlagBitsEXT {
VK_VIDEO_ENCODE_H265_CTB_SIZE_16_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_CTB_SIZE_32_BIT_EXT = 0x00000002,
@@ -417,25 +380,23 @@ typedef struct VkVideoEncodeH265CapabilitiesEXT {
VkStructureType sType;
void* pNext;
VkVideoEncodeH265CapabilityFlagsEXT flags;
VkVideoEncodeH265InputModeFlagsEXT inputModeFlags;
VkVideoEncodeH265OutputModeFlagsEXT outputModeFlags;
VkVideoEncodeH265CtbSizeFlagsEXT ctbSizes;
VkVideoEncodeH265TransformBlockSizeFlagsEXT transformBlockSizes;
uint8_t maxPPictureL0ReferenceCount;
uint8_t maxBPictureL0ReferenceCount;
uint8_t maxL1ReferenceCount;
uint8_t maxSubLayersCount;
uint8_t minLog2MinLumaCodingBlockSizeMinus3;
uint8_t maxLog2MinLumaCodingBlockSizeMinus3;
uint8_t minLog2MinLumaTransformBlockSizeMinus2;
uint8_t maxLog2MinLumaTransformBlockSizeMinus2;
uint8_t minMaxTransformHierarchyDepthInter;
uint8_t maxMaxTransformHierarchyDepthInter;
uint8_t minMaxTransformHierarchyDepthIntra;
uint8_t maxMaxTransformHierarchyDepthIntra;
uint8_t maxDiffCuQpDeltaDepth;
uint8_t minMaxNumMergeCand;
uint8_t maxMaxNumMergeCand;
uint32_t maxPPictureL0ReferenceCount;
uint32_t maxBPictureL0ReferenceCount;
uint32_t maxL1ReferenceCount;
uint32_t maxSubLayersCount;
uint32_t minLog2MinLumaCodingBlockSizeMinus3;
uint32_t maxLog2MinLumaCodingBlockSizeMinus3;
uint32_t minLog2MinLumaTransformBlockSizeMinus2;
uint32_t maxLog2MinLumaTransformBlockSizeMinus2;
uint32_t minMaxTransformHierarchyDepthInter;
uint32_t maxMaxTransformHierarchyDepthInter;
uint32_t minMaxTransformHierarchyDepthIntra;
uint32_t maxMaxTransformHierarchyDepthIntra;
uint32_t maxDiffCuQpDeltaDepth;
uint32_t minMaxNumMergeCand;
uint32_t maxMaxNumMergeCand;
} VkVideoEncodeH265CapabilitiesEXT;
typedef struct VkVideoEncodeH265SessionParametersAddInfoEXT {
@@ -458,50 +419,28 @@ typedef struct VkVideoEncodeH265SessionParametersCreateInfoEXT {
const VkVideoEncodeH265SessionParametersAddInfoEXT* pParametersAddInfo;
} VkVideoEncodeH265SessionParametersCreateInfoEXT;
typedef struct VkVideoEncodeH265DpbSlotInfoEXT {
VkStructureType sType;
const void* pNext;
int8_t slotIndex;
const StdVideoEncodeH265ReferenceInfo* pStdReferenceInfo;
} VkVideoEncodeH265DpbSlotInfoEXT;
typedef struct VkVideoEncodeH265ReferenceListsInfoEXT {
VkStructureType sType;
const void* pNext;
uint8_t referenceList0EntryCount;
const VkVideoEncodeH265DpbSlotInfoEXT* pReferenceList0Entries;
uint8_t referenceList1EntryCount;
const VkVideoEncodeH265DpbSlotInfoEXT* pReferenceList1Entries;
const StdVideoEncodeH265ReferenceModifications* pReferenceModifications;
} VkVideoEncodeH265ReferenceListsInfoEXT;
typedef struct VkVideoEncodeH265NaluSliceSegmentInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t ctbCount;
const VkVideoEncodeH265ReferenceListsInfoEXT* pReferenceFinalLists;
const StdVideoEncodeH265SliceSegmentHeader* pSliceSegmentHeaderStd;
VkStructureType sType;
const void* pNext;
uint32_t ctbCount;
const StdVideoEncodeH265ReferenceListsInfo* pStdReferenceFinalLists;
const StdVideoEncodeH265SliceSegmentHeader* pStdSliceSegmentHeader;
} VkVideoEncodeH265NaluSliceSegmentInfoEXT;
typedef struct VkVideoEncodeH265VclFrameInfoEXT {
VkStructureType sType;
const void* pNext;
const VkVideoEncodeH265ReferenceListsInfoEXT* pReferenceFinalLists;
const StdVideoEncodeH265ReferenceListsInfo* pStdReferenceFinalLists;
uint32_t naluSliceSegmentEntryCount;
const VkVideoEncodeH265NaluSliceSegmentInfoEXT* pNaluSliceSegmentEntries;
const StdVideoEncodeH265PictureInfo* pCurrentPictureInfo;
const StdVideoEncodeH265PictureInfo* pStdPictureInfo;
} VkVideoEncodeH265VclFrameInfoEXT;
typedef struct VkVideoEncodeH265EmitPictureParametersInfoEXT {
VkStructureType sType;
const void* pNext;
uint8_t vpsId;
uint8_t spsId;
VkBool32 emitVpsEnable;
VkBool32 emitSpsEnable;
uint32_t ppsIdEntryCount;
const uint8_t* ppsIdEntries;
} VkVideoEncodeH265EmitPictureParametersInfoEXT;
typedef struct VkVideoEncodeH265DpbSlotInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH265ReferenceInfo* pStdReferenceInfo;
} VkVideoEncodeH265DpbSlotInfoEXT;
typedef struct VkVideoEncodeH265ProfileInfoEXT {
VkStructureType sType;
@@ -516,7 +455,7 @@ typedef struct VkVideoEncodeH265RateControlInfoEXT {
uint32_t idrPeriod;
uint32_t consecutiveBFrameCount;
VkVideoEncodeH265RateControlStructureEXT rateControlStructure;
uint8_t subLayerCount;
uint32_t subLayerCount;
} VkVideoEncodeH265RateControlInfoEXT;
typedef struct VkVideoEncodeH265QpEXT {
@@ -534,7 +473,7 @@ typedef struct VkVideoEncodeH265FrameSizeEXT {
typedef struct VkVideoEncodeH265RateControlLayerInfoEXT {
VkStructureType sType;
const void* pNext;
uint8_t temporalId;
uint32_t temporalId;
VkBool32 useInitialRcQp;
VkVideoEncodeH265QpEXT initialRcQp;
VkBool32 useMinQp;
@@ -546,6 +485,51 @@ typedef struct VkVideoEncodeH265RateControlLayerInfoEXT {
} VkVideoEncodeH265RateControlLayerInfoEXT;
#define VK_NV_displacement_micromap 1
#define VK_NV_DISPLACEMENT_MICROMAP_SPEC_VERSION 1
#define VK_NV_DISPLACEMENT_MICROMAP_EXTENSION_NAME "VK_NV_displacement_micromap"
typedef enum VkDisplacementMicromapFormatNV {
VK_DISPLACEMENT_MICROMAP_FORMAT_64_TRIANGLES_64_BYTES_NV = 1,
VK_DISPLACEMENT_MICROMAP_FORMAT_256_TRIANGLES_128_BYTES_NV = 2,
VK_DISPLACEMENT_MICROMAP_FORMAT_1024_TRIANGLES_128_BYTES_NV = 3,
VK_DISPLACEMENT_MICROMAP_FORMAT_MAX_ENUM_NV = 0x7FFFFFFF
} VkDisplacementMicromapFormatNV;
typedef struct VkPhysicalDeviceDisplacementMicromapFeaturesNV {
VkStructureType sType;
void* pNext;
VkBool32 displacementMicromap;
} VkPhysicalDeviceDisplacementMicromapFeaturesNV;
typedef struct VkPhysicalDeviceDisplacementMicromapPropertiesNV {
VkStructureType sType;
void* pNext;
uint32_t maxDisplacementMicromapSubdivisionLevel;
} VkPhysicalDeviceDisplacementMicromapPropertiesNV;
typedef struct VkAccelerationStructureTrianglesDisplacementMicromapNV {
VkStructureType sType;
void* pNext;
VkFormat displacementBiasAndScaleFormat;
VkFormat displacementVectorFormat;
VkDeviceOrHostAddressConstKHR displacementBiasAndScaleBuffer;
VkDeviceSize displacementBiasAndScaleStride;
VkDeviceOrHostAddressConstKHR displacementVectorBuffer;
VkDeviceSize displacementVectorStride;
VkDeviceOrHostAddressConstKHR displacedMicromapPrimitiveFlags;
VkDeviceSize displacedMicromapPrimitiveFlagsStride;
VkIndexType indexType;
VkDeviceOrHostAddressConstKHR indexBuffer;
VkDeviceSize indexStride;
uint32_t baseTriangle;
uint32_t usageCountsCount;
const VkMicromapUsageEXT* pUsageCounts;
const VkMicromapUsageEXT* const* ppUsageCounts;
VkMicromapEXT micromap;
} VkAccelerationStructureTrianglesDisplacementMicromapNV;
#ifdef __cplusplus
}
#endif
@@ -2,7 +2,7 @@
#define VULKAN_CORE_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -58,37 +58,37 @@ extern "C" {
#endif
#endif
// DEPRECATED: This define is deprecated. VK_MAKE_API_VERSION should be used instead.
#define VK_MAKE_VERSION(major, minor, patch) \
((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch)))
#define VK_MAKE_API_VERSION(variant, major, minor, patch) \
((((uint32_t)(variant)) << 29U) | (((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch)))
// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead.
//#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) // Patch version should always be set to 0
#define VK_MAKE_API_VERSION(variant, major, minor, patch) \
((((uint32_t)(variant)) << 29) | (((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch)))
//#define VK_API_VERSION VK_MAKE_API_VERSION(0, 1, 0, 0) // Patch version should always be set to 0
// Vulkan 1.0 version number
#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0
// Version of this file
#define VK_HEADER_VERSION 238
#define VK_HEADER_VERSION 248
// Complete version of this file
#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION)
// DEPRECATED: This define is deprecated. VK_MAKE_API_VERSION should be used instead.
#define VK_MAKE_VERSION(major, minor, patch) \
((((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch)))
// DEPRECATED: This define is deprecated. VK_API_VERSION_MAJOR should be used instead.
#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22)
#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22U)
// DEPRECATED: This define is deprecated. VK_API_VERSION_MINOR should be used instead.
#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU)
#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12U) & 0x3FFU)
// DEPRECATED: This define is deprecated. VK_API_VERSION_PATCH should be used instead.
#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU)
#define VK_API_VERSION_VARIANT(version) ((uint32_t)(version) >> 29)
#define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22) & 0x7FU)
#define VK_API_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU)
#define VK_API_VERSION_VARIANT(version) ((uint32_t)(version) >> 29U)
#define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22U) & 0x7FU)
#define VK_API_VERSION_MINOR(version) (((uint32_t)(version) >> 12U) & 0x3FFU)
#define VK_API_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU)
typedef uint32_t VkBool32;
typedef uint64_t VkDeviceAddress;
@@ -181,7 +181,11 @@ typedef enum VkResult {
VK_THREAD_DONE_KHR = 1000268001,
VK_OPERATION_DEFERRED_KHR = 1000268002,
VK_OPERATION_NOT_DEFERRED_KHR = 1000268003,
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR = -1000299000,
#endif
VK_ERROR_COMPRESSION_EXHAUSTED_EXT = -1000338000,
VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT = 1000482000,
VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY,
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE,
VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION,
@@ -480,9 +484,6 @@ typedef enum VkStructureType {
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_INFO_EXT = 1000038005,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_INFO_EXT = 1000038006,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_EXT = 1000038007,
#endif
@@ -492,9 +493,6 @@ typedef enum VkStructureType {
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_LAYER_INFO_EXT = 1000038009,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_REFERENCE_LISTS_INFO_EXT = 1000038010,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_CAPABILITIES_EXT = 1000039000,
#endif
@@ -513,15 +511,9 @@ typedef enum VkStructureType {
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_NALU_SLICE_SEGMENT_INFO_EXT = 1000039005,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_EMIT_PICTURE_PARAMETERS_INFO_EXT = 1000039006,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_EXT = 1000039007,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_REFERENCE_LISTS_INFO_EXT = 1000039008,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_EXT = 1000039009,
#endif
@@ -777,6 +769,8 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR = 1000269003,
VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004,
VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005,
VK_STRUCTURE_TYPE_MEMORY_MAP_INFO_KHR = 1000271000,
VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR = 1000271001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000,
VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT = 1000274000,
VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT = 1000274001,
@@ -828,9 +822,13 @@ typedef enum VkStructureType {
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_VIDEO_ENCODE_USAGE_INFO_KHR = 1000299004,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_QUERY_POOL_VIDEO_ENCODE_FEEDBACK_CREATE_INFO_KHR = 1000299005,
#endif
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000,
VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001,
VK_STRUCTURE_TYPE_QUERY_LOW_LATENCY_SUPPORT_NV = 1000310000,
VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECT_CREATE_INFO_EXT = 1000311000,
VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECTS_INFO_EXT = 1000311001,
VK_STRUCTURE_TYPE_EXPORT_METAL_DEVICE_INFO_EXT = 1000311002,
@@ -936,6 +934,8 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT = 1000393000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT = 1000395000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_PROPERTIES_EXT = 1000395001,
VK_STRUCTURE_TYPE_MICROMAP_BUILD_INFO_EXT = 1000396000,
VK_STRUCTURE_TYPE_MICROMAP_VERSION_INFO_EXT = 1000396001,
VK_STRUCTURE_TYPE_COPY_MICROMAP_INFO_EXT = 1000396002,
@@ -946,9 +946,23 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_MICROMAP_CREATE_INFO_EXT = 1000396007,
VK_STRUCTURE_TYPE_MICROMAP_BUILD_SIZES_INFO_EXT = 1000396008,
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_TRIANGLES_OPACITY_MICROMAP_EXT = 1000396009,
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISPLACEMENT_MICROMAP_FEATURES_NV = 1000397000,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISPLACEMENT_MICROMAP_PROPERTIES_NV = 1000397001,
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_TRIANGLES_DISPLACEMENT_MICROMAP_NV = 1000397002,
#endif
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_FEATURES_HUAWEI = 1000404000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_PROPERTIES_HUAWEI = 1000404001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT = 1000411000,
VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT = 1000411001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_ARM = 1000415000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT = 1000418000,
VK_STRUCTURE_TYPE_IMAGE_VIEW_SLICED_CREATE_INFO_EXT = 1000418001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE = 1000420000,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_BINDING_REFERENCE_VALVE = 1000420001,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_HOST_MAPPING_INFO_VALVE = 1000420002,
@@ -988,6 +1002,9 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_OPTICAL_FLOW_SESSION_CREATE_PRIVATE_DATA_INFO_NV = 1000464010,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT = 1000465000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT = 1000466000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT = 1000482000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT = 1000482001,
VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT = 1000482002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM = 1000484000,
VK_STRUCTURE_TYPE_TILE_PROPERTIES_QCOM = 1000484001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC = 1000485000,
@@ -999,6 +1016,9 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT = 1000351002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_FEATURES_ARM = 1000497000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_PROPERTIES_ARM = 1000497001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT = 1000498000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_RENDER_AREAS_FEATURES_QCOM = 1000510000,
VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_RENDER_AREAS_RENDER_PASS_BEGIN_INFO_QCOM = 1000510001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES,
VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
@@ -1172,6 +1192,7 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES,
VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS,
VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS,
VK_STRUCTURE_TYPE_SHADER_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO,
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkStructureType;
@@ -1276,6 +1297,7 @@ typedef enum VkObjectType {
VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = 1000366000,
VK_OBJECT_TYPE_MICROMAP_EXT = 1000396000,
VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV = 1000464000,
VK_OBJECT_TYPE_SHADER_EXT = 1000482000,
VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE,
VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,
VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = VK_OBJECT_TYPE_PRIVATE_DATA_SLOT,
@@ -1289,6 +1311,7 @@ typedef enum VkVendorId {
VK_VENDOR_ID_CODEPLAY = 0x10004,
VK_VENDOR_ID_MESA = 0x10005,
VK_VENDOR_ID_POCL = 0x10006,
VK_VENDOR_ID_MOBILEYE = 0x10007,
VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF
} VkVendorId;
@@ -1647,7 +1670,7 @@ typedef enum VkQueryType {
VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000,
VK_QUERY_TYPE_PERFORMANCE_QUERY_INTEL = 1000210000,
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_QUERY_TYPE_VIDEO_ENCODE_BITSTREAM_BUFFER_RANGE_KHR = 1000299000,
VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR = 1000299000,
#endif
VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT = 1000328000,
VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT = 1000382000,
@@ -1803,10 +1826,13 @@ typedef enum VkDynamicState {
VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004,
VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000,
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000,
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT = 1000099001,
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT = 1000099002,
VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000,
VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR = 1000347000,
VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1000164004,
VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006,
VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV = 1000205000,
VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001,
VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR = 1000226000,
VK_DYNAMIC_STATE_LINE_STIPPLE_EXT = 1000259000,
@@ -2352,6 +2378,7 @@ typedef enum VkQueryPipelineStatisticFlagBits {
VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 0x00000400,
VK_QUERY_PIPELINE_STATISTIC_TASK_SHADER_INVOCATIONS_BIT_EXT = 0x00000800,
VK_QUERY_PIPELINE_STATISTIC_MESH_SHADER_INVOCATIONS_BIT_EXT = 0x00001000,
VK_QUERY_PIPELINE_STATISTIC_CLUSTER_CULLING_SHADER_INVOCATIONS_BIT_HUAWEI = 0x00002000,
VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkQueryPipelineStatisticFlagBits;
typedef VkFlags VkQueryPipelineStatisticFlags;
@@ -2472,6 +2499,9 @@ typedef enum VkPipelineCreateFlagBits {
VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x02000000,
VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x04000000,
VK_PIPELINE_CREATE_RAY_TRACING_OPACITY_MICROMAP_BIT_EXT = 0x01000000,
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_PIPELINE_CREATE_RAY_TRACING_DISPLACEMENT_MICROMAP_BIT_NV = 0x10000000,
#endif
VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT = 0x08000000,
VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT = 0x40000000,
VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT,
@@ -2512,6 +2542,7 @@ typedef enum VkShaderStageFlagBits {
VK_SHADER_STAGE_TASK_BIT_EXT = 0x00000040,
VK_SHADER_STAGE_MESH_BIT_EXT = 0x00000080,
VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI = 0x00004000,
VK_SHADER_STAGE_CLUSTER_CULLING_BIT_HUAWEI = 0x00080000,
VK_SHADER_STAGE_RAYGEN_BIT_NV = VK_SHADER_STAGE_RAYGEN_BIT_KHR,
VK_SHADER_STAGE_ANY_HIT_BIT_NV = VK_SHADER_STAGE_ANY_HIT_BIT_KHR,
VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,
@@ -5641,6 +5672,7 @@ typedef enum VkDriverId {
VK_DRIVER_ID_MESA_VENUS = 22,
VK_DRIVER_ID_MESA_DOZEN = 23,
VK_DRIVER_ID_MESA_NVK = 24,
VK_DRIVER_ID_IMAGINATION_OPEN_SOURCE_MESA = 25,
VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY,
VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE,
VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV,
@@ -6475,6 +6507,7 @@ static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HU
static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL;
static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR = 0x10000000ULL;
static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MICROMAP_BUILD_BIT_EXT = 0x40000000ULL;
static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLUSTER_CULLING_SHADER_BIT_HUAWEI = 0x20000000000ULL;
static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_OPTICAL_FLOW_BIT_NV = 0x20000000ULL;
typedef VkFlags64 VkAccessFlags2;
@@ -9824,6 +9857,41 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR
#endif
#define VK_KHR_map_memory2 1
#define VK_KHR_MAP_MEMORY_2_SPEC_VERSION 1
#define VK_KHR_MAP_MEMORY_2_EXTENSION_NAME "VK_KHR_map_memory2"
typedef VkFlags VkMemoryUnmapFlagsKHR;
typedef struct VkMemoryMapInfoKHR {
VkStructureType sType;
const void* pNext;
VkMemoryMapFlags flags;
VkDeviceMemory memory;
VkDeviceSize offset;
VkDeviceSize size;
} VkMemoryMapInfoKHR;
typedef struct VkMemoryUnmapInfoKHR {
VkStructureType sType;
const void* pNext;
VkMemoryUnmapFlagsKHR flags;
VkDeviceMemory memory;
} VkMemoryUnmapInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkMapMemory2KHR)(VkDevice device, const VkMemoryMapInfoKHR* pMemoryMapInfo, void** ppData);
typedef VkResult (VKAPI_PTR *PFN_vkUnmapMemory2KHR)(VkDevice device, const VkMemoryUnmapInfoKHR* pMemoryUnmapInfo);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory2KHR(
VkDevice device,
const VkMemoryMapInfoKHR* pMemoryMapInfo,
void** ppData);
VKAPI_ATTR VkResult VKAPI_CALL vkUnmapMemory2KHR(
VkDevice device,
const VkMemoryUnmapInfoKHR* pMemoryUnmapInfo);
#endif
#define VK_KHR_shader_integer_dot_product 1
#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION 1
#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME "VK_KHR_shader_integer_dot_product"
@@ -11158,7 +11226,7 @@ typedef struct VkPipelineViewportSwizzleStateCreateInfoNV {
#define VK_EXT_discard_rectangles 1
#define VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION 1
#define VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION 2
#define VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME "VK_EXT_discard_rectangles"
typedef enum VkDiscardRectangleModeEXT {
@@ -11183,6 +11251,8 @@ typedef struct VkPipelineDiscardRectangleStateCreateInfoEXT {
} VkPipelineDiscardRectangleStateCreateInfoEXT;
typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleEXT)(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle, uint32_t discardRectangleCount, const VkRect2D* pDiscardRectangles);
typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 discardRectangleEnable);
typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleModeEXT)(VkCommandBuffer commandBuffer, VkDiscardRectangleModeEXT discardRectangleMode);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEXT(
@@ -11190,6 +11260,14 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEXT(
uint32_t firstDiscardRectangle,
uint32_t discardRectangleCount,
const VkRect2D* pDiscardRectangles);
VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 discardRectangleEnable);
VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleModeEXT(
VkCommandBuffer commandBuffer,
VkDiscardRectangleModeEXT discardRectangleMode);
#endif
@@ -12009,6 +12087,9 @@ typedef enum VkBuildAccelerationStructureFlagBitsKHR {
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_EXT = 0x00000040,
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISABLE_OPACITY_MICROMAPS_EXT = 0x00000080,
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_DATA_UPDATE_EXT = 0x00000100,
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISPLACEMENT_MICROMAP_UPDATE_NV = 0x00000200,
#endif
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR,
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR,
VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR,
@@ -12610,7 +12691,7 @@ typedef struct VkPhysicalDeviceShaderImageFootprintFeaturesNV {
#define VK_NV_scissor_exclusive 1
#define VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION 1
#define VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION 2
#define VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME "VK_NV_scissor_exclusive"
typedef struct VkPipelineViewportExclusiveScissorStateCreateInfoNV {
VkStructureType sType;
@@ -12625,9 +12706,16 @@ typedef struct VkPhysicalDeviceExclusiveScissorFeaturesNV {
VkBool32 exclusiveScissor;
} VkPhysicalDeviceExclusiveScissorFeaturesNV;
typedef void (VKAPI_PTR *PFN_vkCmdSetExclusiveScissorEnableNV)(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkBool32* pExclusiveScissorEnables);
typedef void (VKAPI_PTR *PFN_vkCmdSetExclusiveScissorNV)(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkRect2D* pExclusiveScissors);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR void VKAPI_CALL vkCmdSetExclusiveScissorEnableNV(
VkCommandBuffer commandBuffer,
uint32_t firstExclusiveScissor,
uint32_t exclusiveScissorCount,
const VkBool32* pExclusiveScissorEnables);
VKAPI_ATTR void VKAPI_CALL vkCmdSetExclusiveScissorNV(
VkCommandBuffer commandBuffer,
uint32_t firstExclusiveScissor,
@@ -13520,21 +13608,21 @@ typedef struct VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT {
typedef struct VkSwapchainPresentFenceInfoEXT {
VkStructureType sType;
void* pNext;
const void* pNext;
uint32_t swapchainCount;
const VkFence* pFences;
} VkSwapchainPresentFenceInfoEXT;
typedef struct VkSwapchainPresentModesCreateInfoEXT {
VkStructureType sType;
void* pNext;
const void* pNext;
uint32_t presentModeCount;
const VkPresentModeKHR* pPresentModes;
} VkSwapchainPresentModesCreateInfoEXT;
typedef struct VkSwapchainPresentModeInfoEXT {
VkStructureType sType;
void* pNext;
const void* pNext;
uint32_t swapchainCount;
const VkPresentModeKHR* pPresentModes;
} VkSwapchainPresentModeInfoEXT;
@@ -14034,6 +14122,17 @@ typedef struct VkDeviceDiagnosticsConfigCreateInfoNV {
#define VK_QCOM_RENDER_PASS_STORE_OPS_EXTENSION_NAME "VK_QCOM_render_pass_store_ops"
#define VK_NV_low_latency 1
#define VK_NV_LOW_LATENCY_SPEC_VERSION 1
#define VK_NV_LOW_LATENCY_EXTENSION_NAME "VK_NV_low_latency"
typedef struct VkQueryLowLatencySupportNV {
VkStructureType sType;
const void* pNext;
void* pQueriedLowLatencyData;
} VkQueryLowLatencySupportNV;
#define VK_EXT_descriptor_buffer 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR)
#define VK_EXT_DESCRIPTOR_BUFFER_SPEC_VERSION 1
@@ -14596,7 +14695,7 @@ typedef struct VkPhysicalDevice4444FormatsFeaturesEXT {
#define VK_EXT_device_fault 1
#define VK_EXT_DEVICE_FAULT_SPEC_VERSION 1
#define VK_EXT_DEVICE_FAULT_SPEC_VERSION 2
#define VK_EXT_DEVICE_FAULT_EXTENSION_NAME "VK_EXT_device_fault"
typedef enum VkDeviceFaultAddressTypeEXT {
@@ -14660,6 +14759,8 @@ typedef struct VkDeviceFaultVendorBinaryHeaderVersionOneEXT {
uint32_t applicationNameOffset;
uint32_t applicationVersion;
uint32_t engineNameOffset;
uint32_t engineVersion;
uint32_t apiVersion;
} VkDeviceFaultVendorBinaryHeaderVersionOneEXT;
typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceFaultInfoEXT)(VkDevice device, VkDeviceFaultCountsEXT* pFaultCounts, VkDeviceFaultInfoEXT* pFaultInfo);
@@ -15143,6 +15244,27 @@ typedef struct VkPhysicalDeviceImage2DViewOf3DFeaturesEXT {
#define VK_EXT_shader_tile_image 1
#define VK_EXT_SHADER_TILE_IMAGE_SPEC_VERSION 1
#define VK_EXT_SHADER_TILE_IMAGE_EXTENSION_NAME "VK_EXT_shader_tile_image"
typedef struct VkPhysicalDeviceShaderTileImageFeaturesEXT {
VkStructureType sType;
void* pNext;
VkBool32 shaderTileImageColorReadAccess;
VkBool32 shaderTileImageDepthReadAccess;
VkBool32 shaderTileImageStencilReadAccess;
} VkPhysicalDeviceShaderTileImageFeaturesEXT;
typedef struct VkPhysicalDeviceShaderTileImagePropertiesEXT {
VkStructureType sType;
void* pNext;
VkBool32 shaderTileImageCoherentReadAccelerated;
VkBool32 shaderTileImageReadSampleFromPixelRateInvocation;
VkBool32 shaderTileImageReadFromHelperInvocation;
} VkPhysicalDeviceShaderTileImagePropertiesEXT;
#define VK_EXT_opacity_micromap 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkMicromapEXT)
#define VK_EXT_OPACITY_MICROMAP_SPEC_VERSION 2
@@ -15150,6 +15272,9 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkMicromapEXT)
typedef enum VkMicromapTypeEXT {
VK_MICROMAP_TYPE_OPACITY_MICROMAP_EXT = 0,
#ifdef VK_ENABLE_BETA_EXTENSIONS
VK_MICROMAP_TYPE_DISPLACEMENT_MICROMAP_NV = 1000397000,
#endif
VK_MICROMAP_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
} VkMicromapTypeEXT;
@@ -15416,6 +15541,42 @@ VKAPI_ATTR void VKAPI_CALL vkGetMicromapBuildSizesEXT(
#define VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_EXT_load_store_op_none"
#define VK_HUAWEI_cluster_culling_shader 1
#define VK_HUAWEI_CLUSTER_CULLING_SHADER_SPEC_VERSION 2
#define VK_HUAWEI_CLUSTER_CULLING_SHADER_EXTENSION_NAME "VK_HUAWEI_cluster_culling_shader"
typedef struct VkPhysicalDeviceClusterCullingShaderFeaturesHUAWEI {
VkStructureType sType;
void* pNext;
VkBool32 clustercullingShader;
VkBool32 multiviewClusterCullingShader;
} VkPhysicalDeviceClusterCullingShaderFeaturesHUAWEI;
typedef struct VkPhysicalDeviceClusterCullingShaderPropertiesHUAWEI {
VkStructureType sType;
void* pNext;
uint32_t maxWorkGroupCount[3];
uint32_t maxWorkGroupSize[3];
uint32_t maxOutputClusterCount;
VkDeviceSize indirectBufferOffsetAlignment;
} VkPhysicalDeviceClusterCullingShaderPropertiesHUAWEI;
typedef void (VKAPI_PTR *PFN_vkCmdDrawClusterHUAWEI)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
typedef void (VKAPI_PTR *PFN_vkCmdDrawClusterIndirectHUAWEI)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR void VKAPI_CALL vkCmdDrawClusterHUAWEI(
VkCommandBuffer commandBuffer,
uint32_t groupCountX,
uint32_t groupCountY,
uint32_t groupCountZ);
VKAPI_ATTR void VKAPI_CALL vkCmdDrawClusterIndirectHUAWEI(
VkCommandBuffer commandBuffer,
VkBuffer buffer,
VkDeviceSize offset);
#endif
#define VK_EXT_border_color_swizzle 1
#define VK_EXT_BORDER_COLOR_SWIZZLE_SPEC_VERSION 1
#define VK_EXT_BORDER_COLOR_SWIZZLE_EXTENSION_NAME "VK_EXT_border_color_swizzle"
@@ -15454,6 +15615,38 @@ VKAPI_ATTR void VKAPI_CALL vkSetDeviceMemoryPriorityEXT(
#endif
#define VK_ARM_shader_core_properties 1
#define VK_ARM_SHADER_CORE_PROPERTIES_SPEC_VERSION 1
#define VK_ARM_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_ARM_shader_core_properties"
typedef struct VkPhysicalDeviceShaderCorePropertiesARM {
VkStructureType sType;
void* pNext;
uint32_t pixelRate;
uint32_t texelRate;
uint32_t fmaRate;
} VkPhysicalDeviceShaderCorePropertiesARM;
#define VK_EXT_image_sliced_view_of_3d 1
#define VK_EXT_IMAGE_SLICED_VIEW_OF_3D_SPEC_VERSION 1
#define VK_EXT_IMAGE_SLICED_VIEW_OF_3D_EXTENSION_NAME "VK_EXT_image_sliced_view_of_3d"
#define VK_REMAINING_3D_SLICES_EXT (~0U)
typedef struct VkPhysicalDeviceImageSlicedViewOf3DFeaturesEXT {
VkStructureType sType;
void* pNext;
VkBool32 imageSlicedViewOf3D;
} VkPhysicalDeviceImageSlicedViewOf3DFeaturesEXT;
typedef struct VkImageViewSlicedCreateInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t sliceOffset;
uint32_t sliceCount;
} VkImageViewSlicedCreateInfoEXT;
#define VK_VALVE_descriptor_set_host_mapping 1
#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_SPEC_VERSION 1
#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_EXTENSION_NAME "VK_VALVE_descriptor_set_host_mapping"
@@ -16251,6 +16444,92 @@ typedef struct VkPhysicalDevicePipelineProtectedAccessFeaturesEXT {
#define VK_EXT_shader_object 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderEXT)
#define VK_EXT_SHADER_OBJECT_SPEC_VERSION 1
#define VK_EXT_SHADER_OBJECT_EXTENSION_NAME "VK_EXT_shader_object"
typedef enum VkShaderCodeTypeEXT {
VK_SHADER_CODE_TYPE_BINARY_EXT = 0,
VK_SHADER_CODE_TYPE_SPIRV_EXT = 1,
VK_SHADER_CODE_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
} VkShaderCodeTypeEXT;
typedef enum VkShaderCreateFlagBitsEXT {
VK_SHADER_CREATE_LINK_STAGE_BIT_EXT = 0x00000001,
VK_SHADER_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = 0x00000002,
VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = 0x00000004,
VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT = 0x00000008,
VK_SHADER_CREATE_DISPATCH_BASE_BIT_EXT = 0x00000010,
VK_SHADER_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_EXT = 0x00000020,
VK_SHADER_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00000040,
VK_SHADER_CREATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkShaderCreateFlagBitsEXT;
typedef VkFlags VkShaderCreateFlagsEXT;
typedef struct VkPhysicalDeviceShaderObjectFeaturesEXT {
VkStructureType sType;
void* pNext;
VkBool32 shaderObject;
} VkPhysicalDeviceShaderObjectFeaturesEXT;
typedef struct VkPhysicalDeviceShaderObjectPropertiesEXT {
VkStructureType sType;
void* pNext;
uint8_t shaderBinaryUUID[VK_UUID_SIZE];
uint32_t shaderBinaryVersion;
} VkPhysicalDeviceShaderObjectPropertiesEXT;
typedef struct VkShaderCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkShaderCreateFlagsEXT flags;
VkShaderStageFlagBits stage;
VkShaderStageFlags nextStage;
VkShaderCodeTypeEXT codeType;
size_t codeSize;
const void* pCode;
const char* pName;
uint32_t setLayoutCount;
const VkDescriptorSetLayout* pSetLayouts;
uint32_t pushConstantRangeCount;
const VkPushConstantRange* pPushConstantRanges;
const VkSpecializationInfo* pSpecializationInfo;
} VkShaderCreateInfoEXT;
typedef VkPipelineShaderStageRequiredSubgroupSizeCreateInfo VkShaderRequiredSubgroupSizeCreateInfoEXT;
typedef VkResult (VKAPI_PTR *PFN_vkCreateShadersEXT)(VkDevice device, uint32_t createInfoCount, const VkShaderCreateInfoEXT* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkShaderEXT* pShaders);
typedef void (VKAPI_PTR *PFN_vkDestroyShaderEXT)(VkDevice device, VkShaderEXT shader, const VkAllocationCallbacks* pAllocator);
typedef VkResult (VKAPI_PTR *PFN_vkGetShaderBinaryDataEXT)(VkDevice device, VkShaderEXT shader, size_t* pDataSize, void* pData);
typedef void (VKAPI_PTR *PFN_vkCmdBindShadersEXT)(VkCommandBuffer commandBuffer, uint32_t stageCount, const VkShaderStageFlagBits* pStages, const VkShaderEXT* pShaders);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateShadersEXT(
VkDevice device,
uint32_t createInfoCount,
const VkShaderCreateInfoEXT* pCreateInfos,
const VkAllocationCallbacks* pAllocator,
VkShaderEXT* pShaders);
VKAPI_ATTR void VKAPI_CALL vkDestroyShaderEXT(
VkDevice device,
VkShaderEXT shader,
const VkAllocationCallbacks* pAllocator);
VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderBinaryDataEXT(
VkDevice device,
VkShaderEXT shader,
size_t* pDataSize,
void* pData);
VKAPI_ATTR void VKAPI_CALL vkCmdBindShadersEXT(
VkCommandBuffer commandBuffer,
uint32_t stageCount,
const VkShaderStageFlagBits* pStages,
const VkShaderEXT* pShaders);
#endif
#define VK_QCOM_tile_properties 1
#define VK_QCOM_TILE_PROPERTIES_SPEC_VERSION 1
#define VK_QCOM_TILE_PROPERTIES_EXTENSION_NAME "VK_QCOM_tile_properties"
@@ -16361,6 +16640,35 @@ typedef struct VkPhysicalDeviceShaderCoreBuiltinsPropertiesARM {
#define VK_EXT_pipeline_library_group_handles 1
#define VK_EXT_PIPELINE_LIBRARY_GROUP_HANDLES_SPEC_VERSION 1
#define VK_EXT_PIPELINE_LIBRARY_GROUP_HANDLES_EXTENSION_NAME "VK_EXT_pipeline_library_group_handles"
typedef struct VkPhysicalDevicePipelineLibraryGroupHandlesFeaturesEXT {
VkStructureType sType;
void* pNext;
VkBool32 pipelineLibraryGroupHandles;
} VkPhysicalDevicePipelineLibraryGroupHandlesFeaturesEXT;
#define VK_QCOM_multiview_per_view_render_areas 1
#define VK_QCOM_MULTIVIEW_PER_VIEW_RENDER_AREAS_SPEC_VERSION 1
#define VK_QCOM_MULTIVIEW_PER_VIEW_RENDER_AREAS_EXTENSION_NAME "VK_QCOM_multiview_per_view_render_areas"
typedef struct VkPhysicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM {
VkStructureType sType;
void* pNext;
VkBool32 multiviewPerViewRenderAreas;
} VkPhysicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM;
typedef struct VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM {
VkStructureType sType;
const void* pNext;
uint32_t perViewRenderAreaCount;
const VkRect2D* pPerViewRenderAreas;
} VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM;
#define VK_KHR_acceleration_structure 1
#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13
#define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure"
@@ -2,7 +2,7 @@
#define VULKAN_DIRECTFB_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_FUCHSIA_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_GGP_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_IOS_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_MACOS_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_METAL_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_SCREEN_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_VI_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_WAYLAND_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_WIN32_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_XCB_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_XLIB_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -2,7 +2,7 @@
#define VULKAN_XLIB_XRANDR_H_ 1
/*
** Copyright 2015-2022 The Khronos Group Inc.
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+3 -1
View File
@@ -25,12 +25,14 @@
namespace Vulkan
{
Buffer::Buffer(Device *device_, VkBuffer buffer_, const DeviceAllocation &alloc_, const BufferCreateInfo &info_)
Buffer::Buffer(Device *device_, VkBuffer buffer_, const DeviceAllocation &alloc_, const BufferCreateInfo &info_,
VkDeviceAddress bda_)
: Cookie(device_)
, device(device_)
, buffer(buffer_)
, alloc(alloc_)
, info(info_)
, bda(bda_)
{
}
+10 -1
View File
@@ -55,6 +55,7 @@ struct BufferCreateInfo
VkDeviceSize size = 0;
VkBufferUsageFlags usage = 0;
BufferMiscFlags misc = 0;
VkMemoryRequirements allocation_requirements = {};
ExternalHandle external;
};
@@ -99,14 +100,22 @@ public:
ExternalHandle export_handle();
VkDeviceAddress get_device_address() const
{
VK_ASSERT(bda);
return bda;
}
private:
friend class Util::ObjectPool<Buffer>;
Buffer(Device *device, VkBuffer buffer, const DeviceAllocation &alloc, const BufferCreateInfo &info);
Buffer(Device *device, VkBuffer buffer, const DeviceAllocation &alloc, const BufferCreateInfo &info,
VkDeviceAddress bda);
Device *device;
VkBuffer buffer;
DeviceAllocation alloc;
BufferCreateInfo info;
VkDeviceAddress bda;
};
using BufferHandle = Util::IntrusivePtr<Buffer>;
File diff suppressed because it is too large. Load diff
+135 -60
View File
@@ -37,6 +37,7 @@
namespace Vulkan
{
class DebugChannelInterface;
class IndirectLayout;
static inline VkPipelineStageFlags convert_vk_stage2(VkPipelineStageFlags2 stages)
{
@@ -133,50 +134,55 @@ using CommandBufferDirtyFlags = uint32_t;
#define BLEND_OP_BITS 3
#define CULL_MODE_BITS 2
#define FRONT_FACE_BITS 1
#define TOPOLOGY_BITS 4
union PipelineState {
struct
{
// Depth state.
unsigned depth_write : 1;
unsigned depth_test : 1;
unsigned blend_enable : 1;
// Word 0, tightly packed.
uint32_t depth_write : 1;
uint32_t depth_test : 1;
uint32_t blend_enable : 1;
uint32_t cull_mode : CULL_MODE_BITS;
uint32_t front_face : FRONT_FACE_BITS;
uint32_t depth_compare : COMPARE_OP_BITS;
uint32_t depth_bias_enable : 1;
uint32_t stencil_test : 1;
uint32_t stencil_front_fail : STENCIL_OP_BITS;
uint32_t stencil_front_pass : STENCIL_OP_BITS;
uint32_t stencil_front_depth_fail : STENCIL_OP_BITS;
uint32_t stencil_front_compare_op : COMPARE_OP_BITS;
uint32_t stencil_back_fail : STENCIL_OP_BITS;
uint32_t stencil_back_pass : STENCIL_OP_BITS;
uint32_t stencil_back_depth_fail : STENCIL_OP_BITS;
unsigned cull_mode : CULL_MODE_BITS;
unsigned front_face : FRONT_FACE_BITS;
unsigned depth_bias_enable : 1;
// Word 1, tightly packed.
uint32_t stencil_back_compare_op : COMPARE_OP_BITS;
uint32_t alpha_to_coverage : 1;
uint32_t alpha_to_one : 1;
uint32_t sample_shading : 1;
uint32_t src_color_blend : BLEND_FACTOR_BITS;
uint32_t dst_color_blend : BLEND_FACTOR_BITS;
uint32_t color_blend_op : BLEND_OP_BITS;
uint32_t src_alpha_blend : BLEND_FACTOR_BITS;
uint32_t dst_alpha_blend : BLEND_FACTOR_BITS;
uint32_t alpha_blend_op : BLEND_OP_BITS;
unsigned depth_compare : COMPARE_OP_BITS;
unsigned stencil_test : 1;
unsigned stencil_front_fail : STENCIL_OP_BITS;
unsigned stencil_front_pass : STENCIL_OP_BITS;
unsigned stencil_front_depth_fail : STENCIL_OP_BITS;
unsigned stencil_front_compare_op : COMPARE_OP_BITS;
unsigned stencil_back_fail : STENCIL_OP_BITS;
unsigned stencil_back_pass : STENCIL_OP_BITS;
unsigned stencil_back_depth_fail : STENCIL_OP_BITS;
unsigned stencil_back_compare_op : COMPARE_OP_BITS;
unsigned alpha_to_coverage : 1;
unsigned alpha_to_one : 1;
unsigned sample_shading : 1;
unsigned src_color_blend : BLEND_FACTOR_BITS;
unsigned dst_color_blend : BLEND_FACTOR_BITS;
unsigned color_blend_op : BLEND_OP_BITS;
unsigned src_alpha_blend : BLEND_FACTOR_BITS;
unsigned dst_alpha_blend : BLEND_FACTOR_BITS;
unsigned alpha_blend_op : BLEND_OP_BITS;
unsigned primitive_restart : 1;
unsigned topology : 4;
unsigned wireframe : 1;
unsigned subgroup_control_size : 1;
unsigned subgroup_full_group : 1;
unsigned subgroup_minimum_size_log2 : 3;
unsigned subgroup_maximum_size_log2 : 3;
unsigned conservative_raster : 1;
// Word 2, tightly packed.
uint32_t primitive_restart : 1;
uint32_t topology : TOPOLOGY_BITS;
uint32_t wireframe : 1;
uint32_t subgroup_control_size : 1;
uint32_t subgroup_full_group : 1;
uint32_t subgroup_minimum_size_log2 : 3;
uint32_t subgroup_maximum_size_log2 : 3;
uint32_t subgroup_control_size_task : 1;
uint32_t subgroup_full_group_task : 1;
uint32_t subgroup_minimum_size_log2_task : 3;
uint32_t subgroup_maximum_size_log2_task : 3;
uint32_t conservative_raster : 1;
uint32_t padding : 9;
// Word 3
uint32_t write_mask;
} state;
uint32_t words[4];
@@ -251,6 +257,9 @@ struct CommandBufferSavedState
struct DeferredPipelineCompile
{
Program *program;
const PipelineLayout *layout;
std::vector<Program *> program_group;
const RenderPass *compatible_render_pass;
PipelineState static_state;
PotentialState potential_static_state;
@@ -281,6 +290,9 @@ public:
AsyncCompute = QUEUE_INDEX_COMPUTE,
AsyncTransfer = QUEUE_INDEX_TRANSFER,
VideoDecode = QUEUE_INDEX_VIDEO_DECODE,
#ifdef VK_ENABLE_BETA_EXTENSIONS
VideoEncode = QUEUE_INDEX_VIDEO_ENCODE,
#endif
AsyncGraphics = QUEUE_INDEX_COUNT, // Aliases with either Generic or AsyncCompute queue
Count
};
@@ -381,6 +393,16 @@ public:
VkPipelineStageFlags2 src_stage, VkAccessFlags2 src_access,
VkPipelineStageFlags2 dst_stage, VkAccessFlags2 dst_access);
void image_barrier_acquire(const Image &image,
VkImageLayout old_layout, VkImageLayout new_layout,
VkPipelineStageFlags2 src_stage, uint32_t src_queue_family,
VkPipelineStageFlags2 dst_stage, VkAccessFlags2 dst_access);
void image_barrier_release(const Image &image,
VkImageLayout old_layout, VkImageLayout new_layout,
VkPipelineStageFlags2 src_stage, VkAccessFlags2 src_access,
uint32_t dst_queue_family);
void buffer_barriers(uint32_t buffer_barriers, const VkBufferMemoryBarrier2 *buffers);
void image_barriers(uint32_t image_barriers, const VkImageMemoryBarrier2 *images);
@@ -423,11 +445,16 @@ public:
const RenderPassInfo &rp, unsigned thread_index, unsigned subpass);
void set_program(Program *program);
void set_program_group(Program * const *programs, unsigned num_programs, const PipelineLayout *layout);
#ifdef GRANITE_VULKAN_SYSTEM_HANDLES
// Convenience functions for one-off shader binds.
void set_program(const std::string &vertex, const std::string &fragment, const std::vector<std::pair<std::string, int>> &defines = {});
void set_program(const std::string &compute, const std::vector<std::pair<std::string, int>> &defines = {});
void set_program(const std::string &task, const std::string &mesh, const std::string &fragment,
const std::vector<std::pair<std::string, int>> &defines = {});
void set_program(const std::string &vertex, const std::string &fragment,
const std::vector<std::pair<std::string, int>> &defines = {});
void set_program(const std::string &compute,
const std::vector<std::pair<std::string, int>> &defines = {});
#endif
void set_buffer_view(unsigned set, unsigned binding, const BufferView &view);
@@ -483,16 +510,24 @@ public:
uint32_t first_instance = 0);
void draw_indexed(uint32_t index_count, uint32_t instance_count = 1, uint32_t first_index = 0,
int32_t vertex_offset = 0, uint32_t first_instance = 0);
void draw_mesh_tasks(uint32_t tasks_x, uint32_t tasks_y, uint32_t tasks_z);
void dispatch(uint32_t groups_x, uint32_t groups_y, uint32_t groups_z);
void draw_indirect(const Buffer &buffer, uint32_t offset, uint32_t draw_count, uint32_t stride);
void draw_indexed_indirect(const Buffer &buffer, uint32_t offset, uint32_t draw_count, uint32_t stride);
void draw_multi_indirect(const Buffer &buffer, uint32_t offset, uint32_t draw_count, uint32_t stride,
const Buffer &count, uint32_t count_offset);
void draw_indexed_multi_indirect(const Buffer &buffer, uint32_t offset, uint32_t draw_count, uint32_t stride,
const Buffer &count, uint32_t count_offset);
void dispatch_indirect(const Buffer &buffer, uint32_t offset);
void draw_indirect(const Buffer &buffer, VkDeviceSize offset, uint32_t draw_count, uint32_t stride);
void draw_indexed_indirect(const Buffer &buffer, VkDeviceSize offset, uint32_t draw_count, uint32_t stride);
void draw_multi_indirect(const Buffer &buffer, VkDeviceSize offset, uint32_t draw_count, uint32_t stride,
const Buffer &count, VkDeviceSize count_offset);
void draw_indexed_multi_indirect(const Buffer &buffer, VkDeviceSize offset, uint32_t draw_count, uint32_t stride,
const Buffer &count, VkDeviceSize count_offset);
void dispatch_indirect(const Buffer &buffer, VkDeviceSize offset);
void draw_mesh_tasks_indirect(const Buffer &buffer, VkDeviceSize offset, uint32_t draw_count, uint32_t stride);
void draw_mesh_tasks_multi_indirect(const Buffer &buffer, VkDeviceSize offset, uint32_t draw_count, uint32_t stride,
const Buffer &count, VkDeviceSize count_offset);
void execute_indirect_commands(const IndirectLayout *indirect_layout,
uint32_t sequences,
const Buffer &indirect, VkDeviceSize offset,
const Buffer *count, size_t count_offset);
void set_opaque_state();
void set_quad_state();
@@ -667,20 +702,51 @@ public:
set_specialization_constant(index, uint32_t(value));
}
inline void enable_subgroup_size_control(bool subgroup_control_size)
inline void enable_subgroup_size_control(bool subgroup_control_size,
VkShaderStageFlagBits stage = VK_SHADER_STAGE_COMPUTE_BIT)
{
SET_STATIC_STATE(subgroup_control_size);
VK_ASSERT(stage == VK_SHADER_STAGE_TASK_BIT_EXT ||
stage == VK_SHADER_STAGE_MESH_BIT_EXT ||
stage == VK_SHADER_STAGE_COMPUTE_BIT);
if (stage != VK_SHADER_STAGE_TASK_BIT_EXT)
{
SET_STATIC_STATE(subgroup_control_size);
}
else
{
auto subgroup_control_size_task = subgroup_control_size;
SET_STATIC_STATE(subgroup_control_size_task);
}
}
inline void set_subgroup_size_log2(bool subgroup_full_group,
uint8_t subgroup_minimum_size_log2,
uint8_t subgroup_maximum_size_log2)
uint8_t subgroup_maximum_size_log2,
VkShaderStageFlagBits stage = VK_SHADER_STAGE_COMPUTE_BIT)
{
VK_ASSERT(stage == VK_SHADER_STAGE_TASK_BIT_EXT ||
stage == VK_SHADER_STAGE_MESH_BIT_EXT ||
stage == VK_SHADER_STAGE_COMPUTE_BIT);
VK_ASSERT(subgroup_minimum_size_log2 < 8);
VK_ASSERT(subgroup_maximum_size_log2 < 8);
SET_STATIC_STATE(subgroup_full_group);
SET_STATIC_STATE(subgroup_minimum_size_log2);
SET_STATIC_STATE(subgroup_maximum_size_log2);
if (stage != VK_SHADER_STAGE_TASK_BIT_EXT)
{
SET_STATIC_STATE(subgroup_full_group);
SET_STATIC_STATE(subgroup_minimum_size_log2);
SET_STATIC_STATE(subgroup_maximum_size_log2);
}
else
{
auto subgroup_full_group_task = subgroup_full_group;
auto subgroup_minimum_size_log2_task = subgroup_minimum_size_log2;
auto subgroup_maximum_size_log2_task = subgroup_maximum_size_log2;
SET_STATIC_STATE(subgroup_full_group_task);
SET_STATIC_STATE(subgroup_minimum_size_log2_task);
SET_STATIC_STATE(subgroup_maximum_size_log2_task);
}
}
inline void set_conservative_rasterization(bool conservative_raster)
@@ -731,8 +797,6 @@ public:
}
QueryPoolHandle write_timestamp(VkPipelineStageFlags2 stage);
void add_checkpoint(const char *tag);
void set_backtrace_checkpoint();
// Used when recording command buffers in a thread, and submitting them in a different thread.
// Need to make sure that no further commands on the VkCommandBuffer happen.
@@ -751,12 +815,16 @@ public:
{
Sync,
FailOnCompileRequired,
AsyncThread
AsyncThread,
IndirectBindable
};
static Pipeline build_graphics_pipeline(Device *device, const DeferredPipelineCompile &compile, CompileMode mode);
static Pipeline build_compute_pipeline(Device *device, const DeferredPipelineCompile &compile, CompileMode mode);
bool flush_pipeline_state_without_blocking();
VkPipeline get_current_compute_pipeline();
VkPipeline get_current_graphics_pipeline();
private:
friend class Util::ObjectPool<CommandBuffer>;
CommandBuffer(Device *device, VkCommandBuffer cmd, VkPipelineCache cache, Type type);
@@ -778,7 +846,6 @@ private:
Pipeline current_pipeline = {};
VkPipelineLayout current_pipeline_layout = VK_NULL_HANDLE;
PipelineLayout *current_layout = nullptr;
VkSubpassContents current_contents = VK_SUBPASS_CONTENTS_INLINE;
unsigned thread_index = 0;
@@ -794,6 +861,7 @@ private:
bool is_compute = true;
bool is_secondary = false;
bool is_ended = false;
bool framebuffer_is_multiview = false;
void set_dirty(CommandBufferDirtyFlags flags)
{
@@ -814,8 +882,8 @@ private:
"Hashable pipeline state is not large enough!");
#endif
bool flush_render_state(bool synchronous);
bool flush_compute_state(bool synchronous);
VkPipeline flush_render_state(bool synchronous);
VkPipeline flush_compute_state(bool synchronous);
void clear_render_state();
bool flush_graphics_pipeline(bool synchronous);
@@ -848,9 +916,16 @@ private:
void bind_pipeline(VkPipelineBindPoint bind_point, VkPipeline pipeline, uint32_t active_dynamic_state);
static void update_hash_graphics_pipeline(DeferredPipelineCompile &compile, uint32_t &active_vbos);
static void update_hash_graphics_pipeline(DeferredPipelineCompile &compile, CompileMode mode, uint32_t *active_vbos);
static void update_hash_compute_pipeline(DeferredPipelineCompile &compile);
void set_surface_transform_specialization_constants();
void set_program_layout(const PipelineLayout *layout);
static bool setup_subgroup_size_control(Device &device, VkPipelineShaderStageCreateInfo &stage_info,
VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT &required_info,
VkShaderStageFlagBits stage,
bool full_group, unsigned min_size_log2, unsigned max_size_log2);
};
#ifdef GRANITE_VULKAN_SYSTEM_HANDLES
+396 -46
View File
@@ -40,8 +40,53 @@
//#undef VULKAN_DEBUG
#ifdef GRANITE_VULKAN_PROFILES
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wshadow"
#endif
// We need to make sure profiles implementation sees volk symbols, not loader.
#include "vulkan/vulkan_profiles.cpp"
// Ideally there would be a vpQueryProfile which returns a const pointer to static VpProfileProperties,
// so we wouldn't have to do this.
struct ProfileHolder
{
explicit ProfileHolder(const std::string &name)
{
if (name.empty())
return;
uint32_t count;
vpGetProfiles(&count, nullptr);
props.resize(count);
vpGetProfiles(&count, props.data());
for (auto &prop : props)
if (name == prop.profileName)
profile = &prop;
}
Util::SmallVector<VpProfileProperties> props;
const VpProfileProperties *profile = nullptr;
};
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
#endif
#define NV_DRIVER_VERSION_MAJOR(v) (uint32_t(v) >> 22)
namespace Vulkan
{
static constexpr ContextCreationFlags video_context_flags =
#ifdef VK_ENABLE_BETA_EXTENSIONS
CONTEXT_CREATION_ENABLE_VIDEO_DECODE_BIT | CONTEXT_CREATION_ENABLE_VIDEO_ENCODE_BIT;
#else
CONTEXT_CREATION_ENABLE_VIDEO_DECODE_BIT;
#endif
void Context::set_instance_factory(InstanceFactory *factory)
{
instance_factory = factory;
@@ -262,6 +307,10 @@ void Context::destroy()
vkDestroyInstance(instance, nullptr);
}
Context::Context()
{
}
Context::~Context()
{
destroy();
@@ -349,12 +398,138 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL vulkan_messenger_cb(
}
#endif
void Context::set_required_profile(const char *profile, bool strict)
{
if (profile)
required_profile = profile;
else
required_profile.clear();
required_profile_strict = strict;
}
bool Context::init_profile()
{
#ifdef GRANITE_VULKAN_PROFILES
if (required_profile.empty())
{
if (const char *env = getenv("GRANITE_VULKAN_PROFILE"))
{
required_profile = env;
LOGI("Overriding profile: %s\n", env);
}
if (const char *strict_env = getenv("GRANITE_VULKAN_PROFILE_STRICT"))
{
required_profile_strict = strtoul(strict_env, nullptr, 0) != 0;
LOGI("Overriding profile strictness: %u\n", required_profile_strict);
}
}
if (required_profile.empty())
return true;
ProfileHolder profile{required_profile};
if (!profile.profile)
{
LOGW("No profile matches %s.\n", required_profile.c_str());
return false;
}
VkBool32 supported = VK_FALSE;
if (vpGetInstanceProfileSupport(nullptr, profile.profile, &supported) != VK_SUCCESS || !supported)
{
LOGE("Profile %s is not supported.\n", required_profile.c_str());
return false;
}
#endif
return true;
}
VkResult Context::create_instance_from_profile(const VkInstanceCreateInfo &info, VkInstance *pInstance)
{
#ifdef GRANITE_VULKAN_PROFILES
ProfileHolder holder{required_profile};
if (!holder.profile)
return VK_ERROR_INITIALIZATION_FAILED;
if (instance_factory)
{
// Can override vkGetInstanceProcAddr (macro define) and override vkCreateInstance
// to a TLS magic trampoline if we really have to.
LOGE("Instance factory currently not supported with profiles.\n");
return VK_ERROR_INITIALIZATION_FAILED;
}
VpInstanceCreateInfo vp_info = {};
vp_info.pCreateInfo = &info;
vp_info.pProfile = holder.profile;
// Any extra extensions we add for instances are essential, like WSI stuff.
vp_info.flags = VP_INSTANCE_CREATE_MERGE_EXTENSIONS_BIT;
VkResult result;
if ((result = vpCreateInstance(&vp_info, nullptr, pInstance)) != VK_SUCCESS)
LOGE("Failed to create instance from profile.\n");
return result;
#else
(void)info;
(void)pInstance;
return VK_ERROR_INITIALIZATION_FAILED;
#endif
}
VkResult Context::create_device_from_profile(const VkDeviceCreateInfo &info, VkDevice *pDevice)
{
#ifdef GRANITE_VULKAN_PROFILES
ProfileHolder holder{required_profile};
if (!holder.profile)
return VK_ERROR_INITIALIZATION_FAILED;
if (device_factory)
{
// Need TLS hackery like instance.
LOGE("Device factory currently not supported with profiles.\n");
return VK_ERROR_INITIALIZATION_FAILED;
}
auto tmp_info = info;
VpDeviceCreateInfo vp_info = {};
vp_info.pProfile = holder.profile;
vp_info.pCreateInfo = &tmp_info;
vp_info.flags |= VP_DEVICE_CREATE_DISABLE_ROBUST_ACCESS;
if (required_profile_strict)
{
tmp_info.enabledExtensionCount = 0;
tmp_info.ppEnabledExtensionNames = nullptr;
tmp_info.pNext = nullptr;
tmp_info.pEnabledFeatures = nullptr;
}
else
{
vp_info.flags = VP_DEVICE_CREATE_MERGE_EXTENSIONS_BIT | VP_DEVICE_CREATE_OVERRIDE_FEATURES_BIT;
}
VkResult result;
if ((result = vpCreateDevice(gpu, &vp_info, nullptr, pDevice)) != VK_SUCCESS)
LOGE("Failed to create device from profile.\n");
return result;
#else
(void)info;
(void)pDevice;
return VK_ERROR_INITIALIZATION_FAILED;
#endif
}
bool Context::create_instance(const char * const *instance_ext, uint32_t instance_ext_count, ContextCreationFlags flags)
{
uint32_t target_instance_version = user_application_info.get_application_info().apiVersion;
// Target an instance version of at least 1.3 for FFmpeg decode.
if (flags & CONTEXT_CREATION_ENABLE_VIDEO_DECODE_BIT)
if ((flags & video_context_flags) != 0)
if (target_instance_version < VK_API_VERSION_1_3)
target_instance_version = VK_API_VERSION_1_3;
@@ -489,6 +664,18 @@ bool Context::create_instance(const char * const *instance_ext, uint32_t instanc
for (auto *ext_name : instance_exts)
LOGI("Enabling instance extension: %s.\n", ext_name);
#ifdef GRANITE_VULKAN_PROFILES
if (!init_profile())
{
LOGE("Profile is not supported.\n");
return false;
}
if (instance == VK_NULL_HANDLE && !required_profile.empty())
if (create_instance_from_profile(info, &instance) != VK_SUCCESS)
return false;
#endif
// instance != VK_NULL_HANDLE here is deprecated and somewhat broken.
// For libretro Vulkan context negotiation v1.
if (instance == VK_NULL_HANDLE)
@@ -559,15 +746,31 @@ QueueInfo::QueueInfo()
index = VK_QUEUE_FAMILY_IGNORED;
}
bool Context::physical_device_supports_surface(VkPhysicalDevice gpu, VkSurfaceKHR surface)
bool Context::physical_device_supports_surface_and_profile(VkPhysicalDevice candidate_gpu, VkSurfaceKHR surface) const
{
#ifdef GRANITE_VULKAN_PROFILES
if (!required_profile.empty())
{
ProfileHolder holder{required_profile};
if (!holder.profile)
return false;
VkBool32 supported = VK_FALSE;
if (vpGetPhysicalDeviceProfileSupport(instance, candidate_gpu, holder.profile, &supported) != VK_SUCCESS ||
!supported)
{
return false;
}
}
#endif
if (surface == VK_NULL_HANDLE)
return true;
uint32_t family_count = 0;
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &family_count, nullptr);
vkGetPhysicalDeviceQueueFamilyProperties(candidate_gpu, &family_count, nullptr);
Util::SmallVector<VkQueueFamilyProperties> props(family_count);
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &family_count, props.data());
vkGetPhysicalDeviceQueueFamilyProperties(candidate_gpu, &family_count, props.data());
for (uint32_t i = 0; i < family_count; i++)
{
@@ -575,7 +778,7 @@ bool Context::physical_device_supports_surface(VkPhysicalDevice gpu, VkSurfaceKH
if ((props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
{
VkBool32 supported = VK_FALSE;
if (vkGetPhysicalDeviceSurfaceSupportKHR(gpu, i, surface, &supported) == VK_SUCCESS && supported)
if (vkGetPhysicalDeviceSurfaceSupportKHR(candidate_gpu, i, surface, &supported) == VK_SUCCESS && supported)
return true;
}
}
@@ -627,7 +830,7 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
if (gpu != VK_NULL_HANDLE)
{
if (!physical_device_supports_surface(gpu, surface))
if (!physical_device_supports_surface_and_profile(gpu, surface))
{
LOGE("Selected physical device which does not support surface.\n");
gpu = VK_NULL_HANDLE;
@@ -641,7 +844,7 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
for (size_t i = gpus.size(); i; i--)
{
unsigned score = device_score(gpus[i - 1]);
if (score >= max_score && physical_device_supports_surface(gpus[i - 1], surface))
if (score >= max_score && physical_device_supports_surface_and_profile(gpus[i - 1], surface))
{
max_score = score;
gpu = gpus[i - 1];
@@ -655,17 +858,34 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
return false;
}
}
else if (!physical_device_supports_surface(gpu, surface))
else if (!physical_device_supports_surface_and_profile(gpu, surface))
{
LOGE("Selected physical device does not support surface.\n");
return false;
}
uint32_t ext_count = 0;
vkEnumerateDeviceExtensionProperties(gpu, nullptr, &ext_count, nullptr);
std::vector<VkExtensionProperties> queried_extensions(ext_count);
if (ext_count)
vkEnumerateDeviceExtensionProperties(gpu, nullptr, &ext_count, queried_extensions.data());
std::vector<VkExtensionProperties> queried_extensions;
#ifdef GRANITE_VULKAN_PROFILES
// Only allow extensions that profile declares.
ProfileHolder profile{required_profile};
if (profile.profile && required_profile_strict)
{
uint32_t ext_count = 0;
vpGetProfileDeviceExtensionProperties(profile.profile, &ext_count, nullptr);
queried_extensions.resize(ext_count);
if (ext_count)
vpGetProfileDeviceExtensionProperties(profile.profile, &ext_count, queried_extensions.data());
}
else
#endif
{
uint32_t ext_count = 0;
vkEnumerateDeviceExtensionProperties(gpu, nullptr, &ext_count, nullptr);
queried_extensions.resize(ext_count);
if (ext_count)
vkEnumerateDeviceExtensionProperties(gpu, nullptr, &ext_count, queried_extensions.data());
}
const auto has_extension = [&](const char *name) -> bool {
auto itr = find_if(begin(queried_extensions), end(queried_extensions), [name](const VkExtensionProperties &e) -> bool {
@@ -691,9 +911,7 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
LOGI("Using Vulkan GPU: %s\n", gpu_props.deviceName);
// FFmpeg integration requires Vulkan 1.3 core for physical device.
const uint32_t minimum_api_version =
(flags & CONTEXT_CREATION_ENABLE_VIDEO_DECODE_BIT) ?
VK_API_VERSION_1_3 : VK_API_VERSION_1_1;
const uint32_t minimum_api_version = (flags & video_context_flags) ? VK_API_VERSION_1_3 : VK_API_VERSION_1_1;
if (gpu_props.apiVersion < minimum_api_version)
{
@@ -709,11 +927,8 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
Util::SmallVector<VkQueueFamilyProperties2> queue_props(queue_family_count);
Util::SmallVector<VkQueueFamilyVideoPropertiesKHR> video_queue_props2(queue_family_count);
if ((flags & CONTEXT_CREATION_ENABLE_VIDEO_DECODE_BIT) != 0 &&
has_extension(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME))
{
if ((flags & video_context_flags) != 0 && has_extension(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME))
ext.supports_video_queue = true;
}
for (uint32_t i = 0; i < queue_family_count; i++)
{
@@ -810,12 +1025,29 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
if (ext.supports_video_queue)
{
if (!find_vacant_queue(queue_info.family_indices[QUEUE_INDEX_VIDEO_DECODE], queue_indices[QUEUE_INDEX_VIDEO_DECODE],
VK_QUEUE_VIDEO_DECODE_BIT_KHR, 0, 0.5f))
if ((flags & CONTEXT_CREATION_ENABLE_VIDEO_DECODE_BIT) != 0)
{
queue_info.family_indices[QUEUE_INDEX_VIDEO_DECODE] = VK_QUEUE_FAMILY_IGNORED;
queue_indices[QUEUE_INDEX_VIDEO_DECODE] = UINT32_MAX;
if (!find_vacant_queue(queue_info.family_indices[QUEUE_INDEX_VIDEO_DECODE],
queue_indices[QUEUE_INDEX_VIDEO_DECODE],
VK_QUEUE_VIDEO_DECODE_BIT_KHR, 0, 0.5f))
{
queue_info.family_indices[QUEUE_INDEX_VIDEO_DECODE] = VK_QUEUE_FAMILY_IGNORED;
queue_indices[QUEUE_INDEX_VIDEO_DECODE] = UINT32_MAX;
}
}
#ifdef VK_ENABLE_BETA_EXTENSIONS
if ((flags & CONTEXT_CREATION_ENABLE_VIDEO_ENCODE_BIT) != 0)
{
if (!find_vacant_queue(queue_info.family_indices[QUEUE_INDEX_VIDEO_ENCODE],
queue_indices[QUEUE_INDEX_VIDEO_ENCODE],
VK_QUEUE_VIDEO_ENCODE_BIT_KHR, 0, 0.5f))
{
queue_info.family_indices[QUEUE_INDEX_VIDEO_ENCODE] = VK_QUEUE_FAMILY_IGNORED;
queue_indices[QUEUE_INDEX_VIDEO_ENCODE] = UINT32_MAX;
}
}
#endif
}
VkDeviceCreateInfo device_info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
@@ -850,10 +1082,6 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
{
flags |= CONTEXT_CREATION_ENABLE_ADVANCED_WSI_BIT;
}
else if (strcmp(required_device_extensions[i], VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME) == 0)
{
flags &= ~CONTEXT_CREATION_DISABLE_BINDLESS_BIT;
}
}
#if defined(ANDROID) && defined(HAVE_SWAPPY)
@@ -899,14 +1127,6 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
}
#endif
#ifdef VULKAN_DEBUG
if (has_extension(VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME))
{
ext.supports_nv_device_diagnostic_checkpoints = true;
enabled_extensions.push_back(VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME);
}
#endif
if (
#ifdef _WIN32
has_extension(VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME) &&
@@ -1009,6 +1229,41 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
}
}
}
#ifdef VK_ENABLE_BETA_EXTENSIONS
if ((flags & CONTEXT_CREATION_ENABLE_VIDEO_ENCODE_BIT) != 0 &&
has_extension(VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME))
{
enabled_extensions.push_back(VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME);
ext.supports_video_encode_queue = true;
if ((flags & CONTEXT_CREATION_ENABLE_VIDEO_H264_BIT) != 0 &&
has_extension(VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME))
{
enabled_extensions.push_back(VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME);
if (queue_info.family_indices[QUEUE_INDEX_VIDEO_ENCODE] != VK_QUEUE_FAMILY_IGNORED)
{
ext.supports_video_encode_h264 =
(video_queue_props2[queue_info.family_indices[QUEUE_INDEX_VIDEO_ENCODE]].videoCodecOperations &
VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT) != 0;
}
}
if ((flags & CONTEXT_CREATION_ENABLE_VIDEO_H265_BIT) != 0 &&
has_extension(VK_EXT_VIDEO_ENCODE_H265_EXTENSION_NAME))
{
enabled_extensions.push_back(VK_EXT_VIDEO_ENCODE_H265_EXTENSION_NAME);
if (queue_info.family_indices[QUEUE_INDEX_VIDEO_ENCODE] != VK_QUEUE_FAMILY_IGNORED)
{
ext.supports_video_encode_h265 =
(video_queue_props2[queue_info.family_indices[QUEUE_INDEX_VIDEO_ENCODE]].videoCodecOperations &
VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT) != 0;
}
}
}
#endif
}
pdf2 = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 };
@@ -1037,8 +1292,13 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
ext.astc_decode_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT };
ext.astc_hdr_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT };
ext.pipeline_creation_cache_control_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT };
ext.pageable_device_local_memory_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT };
ext.mesh_shader_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT };
ext.shader_subgroup_extended_types_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES };
ext.compute_shader_derivative_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV };
ext.device_generated_commands_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV };
ext.buffer_device_address_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR };
void **ppNext = &pdf2.pNext;
@@ -1119,7 +1379,7 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
ppNext = &ext.timeline_semaphore_features.pNext;
}
if ((flags & CONTEXT_CREATION_DISABLE_BINDLESS_BIT) == 0 && has_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME))
if (has_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME))
{
enabled_extensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
*ppNext = &ext.descriptor_indexing_features;
@@ -1177,16 +1437,57 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
ppNext = &ext.pipeline_creation_cache_control_features.pNext;
}
if (has_extension(VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME))
{
enabled_extensions.push_back(VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME);
*ppNext = &ext.pageable_device_local_memory_features;
ppNext = &ext.pageable_device_local_memory_features.pNext;
}
if (has_extension(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME))
{
ext.supports_format_feature_flags2 = true;
enabled_extensions.push_back(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME);
}
if (has_extension(VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME))
{
enabled_extensions.push_back(VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME);
*ppNext = &ext.device_generated_commands_features;
ppNext = &ext.device_generated_commands_features.pNext;
}
if (has_extension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME))
{
enabled_extensions.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
*ppNext = &ext.buffer_device_address_features;
ppNext = &ext.buffer_device_address_features.pNext;
}
if (has_extension(VK_EXT_MESH_SHADER_EXTENSION_NAME))
{
enabled_extensions.push_back(VK_EXT_MESH_SHADER_EXTENSION_NAME);
*ppNext = &ext.mesh_shader_features;
ppNext = &ext.mesh_shader_features.pNext;
}
if (has_extension(VK_KHR_SPIRV_1_4_EXTENSION_NAME))
{
enabled_extensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
ext.supports_spirv_1_4 = true;
}
if (has_extension(VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME))
{
enabled_extensions.push_back(VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME);
*ppNext = &ext.shader_subgroup_extended_types_features;
ppNext = &ext.shader_subgroup_extended_types_features.pNext;
}
if ((flags & CONTEXT_CREATION_ENABLE_ADVANCED_WSI_BIT) != 0 && requires_swapchain)
{
bool broken_present_wait = ext.driver_properties.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
VK_VERSION_MAJOR(gpu_props.driverVersion) == 525;
NV_DRIVER_VERSION_MAJOR(gpu_props.driverVersion) < 535;
if (broken_present_wait)
{
@@ -1223,7 +1524,20 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
}
}
vkGetPhysicalDeviceFeatures2(gpu, &pdf2);
#ifdef GRANITE_VULKAN_PROFILES
// Override any features in the profile in strict mode.
if (profile.profile && required_profile_strict)
{
vpGetProfileFeatures(profile.profile, &pdf2);
}
else
#endif
{
vkGetPhysicalDeviceFeatures2(gpu, &pdf2);
}
ext.buffer_device_address_features.bufferDeviceAddressCaptureReplay = VK_FALSE;
ext.buffer_device_address_features.bufferDeviceAddressMultiDevice = VK_FALSE;
// Enable device features we might care about.
{
@@ -1281,7 +1595,7 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
device_info.pNext = &pdf2;
if (ext.supports_external && has_extension(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME))
if (has_extension(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME))
{
ext.supports_external_memory_host = true;
enabled_extensions.push_back(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME);
@@ -1298,6 +1612,8 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
ext.conservative_rasterization_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT };
ext.float_control_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR };
ext.id_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES };
ext.device_generated_commands_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV };
ext.mesh_shader_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_EXT };
ppNext = &props.pNext;
@@ -1324,6 +1640,12 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
ppNext = &ext.descriptor_indexing_properties.pNext;
}
if (has_extension(VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME))
{
*ppNext = &ext.device_generated_commands_properties;
ppNext = &ext.device_generated_commands_properties.pNext;
}
if (ext.supports_conservative_rasterization)
{
*ppNext = &ext.conservative_rasterization_properties;
@@ -1342,22 +1664,44 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
ppNext = &ext.id_properties.pNext;
}
if (has_extension(VK_EXT_MESH_SHADER_EXTENSION_NAME))
{
*ppNext = &ext.mesh_shader_properties;
ppNext = &ext.mesh_shader_properties.pNext;
}
vkGetPhysicalDeviceProperties2(gpu, &props);
#ifdef GRANITE_VULKAN_PROFILES
// Override any properties in the profile in strict mode.
if (profile.profile && required_profile_strict)
vpGetProfileProperties(profile.profile, &props);
#endif
device_info.enabledExtensionCount = enabled_extensions.size();
device_info.ppEnabledExtensionNames = enabled_extensions.empty() ? nullptr : enabled_extensions.data();
for (auto *enabled_extension : enabled_extensions)
LOGI("Enabling device extension: %s.\n", enabled_extension);
if (device_factory)
#ifdef GRANITE_VULKAN_PROFILES
if (!required_profile.empty())
{
device = device_factory->create_device(gpu, &device_info);
if (device == VK_NULL_HANDLE)
if (create_device_from_profile(device_info, &device) != VK_SUCCESS)
return false;
}
else
#endif
{
if (device_factory)
{
device = device_factory->create_device(gpu, &device_info);
if (device == VK_NULL_HANDLE)
return false;
}
else if (vkCreateDevice(gpu, &device_info, nullptr, &device) != VK_SUCCESS)
return false;
}
else if (vkCreateDevice(gpu, &device_info, nullptr, &device) != VK_SUCCESS)
return false;
enabled_device_extensions = std::move(enabled_extensions);
ext.device_extensions = enabled_device_extensions.data();
@@ -1394,7 +1738,13 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface,
}
#ifdef VULKAN_DEBUG
static const char *family_names[QUEUE_INDEX_COUNT] = { "Graphics", "Compute", "Transfer", "Video decode" };
static const char *family_names[QUEUE_INDEX_COUNT] = { "Graphics", "Compute", "Transfer", "Video decode",
#ifdef VK_ENABLE_BETA_EXTENSIONS
"Video encode",
#endif
};
for (int i = 0; i < QUEUE_INDEX_COUNT; i++)
if (queue_info.family_indices[i] != VK_QUEUE_FAMILY_IGNORED)
LOGI("%s queue: family %u, index %u.\n", family_names[i], queue_info.family_indices[i], queue_indices[i]);
+35 -6
View File
@@ -50,7 +50,6 @@ struct DeviceFeatures
{
bool supports_debug_utils = false;
bool supports_mirror_clamp_to_edge = false;
bool supports_nv_device_diagnostic_checkpoints = false;
bool supports_external_memory_host = false;
bool supports_surface_capabilities2 = false;
bool supports_full_screen_exclusive = false;
@@ -67,6 +66,11 @@ struct DeviceFeatures
bool supports_video_decode_queue = false;
bool supports_video_decode_h264 = false;
bool supports_video_decode_h265 = false;
#ifdef VK_ENABLE_BETA_EXTENSIONS
bool supports_video_encode_queue = false;
bool supports_video_encode_h264 = false;
bool supports_video_encode_h265 = false;
#endif
bool supports_pipeline_creation_cache_control = false;
bool supports_format_feature_flags2 = false;
bool supports_external = false;
@@ -76,6 +80,7 @@ struct DeviceFeatures
bool supports_hdr_metadata = false;
bool supports_swapchain_colorspace = false;
bool supports_surface_maintenance1 = false;
bool supports_spirv_1_4 = false;
// Vulkan 1.1 core
VkPhysicalDeviceFeatures enabled_features = {};
@@ -96,7 +101,9 @@ struct DeviceFeatures
VkPhysicalDevice16BitStorageFeaturesKHR storage_16bit_features = {};
VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8_features = {};
VkPhysicalDeviceFloatControlsPropertiesKHR float_control_properties = {};
VkPhysicalDeviceBufferDeviceAddressFeaturesKHR buffer_device_address_features = {};
VkPhysicalDeviceIDProperties id_properties = {};
VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR shader_subgroup_extended_types_features = {};
// EXT
VkPhysicalDeviceExternalMemoryHostPropertiesEXT host_memory_properties = {};
@@ -114,9 +121,14 @@ struct DeviceFeatures
VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT astc_hdr_features = {};
VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT pipeline_creation_cache_control_features = {};
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_features = {};
VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT pageable_device_local_memory_features = {};
VkPhysicalDeviceMeshShaderFeaturesEXT mesh_shader_features = {};
VkPhysicalDeviceMeshShaderPropertiesEXT mesh_shader_properties = {};
// Vendor
VkPhysicalDeviceComputeShaderDerivativesFeaturesNV compute_shader_derivative_features = {};
VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV device_generated_commands_features = {};
VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV device_generated_commands_properties = {};
// References Vulkan::Context.
const VkPhysicalDeviceFeatures2 *pdf2 = nullptr;
@@ -137,9 +149,11 @@ enum VendorID
enum ContextCreationFlagBits
{
CONTEXT_CREATION_DISABLE_BINDLESS_BIT = 1 << 0,
CONTEXT_CREATION_ENABLE_ADVANCED_WSI_BIT = 1 << 1,
CONTEXT_CREATION_ENABLE_VIDEO_DECODE_BIT = 1 << 2,
CONTEXT_CREATION_ENABLE_ADVANCED_WSI_BIT = 1 << 0,
CONTEXT_CREATION_ENABLE_VIDEO_DECODE_BIT = 1 << 1,
#ifdef VK_ENABLE_BETA_EXTENSIONS
CONTEXT_CREATION_ENABLE_VIDEO_ENCODE_BIT = 1 << 2,
#endif
CONTEXT_CREATION_ENABLE_VIDEO_H264_BIT = 1 << 3,
CONTEXT_CREATION_ENABLE_VIDEO_H265_BIT = 1 << 4
};
@@ -195,6 +209,14 @@ public:
void set_instance_factory(InstanceFactory *factory);
void set_device_factory(DeviceFactory *factory);
// Only takes effect if profiles are enabled in build. (GRANITE_VULKAN_PROFILES)
// If profile is non-null, forces a specific profile.
// If not supported, initialization fails.
// If not set, ignore profiles.
// If strict is false, the profile should be seen as a baseline and Granite will augment features on top.
// If true, the profile is a strict limit for device functionality. For validation purposes.
void set_required_profile(const char *profile, bool strict);
// Call before initializing instances. app_info may be freed after returning.
// API_VERSION must be at least 1.1.
// By default, a Vulkan 1.1 instance is created.
@@ -225,7 +247,7 @@ public:
const VkPhysicalDeviceFeatures *required_features,
ContextCreationFlags flags = 0);
Context() = default;
Context();
Context(const Context &) = delete;
void operator=(const Context &) = delete;
static bool init_loader(PFN_vkGetInstanceProcAddr addr);
@@ -357,6 +379,9 @@ private:
std::vector<const char *> enabled_device_extensions;
std::vector<const char *> enabled_instance_extensions;
std::string required_profile;
bool required_profile_strict = false;
#ifdef VULKAN_DEBUG
VkDebugUtilsMessengerEXT debug_messenger = VK_NULL_HANDLE;
bool force_no_validation = false;
@@ -366,13 +391,17 @@ private:
void destroy();
void check_descriptor_indexing_features();
static bool physical_device_supports_surface(VkPhysicalDevice gpu, VkSurfaceKHR surface);
bool physical_device_supports_surface_and_profile(VkPhysicalDevice candidate_gpu, VkSurfaceKHR surface) const;
#ifdef GRANITE_VULKAN_FOSSILIZE
Fossilize::FeatureFilter feature_filter;
bool format_is_supported(VkFormat format, VkFormatFeatureFlags features) override;
bool descriptor_set_layout_is_supported(const VkDescriptorSetLayoutCreateInfo *set_layout) override;
#endif
bool init_profile();
VkResult create_instance_from_profile(const VkInstanceCreateInfo &info, VkInstance *pInstance);
VkResult create_device_from_profile(const VkDeviceCreateInfo &info, VkDevice *pDevice);
};
using ContextHandle = Util::IntrusivePtr<Context>;
+258 -132
View File
@@ -61,18 +61,29 @@ using namespace Util;
namespace Vulkan
{
static const char *queue_name_table[] = {
"Graphics",
"Compute",
"Transfer",
"Video decode"
};
#ifdef VK_ENABLE_BETA_EXTENSIONS
static constexpr VkImageUsageFlags image_usage_video_flags =
VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
#else
static constexpr VkImageUsageFlags image_usage_video_flags =
VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
#endif
static const QueueIndices queue_flush_order[] = {
QUEUE_INDEX_TRANSFER,
QUEUE_INDEX_VIDEO_DECODE,
#ifdef VK_ENABLE_BETA_EXTENSIONS
QUEUE_INDEX_VIDEO_ENCODE,
#endif
QUEUE_INDEX_GRAPHICS,
QUEUE_INDEX_COMPUTE
QUEUE_INDEX_COMPUTE,
};
Device::Device()
@@ -232,7 +243,6 @@ void Device::add_wait_semaphore(CommandBuffer::Type type, Semaphore semaphore, V
void Device::add_wait_semaphore_nolock(QueueIndices physical_type, Semaphore semaphore,
VkPipelineStageFlags2 stages, bool flush)
{
VK_ASSERT(stages != 0);
if (flush)
flush_frame(physical_type);
auto &data = queue_data[physical_type];
@@ -427,6 +437,38 @@ Program *Device::request_program(Shader *vertex, Shader *fragment, const Immutab
return ret;
}
Program *Device::request_program(Shader *task, Shader *mesh, Shader *fragment, const ImmutableSamplerBank *sampler_bank)
{
if (!mesh || !fragment)
return nullptr;
if (!get_device_features().mesh_shader_features.meshShader)
{
LOGE("meshShader not supported.\n");
return nullptr;
}
if (task && !get_device_features().mesh_shader_features.taskShader)
{
LOGE("taskShader not supported.\n");
return nullptr;
}
Util::Hasher hasher;
hasher.u64(task ? task->get_hash() : 0);
hasher.u64(mesh->get_hash());
hasher.u64(fragment->get_hash());
ImmutableSamplerBank::hash(hasher, sampler_bank);
auto hash = hasher.get();
LOCK_CACHE();
auto *ret = programs.find(hash);
if (!ret)
ret = programs.emplace_yield(hash, this, task, mesh, fragment, sampler_bank);
return ret;
}
Program *Device::request_program(const uint32_t *vertex_data, size_t vertex_size,
const uint32_t *fragment_data, size_t fragment_size,
const ResourceLayout *vertex_layout,
@@ -440,8 +482,26 @@ Program *Device::request_program(const uint32_t *vertex_data, size_t vertex_size
return request_program(vertex, fragment);
}
PipelineLayout *Device::request_pipeline_layout(const CombinedResourceLayout &layout,
const ImmutableSamplerBank *sampler_bank)
Program *Device::request_program(const uint32_t *task_data, size_t task_size,
const uint32_t *mesh_data, size_t mesh_size,
const uint32_t *fragment_data, size_t fragment_size,
const ResourceLayout *task_layout,
const ResourceLayout *mesh_layout,
const ResourceLayout *fragment_layout)
{
if (!mesh_size || !fragment_size)
return nullptr;
Shader *task = nullptr;
if (task_size)
task = request_shader(task_data, task_size, task_layout);
auto *mesh = request_shader(mesh_data, mesh_size, mesh_layout);
auto *fragment = request_shader(fragment_data, fragment_size, fragment_layout);
return request_program(task, mesh, fragment);
}
const PipelineLayout *Device::request_pipeline_layout(const CombinedResourceLayout &layout,
const ImmutableSamplerBank *sampler_bank)
{
Hasher h;
h.data(reinterpret_cast<const uint32_t *>(layout.sets), sizeof(layout.sets));
@@ -485,16 +545,44 @@ DescriptorSetAllocator *Device::request_descriptor_set_allocator(const Descripto
return ret;
}
void Device::bake_program(Program &program, const ImmutableSamplerBank *sampler_bank)
const IndirectLayout *Device::request_indirect_layout(
const Vulkan::IndirectLayoutToken *tokens, uint32_t num_tokens, uint32_t stride)
{
CombinedResourceLayout layout;
if (program.get_shader(ShaderStage::Vertex))
layout.attribute_mask = program.get_shader(ShaderStage::Vertex)->get_layout().input_mask;
if (program.get_shader(ShaderStage::Fragment))
layout.render_target_mask = program.get_shader(ShaderStage::Fragment)->get_layout().output_mask;
Hasher h;
for (uint32_t i = 0; i < num_tokens; i++)
h.u32(Util::ecast(tokens[i].type));
ImmutableSamplerBank ext_immutable_samplers = {};
layout.descriptor_set_mask = 0;
for (uint32_t i = 0; i < num_tokens; i++)
{
h.u32(tokens[i].offset);
if (tokens[i].type == IndirectLayoutToken::Type::PushConstant)
{
h.u64(tokens[i].data.push.layout->get_hash());
h.u32(tokens[i].data.push.offset);
h.u32(tokens[i].data.push.range);
}
else if (tokens[i].type == IndirectLayoutToken::Type::VBO)
{
h.u32(tokens[i].data.vbo.binding);
}
}
h.u32(stride);
auto hash = h.get();
LOCK_CACHE();
auto *ret = indirect_layouts.find(hash);
if (!ret)
ret = indirect_layouts.emplace_yield(hash, this, tokens, num_tokens, stride);
return ret;
}
void Device::merge_combined_resource_layout(CombinedResourceLayout &layout, const Program &program)
{
if (program.get_shader(ShaderStage::Vertex))
layout.attribute_mask |= program.get_shader(ShaderStage::Vertex)->get_layout().input_mask;
if (program.get_shader(ShaderStage::Fragment))
layout.render_target_mask |= program.get_shader(ShaderStage::Fragment)->get_layout().output_mask;
for (unsigned i = 0; i < static_cast<unsigned>(ShaderStage::Count); i++)
{
@@ -559,6 +647,58 @@ void Device::bake_program(Program &program, const ImmutableSamplerBank *sampler_
layout.bindless_descriptor_set_mask |= shader_layout.bindless_set_mask;
}
for (unsigned set = 0; set < VULKAN_NUM_DESCRIPTOR_SETS; set++)
{
if (layout.stages_for_sets[set] == 0)
continue;
layout.descriptor_set_mask |= 1u << set;
for (unsigned binding = 0; binding < VULKAN_NUM_BINDINGS; binding++)
{
auto &array_size = layout.sets[set].array_size[binding];
if (array_size == DescriptorSetLayout::UNSIZED_ARRAY)
{
for (unsigned i = 1; i < VULKAN_NUM_BINDINGS; i++)
{
if (layout.stages_for_bindings[set][i] != 0)
LOGE("Using bindless for set = %u, but binding = %u has a descriptor attached to it.\n", set, i);
}
// Allows us to have one unified descriptor set layout for bindless.
layout.stages_for_bindings[set][binding] = VK_SHADER_STAGE_ALL;
}
else if (array_size == 0)
{
array_size = 1;
}
else
{
for (unsigned i = 1; i < array_size; i++)
{
if (layout.stages_for_bindings[set][binding + i] != 0)
{
LOGE("Detected binding aliasing for (%u, %u). Binding array with %u elements starting at (%u, %u) overlaps.\n",
set, binding + i, array_size, set, binding);
}
}
}
}
}
Hasher h;
h.u32(layout.push_constant_range.stageFlags);
h.u32(layout.push_constant_range.size);
layout.push_constant_layout_hash = h.get();
}
void Device::bake_program(Program &program, const ImmutableSamplerBank *sampler_bank)
{
CombinedResourceLayout layout;
ImmutableSamplerBank ext_immutable_samplers = {};
merge_combined_resource_layout(layout, program);
if (sampler_bank)
{
for (unsigned set = 0; set < VULKAN_NUM_DESCRIPTOR_SETS; set++)
@@ -574,49 +714,6 @@ void Device::bake_program(Program &program, const ImmutableSamplerBank *sampler_
}
}
for (unsigned set = 0; set < VULKAN_NUM_DESCRIPTOR_SETS; set++)
{
if (layout.stages_for_sets[set] != 0)
{
layout.descriptor_set_mask |= 1u << set;
for (unsigned binding = 0; binding < VULKAN_NUM_BINDINGS; binding++)
{
auto &array_size = layout.sets[set].array_size[binding];
if (array_size == DescriptorSetLayout::UNSIZED_ARRAY)
{
for (unsigned i = 1; i < VULKAN_NUM_BINDINGS; i++)
{
if (layout.stages_for_bindings[set][i] != 0)
LOGE("Using bindless for set = %u, but binding = %u has a descriptor attached to it.\n", set, i);
}
// Allows us to have one unified descriptor set layout for bindless.
layout.stages_for_bindings[set][binding] = VK_SHADER_STAGE_ALL;
}
else if (array_size == 0)
{
array_size = 1;
}
else
{
for (unsigned i = 1; i < array_size; i++)
{
if (layout.stages_for_bindings[set][binding + i] != 0)
{
LOGE("Detected binding aliasing for (%u, %u). Binding array with %u elements starting at (%u, %u) overlaps.\n",
set, binding + i, array_size, set, binding);
}
}
}
}
}
}
Hasher h;
h.u32(layout.push_constant_range.stageFlags);
h.u32(layout.push_constant_range.size);
layout.push_constant_layout_hash = h.get();
program.set_pipeline_layout(request_pipeline_layout(layout, &ext_immutable_samplers));
}
@@ -1303,12 +1400,10 @@ void Device::submit_empty_inner(QueueIndices physical_type, InternalFence *fence
auto start_ts = write_calibrated_timestamp_nolock();
auto result = submit_batches(composer, queue, cleared_fence);
auto end_ts = write_calibrated_timestamp_nolock();
register_time_interval_nolock("CPU", std::move(start_ts), std::move(end_ts), "submit", "");
register_time_interval_nolock("CPU", std::move(start_ts), std::move(end_ts), "submit");
if (result != VK_SUCCESS)
LOGE("vkQueueSubmit2KHR failed (code: %d).\n", int(result));
if (result == VK_ERROR_DEVICE_LOST)
report_checkpoints();
if (!ext.timeline_semaphore_features.timelineSemaphore)
data.need_fence = true;
@@ -1653,6 +1748,13 @@ VkResult Device::queue_submit(VkQueue queue, uint32_t count, const VkSubmitInfo2
return result;
}
if (count == 0 && fence)
{
auto result = table->vkQueueSubmit(queue, 0, nullptr, fence);
if (result != VK_SUCCESS)
return result;
}
return VK_SUCCESS;
}
}
@@ -1750,6 +1852,7 @@ void Device::submit_queue(QueueIndices physical_type, InternalFence *fence,
wsi.release->set_internal_sync_object();
composer.add_signal_semaphore(release, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0);
wsi.present_queue = queue;
wsi.present_queue_type = cmd->get_command_buffer_type();
wsi.consumed = true;
}
else
@@ -1781,12 +1884,10 @@ void Device::submit_queue(QueueIndices physical_type, InternalFence *fence,
auto start_ts = write_calibrated_timestamp_nolock();
auto result = submit_batches(composer, queue, cleared_fence, profiling_iteration);
auto end_ts = write_calibrated_timestamp_nolock();
register_time_interval_nolock("CPU", std::move(start_ts), std::move(end_ts), "submit", "");
register_time_interval_nolock("CPU", std::move(start_ts), std::move(end_ts), "submit");
if (result != VK_SUCCESS)
LOGE("vkQueueSubmit2KHR failed (code: %d).\n", int(result));
if (result == VK_ERROR_DEVICE_LOST)
report_checkpoints();
submissions.clear();
if (!ext.timeline_semaphore_features.timelineSemaphore)
@@ -2008,6 +2109,12 @@ VkQueue Device::get_current_present_queue() const
return wsi.present_queue;
}
CommandBuffer::Type Device::get_current_present_queue_type() const
{
VK_ASSERT(wsi.present_queue);
return wsi.present_queue_type;
}
const Sampler &Device::get_stock_sampler(StockSampler sampler) const
{
return samplers[static_cast<unsigned>(sampler)]->get_sampler();
@@ -2205,12 +2312,6 @@ static inline bool exists(const T &container, const U &value)
#endif
void Device::destroy_pipeline(VkPipeline pipeline)
{
LOCK();
destroy_pipeline_nolock(pipeline);
}
void Device::reset_fence(VkFence fence, bool observed_wait)
{
LOCK();
@@ -2289,12 +2390,6 @@ void Device::destroy_image_view(VkImageView view)
destroy_image_view_nolock(view);
}
void Device::destroy_pipeline_nolock(VkPipeline pipeline)
{
VK_ASSERT(!exists(frame().destroyed_pipelines, pipeline));
frame().destroyed_pipelines.push_back(pipeline);
}
void Device::destroy_image_view_nolock(VkImageView view)
{
VK_ASSERT(!exists(frame().destroyed_image_views, view));
@@ -2406,8 +2501,6 @@ void Device::wait_idle_nolock()
auto result = table->vkDeviceWaitIdle(device);
if (result != VK_SUCCESS)
LOGE("vkDeviceWaitIdle failed with code: %d\n", result);
if (result == VK_ERROR_DEVICE_LOST)
report_checkpoints();
if (queue_unlock_callback)
queue_unlock_callback();
}
@@ -2479,7 +2572,7 @@ void Device::next_frame_context()
if (frame_context_begin_ts)
{
auto frame_context_end_ts = write_calibrated_timestamp_nolock();
register_time_interval_nolock("CPU", std::move(frame_context_begin_ts), std::move(frame_context_end_ts), "command submissions", "");
register_time_interval_nolock("CPU", std::move(frame_context_begin_ts), std::move(frame_context_end_ts), "command submissions");
frame_context_begin_ts = {};
}
@@ -2661,14 +2754,15 @@ void Device::recalibrate_timestamps()
resample_calibrated_timestamps();
}
void Device::register_time_interval(std::string tid, QueryPoolHandle start_ts, QueryPoolHandle end_ts, std::string tag, std::string extra)
void Device::register_time_interval(std::string tid, QueryPoolHandle start_ts, QueryPoolHandle end_ts,
const std::string &tag)
{
LOCK();
register_time_interval_nolock(std::move(tid), std::move(start_ts), std::move(end_ts), std::move(tag), std::move(extra));
register_time_interval_nolock(std::move(tid), std::move(start_ts), std::move(end_ts), tag);
}
void Device::register_time_interval_nolock(std::string tid, QueryPoolHandle start_ts, QueryPoolHandle end_ts,
std::string tag, std::string extra)
const std::string &tag)
{
if (start_ts && end_ts)
{
@@ -2677,7 +2771,7 @@ void Device::register_time_interval_nolock(std::string tid, QueryPoolHandle star
if (start_ts->is_signalled() && end_ts->is_signalled())
VK_ASSERT(end_ts->get_timestamp_ticks() >= start_ts->get_timestamp_ticks());
#endif
frame().timestamp_intervals.push_back({ std::move(tid), std::move(start_ts), std::move(end_ts), timestamp_tag, std::move(extra) });
frame().timestamp_intervals.push_back({ std::move(tid), std::move(start_ts), std::move(end_ts), timestamp_tag });
}
}
@@ -2786,8 +2880,6 @@ void Device::PerFrame::begin()
table.vkDestroyFramebuffer(vkdevice, framebuffer, nullptr);
for (auto &sampler : destroyed_samplers)
table.vkDestroySampler(vkdevice, sampler, nullptr);
for (auto &pipeline : destroyed_pipelines)
table.vkDestroyPipeline(vkdevice, pipeline, nullptr);
for (auto &view : destroyed_image_views)
table.vkDestroyImageView(vkdevice, view, nullptr);
for (auto &view : destroyed_buffer_views)
@@ -2815,7 +2907,6 @@ void Device::PerFrame::begin()
destroyed_framebuffers.clear();
destroyed_samplers.clear();
destroyed_pipelines.clear();
destroyed_image_views.clear();
destroyed_buffer_views.clear();
destroyed_images.clear();
@@ -2827,7 +2918,7 @@ void Device::PerFrame::begin()
allocations.clear();
if (!in_destructor)
device.register_time_interval_nolock("CPU", std::move(wait_fence_ts), device.write_calibrated_timestamp_nolock(), "fence + recycle", "");
device.register_time_interval_nolock("CPU", std::move(wait_fence_ts), device.write_calibrated_timestamp_nolock(), "fence + recycle");
int64_t min_timestamp_us = std::numeric_limits<int64_t>::max();
int64_t max_timestamp_us = 0;
@@ -3148,9 +3239,7 @@ public:
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
image_usage_video_flags;
if (format_is_srgb(create_info.format))
usage_info.usage &= ~VK_IMAGE_USAGE_STORAGE_BIT;
@@ -3198,9 +3287,7 @@ public:
if ((create_info.usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)) == 0)
image_usage_video_flags)) == 0)
{
LOGE("Cannot create image view unless certain usage flags are present.\n");
return false;
@@ -3789,7 +3876,12 @@ ImageHandle Device::create_image_from_staging_buffer(const ImageCreateInfo &crea
if (format_info.viewFormatCount != 0)
{
create_unorm_srgb_views = true;
if (ext.supports_image_format_list)
const auto *input_format_list = static_cast<const VkBaseInStructure *>(info.pNext);
while (input_format_list && input_format_list->sType != VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR)
input_format_list = static_cast<const VkBaseInStructure *>(input_format_list->pNext);
if (ext.supports_image_format_list && !input_format_list)
{
format_info.pNext = info.pNext;
info.pNext = &format_info;
@@ -3806,7 +3898,7 @@ ImageHandle Device::create_image_from_staging_buffer(const ImageCreateInfo &crea
IMAGE_MISC_CONCURRENT_QUEUE_ASYNC_COMPUTE_BIT |
IMAGE_MISC_CONCURRENT_QUEUE_ASYNC_GRAPHICS_BIT |
IMAGE_MISC_CONCURRENT_QUEUE_ASYNC_TRANSFER_BIT |
IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_DECODE_BIT);
IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_DUPLEX);
bool concurrent_queue = queue_flags != 0 ||
staging_buffer != nullptr ||
create_info.initial_layout != VK_IMAGE_LAYOUT_UNDEFINED;
@@ -3845,6 +3937,9 @@ ImageHandle Device::create_image_from_staging_buffer(const ImageCreateInfo &crea
{ IMAGE_MISC_CONCURRENT_QUEUE_ASYNC_COMPUTE_BIT, QUEUE_INDEX_COMPUTE },
{ IMAGE_MISC_CONCURRENT_QUEUE_ASYNC_TRANSFER_BIT, QUEUE_INDEX_TRANSFER },
{ IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_DECODE_BIT, QUEUE_INDEX_VIDEO_DECODE },
#ifdef VK_ENABLE_BETA_EXTENSIONS
{ IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_ENCODE_BIT, QUEUE_INDEX_VIDEO_ENCODE },
#endif
};
for (auto &m : mappings)
@@ -3980,9 +4075,7 @@ ImageHandle Device::create_image_from_staging_buffer(const ImageCreateInfo &crea
bool has_view = (info.usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)) != 0 &&
image_usage_video_flags)) != 0 &&
(create_info.misc & IMAGE_MISC_NO_DEFAULT_VIEWS_BIT) == 0;
VkImageViewType view_type = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
@@ -4085,6 +4178,10 @@ ImageHandle Device::create_image_from_staging_buffer(const ImageCreateInfo &crea
type = CommandBuffer::Type::AsyncTransfer;
else if (queue_flags & IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_DECODE_BIT)
type = CommandBuffer::Type::VideoDecode;
#ifdef VK_ENABLE_BETA_EXTENSIONS
else if (queue_flags & IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_ENCODE_BIT)
type = CommandBuffer::Type::VideoEncode;
#endif
VK_ASSERT(type != CommandBuffer::Type::Count);
auto cmd = request_command_buffer(type);
@@ -4154,6 +4251,16 @@ ImageHandle Device::create_image_from_staging_buffer(const ImageCreateInfo &crea
sem_count++;
}
#ifdef VK_ENABLE_BETA_EXTENSIONS
if (create_info.misc & IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_ENCODE_BIT)
{
types[sem_count] = CommandBuffer::Type::VideoEncode;
stages[sem_count] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
if (stages[sem_count] != 0)
sem_count++;
}
#endif
VK_ASSERT(sem_count);
submit(transition_cmd, nullptr, sem_count, sem);
@@ -4325,6 +4432,8 @@ BufferHandle Device::create_imported_host_buffer(const BufferCreateInfo &create_
VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
info.size = create_info.size;
info.usage = create_info.usage;
if (get_device_features().buffer_device_address_features.bufferDeviceAddress)
info.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.pNext = &external_info;
@@ -4378,6 +4487,13 @@ BufferHandle Device::create_imported_host_buffer(const BufferCreateInfo &create_
~(ext.host_memory_properties.minImportedHostPointerAlignment - 1);
alloc_info.memoryTypeIndex = memory_type;
VkMemoryAllocateFlagsInfo flags_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO };
if (get_device_features().buffer_device_address_features.bufferDeviceAddress)
{
alloc_info.pNext = &flags_info;
flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
}
VkImportMemoryHostPointerInfoEXT import = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT };
import.handleType = type;
import.pHostPointer = host_buffer;
@@ -4411,7 +4527,15 @@ BufferHandle Device::create_imported_host_buffer(const BufferCreateInfo &create_
return BufferHandle{};
}
BufferHandle handle(handle_pool.buffers.allocate(this, buffer, allocation, create_info));
VkDeviceAddress bda = 0;
if (get_device_features().buffer_device_address_features.bufferDeviceAddress)
{
VkBufferDeviceAddressInfoKHR bda_info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR };
bda_info.buffer = buffer;
bda = table->vkGetBufferDeviceAddressKHR(device, &bda_info);
}
BufferHandle handle(handle_pool.buffers.allocate(this, buffer, allocation, create_info, bda));
return handle;
}
@@ -4437,6 +4561,8 @@ BufferHandle Device::create_buffer(const BufferCreateInfo &create_info, const vo
VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
info.size = create_info.size;
info.usage = create_info.usage | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
if (get_device_features().buffer_device_address_features.bufferDeviceAddress)
info.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
uint32_t sharing_indices[QUEUE_INDEX_COUNT];
@@ -4490,6 +4616,16 @@ BufferHandle Device::create_buffer(const BufferCreateInfo &create_info, const vo
req_info.buffer = buffer;
table->vkGetBufferMemoryRequirements2(device, &req_info, &reqs);
if (create_info.allocation_requirements.size)
{
reqs.memoryRequirements.memoryTypeBits &=
create_info.allocation_requirements.memoryTypeBits;
reqs.memoryRequirements.size =
std::max<VkDeviceSize>(reqs.memoryRequirements.size, create_info.allocation_requirements.size);
reqs.memoryRequirements.alignment =
std::max<VkDeviceSize>(reqs.memoryRequirements.alignment, create_info.allocation_requirements.alignment);
}
uint32_t memory_type = find_memory_type(create_info.domain, reqs.memoryRequirements.memoryTypeBits);
if (memory_type == UINT32_MAX)
{
@@ -4565,7 +4701,16 @@ BufferHandle Device::create_buffer(const BufferCreateInfo &create_info, const vo
auto tmpinfo = create_info;
tmpinfo.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
BufferHandle handle(handle_pool.buffers.allocate(this, buffer, allocation, tmpinfo));
VkDeviceAddress bda = 0;
if (get_device_features().buffer_device_address_features.bufferDeviceAddress)
{
VkBufferDeviceAddressInfoKHR bda_info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR };
bda_info.buffer = buffer;
bda = table->vkGetBufferDeviceAddressKHR(device, &bda_info);
}
BufferHandle handle(handle_pool.buffers.allocate(this, buffer, allocation, tmpinfo, bda));
if (create_info.domain == BufferDomain::Device && (initial || zero_initialize) && !memory_type_is_host_visible(memory_type))
{
@@ -4926,32 +5071,6 @@ void Device::set_name(const CommandBuffer &cmd, const char *name)
set_name((uint64_t)cmd.get_command_buffer(), VK_OBJECT_TYPE_COMMAND_BUFFER, name);
}
void Device::report_checkpoints()
{
if (!ext.supports_nv_device_diagnostic_checkpoints)
return;
for (int i = 0; i < QUEUE_INDEX_COUNT; i++)
{
if (queue_info.queues[i] == VK_NULL_HANDLE)
continue;
uint32_t count;
table->vkGetQueueCheckpointDataNV(queue_info.queues[i], &count, nullptr);
std::vector<VkCheckpointDataNV> checkpoint_data(count);
for (auto &data : checkpoint_data)
data.sType = VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV;
table->vkGetQueueCheckpointDataNV(queue_info.queues[i], &count, checkpoint_data.data());
if (!checkpoint_data.empty())
{
LOGI("Checkpoints for %s queue:\n", queue_name_table[i]);
for (auto &d : checkpoint_data)
LOGI("Stage %u:\n%s\n", d.stage, static_cast<const char *>(d.pCheckpointMarker));
}
}
}
void Device::query_available_performance_counters(CommandBuffer::Type type, uint32_t *count,
const VkPerformanceCounterKHR **counters,
const VkPerformanceCounterDescriptionKHR **desc)
@@ -5136,11 +5255,18 @@ void Device::end_renderdoc_capture()
#endif
bool Device::supports_subgroup_size_log2(bool subgroup_full_group, uint8_t subgroup_minimum_size_log2,
uint8_t subgroup_maximum_size_log2) const
uint8_t subgroup_maximum_size_log2, VkShaderStageFlagBits stage) const
{
if (ImplementationQuirks::get().force_no_subgroup_size_control)
return false;
if (stage != VK_SHADER_STAGE_COMPUTE_BIT &&
stage != VK_SHADER_STAGE_MESH_BIT_EXT &&
stage != VK_SHADER_STAGE_TASK_BIT_EXT)
{
return false;
}
if (!ext.subgroup_size_control_features.subgroupSizeControl)
return false;
if (subgroup_full_group && !ext.subgroup_size_control_features.computeFullSubgroups)
@@ -5164,7 +5290,7 @@ bool Device::supports_subgroup_size_log2(bool subgroup_full_group, uint8_t subgr
}
// We need requiredSubgroupSizeStages support here.
return (ext.subgroup_size_control_properties.requiredSubgroupSizeStages & VK_SHADER_STAGE_COMPUTE_BIT) != 0;
return (ext.subgroup_size_control_properties.requiredSubgroupSizeStages & stage) != 0;
}
const QueueInfo &Device::get_queue_info() const
@@ -5196,7 +5322,7 @@ CommandBufferHandle request_command_buffer_with_ownership_transfer(
Vulkan::IMAGE_MISC_CONCURRENT_QUEUE_GRAPHICS_BIT |
Vulkan::IMAGE_MISC_CONCURRENT_QUEUE_ASYNC_COMPUTE_BIT |
Vulkan::IMAGE_MISC_CONCURRENT_QUEUE_ASYNC_GRAPHICS_BIT |
Vulkan::IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_DECODE_BIT)) != 0;
Vulkan::IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_DUPLEX)) != 0;
bool need_ownership_transfer = old_family != new_family && !image_is_concurrent;
VkImageMemoryBarrier2 ownership = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 };
+21 -10
View File
@@ -38,6 +38,7 @@
#include "context.hpp"
#include "query_pool.hpp"
#include "buffer_pool.hpp"
#include "indirect_layout.hpp"
#include <memory>
#include <vector>
#include <functional>
@@ -285,19 +286,28 @@ public:
void submit_discard(CommandBufferHandle &cmd);
QueueIndices get_physical_queue_type(CommandBuffer::Type queue_type) const;
void register_time_interval(std::string tid, QueryPoolHandle start_ts, QueryPoolHandle end_ts,
std::string tag, std::string extra = {});
const std::string &tag);
// Request shaders and programs. These objects are owned by the Device.
Shader *request_shader(const uint32_t *code, size_t size, const ResourceLayout *layout = nullptr);
Shader *request_shader_by_hash(Util::Hash hash);
Program *request_program(const uint32_t *task_data, size_t task_size,
const uint32_t *mesh_data, size_t mesh_size,
const uint32_t *fragment_data, size_t fragment_size,
const ResourceLayout *task_layout = nullptr,
const ResourceLayout *mesh_layout = nullptr,
const ResourceLayout *fragment_layout = nullptr);
Program *request_program(const uint32_t *vertex_data, size_t vertex_size,
const uint32_t *fragment_data, size_t fragment_size,
const ResourceLayout *vertex_layout = nullptr,
const ResourceLayout *fragment_layout = nullptr);
Program *request_program(const uint32_t *compute_data, size_t compute_size,
const ResourceLayout *layout = nullptr);
Program *request_program(Shader *task, Shader *mesh, Shader *fragment, const ImmutableSamplerBank *sampler_bank = nullptr);
Program *request_program(Shader *vertex, Shader *fragment, const ImmutableSamplerBank *sampler_bank = nullptr);
Program *request_program(Shader *compute, const ImmutableSamplerBank *sampler_bank = nullptr);
const IndirectLayout *request_indirect_layout(const IndirectLayoutToken *tokens,
uint32_t num_tokens, uint32_t stride);
const ImmutableYcbcrConversion *request_immutable_ycbcr_conversion(const VkSamplerYcbcrConversionCreateInfo &info);
const ImmutableSampler *request_immutable_sampler(const SamplerCreateInfo &info, const ImmutableYcbcrConversion *ycbcr);
@@ -483,7 +493,8 @@ public:
bool supports_subgroup_size_log2(bool subgroup_full_group,
uint8_t subgroup_minimum_size_log2,
uint8_t subgroup_maximum_size_log2) const;
uint8_t subgroup_maximum_size_log2,
VkShaderStageFlagBits stage = VK_SHADER_STAGE_COMPUTE_BIT) const;
const QueueInfo &get_queue_info() const;
@@ -503,6 +514,7 @@ private:
uint64_t allocate_cookie();
void bake_program(Program &program, const ImmutableSamplerBank *sampler_bank);
void merge_combined_resource_layout(CombinedResourceLayout &layout, const Program &program);
void request_vertex_block(BufferBlock &block, VkDeviceSize size);
void request_index_block(BufferBlock &block, VkDeviceSize size);
@@ -514,9 +526,10 @@ private:
void set_acquire_semaphore(unsigned index, Semaphore acquire);
Semaphore consume_release_semaphore();
VkQueue get_current_present_queue() const;
CommandBuffer::Type get_current_present_queue_type() const;
PipelineLayout *request_pipeline_layout(const CombinedResourceLayout &layout,
const ImmutableSamplerBank *immutable_samplers);
const PipelineLayout *request_pipeline_layout(const CombinedResourceLayout &layout,
const ImmutableSamplerBank *immutable_samplers);
DescriptorSetAllocator *request_descriptor_set_allocator(const DescriptorSetLayout &layout,
const uint32_t *stages_for_sets,
const ImmutableSampler * const *immutable_samplers);
@@ -538,7 +551,8 @@ private:
QueryPoolHandle write_timestamp_nolock(VkCommandBuffer cmd, VkPipelineStageFlags2 stage);
QueryPoolHandle write_calibrated_timestamp_nolock();
void register_time_interval_nolock(std::string tid, QueryPoolHandle start_ts, QueryPoolHandle end_ts, std::string tag, std::string extra);
void register_time_interval_nolock(std::string tid, QueryPoolHandle start_ts, QueryPoolHandle end_ts,
const std::string &tag);
// Make sure this is deleted last.
HandlePool handle_pool;
@@ -607,7 +621,6 @@ private:
std::vector<DeviceAllocation> allocations;
std::vector<VkFramebuffer> destroyed_framebuffers;
std::vector<VkSampler> destroyed_samplers;
std::vector<VkPipeline> destroyed_pipelines;
std::vector<VkImageView> destroyed_image_views;
std::vector<VkBufferView> destroyed_buffer_views;
std::vector<VkImage> destroyed_images;
@@ -633,7 +646,6 @@ private:
QueryPoolHandle start_ts;
QueryPoolHandle end_ts;
TimestampInterval *timestamp_tag;
std::string extra;
};
std::vector<TimestampIntervalHandles> timestamp_intervals;
@@ -649,6 +661,7 @@ private:
Semaphore release;
std::vector<ImageHandle> swapchain;
VkQueue present_queue = VK_NULL_HANDLE;
Vulkan::CommandBuffer::Type present_queue_type = {};
uint32_t queue_family_support_mask = 0;
unsigned index = 0;
bool consumed = false;
@@ -718,6 +731,7 @@ private:
VulkanCache<Program> programs;
VulkanCache<ImmutableSampler> immutable_samplers;
VulkanCache<ImmutableYcbcrConversion> immutable_ycbcr_conversions;
VulkanCache<IndirectLayout> indirect_layouts;
FramebufferAllocator framebuffer_allocator;
TransientAttachmentAllocator transient_allocator;
@@ -753,7 +767,6 @@ private:
void destroy_image(VkImage image);
void destroy_image_view(VkImageView view);
void destroy_buffer_view(VkBufferView view);
void destroy_pipeline(VkPipeline pipeline);
void destroy_sampler(VkSampler sampler);
void destroy_framebuffer(VkFramebuffer framebuffer);
void destroy_semaphore(VkSemaphore semaphore);
@@ -768,7 +781,6 @@ private:
void destroy_image_nolock(VkImage image);
void destroy_image_view_nolock(VkImageView view);
void destroy_buffer_view_nolock(VkBufferView view);
void destroy_pipeline_nolock(VkPipeline pipeline);
void destroy_sampler_nolock(VkSampler sampler);
void destroy_framebuffer_nolock(VkFramebuffer framebuffer);
void destroy_semaphore_nolock(VkSemaphore semaphore);
@@ -859,7 +871,6 @@ private:
ImplementationWorkarounds workarounds;
void init_workarounds();
void report_checkpoints();
void fill_buffer_sharing_indices(VkBufferCreateInfo &create_info, uint32_t *sharing_indices);
@@ -195,32 +195,78 @@ bool Device::enqueue_create_shader_module(Fossilize::Hash hash, const VkShaderMo
bool Device::fossilize_replay_graphics_pipeline(Fossilize::Hash hash, VkGraphicsPipelineCreateInfo &info)
{
if (info.stageCount != 2 ||
info.pStages[0].stage != VK_SHADER_STAGE_VERTEX_BIT ||
info.pStages[1].stage != VK_SHADER_STAGE_FRAGMENT_BIT)
int vert_index = -1;
int task_index = -1;
int mesh_index = -1;
int frag_index = -1;
for (uint32_t i = 0; i < info.stageCount; i++)
{
switch (info.pStages[i].stage)
{
case VK_SHADER_STAGE_VERTEX_BIT:
vert_index = int(i);
break;
case VK_SHADER_STAGE_TASK_BIT_EXT:
task_index = int(i);
break;
case VK_SHADER_STAGE_MESH_BIT_EXT:
mesh_index = int(i);
break;
case VK_SHADER_STAGE_FRAGMENT_BIT:
frag_index = int(i);
break;
default:
replayer_state->progress.pipelines.fetch_add(1, std::memory_order_release);
return false;
}
}
if (frag_index < 0 || (mesh_index < 0 && vert_index < 0) ||
(mesh_index >= 0 && vert_index >= 0))
{
replayer_state->progress.pipelines.fetch_add(1, std::memory_order_release);
return false;
}
auto *vert_shader = shaders.find((Fossilize::Hash)info.pStages[0].module);
auto *frag_shader = shaders.find((Fossilize::Hash)info.pStages[1].module);
auto *vert_shader = vert_index >= 0 ? shaders.find((Fossilize::Hash)info.pStages[vert_index].module) : nullptr;
auto *task_shader = task_index >= 0 ? shaders.find((Fossilize::Hash)info.pStages[task_index].module) : nullptr;
auto *mesh_shader = mesh_index >= 0 ? shaders.find((Fossilize::Hash)info.pStages[mesh_index].module) : nullptr;
auto *frag_shader = shaders.find((Fossilize::Hash)info.pStages[frag_index].module);
if (!vert_shader || !frag_shader)
if ((!vert_shader && !mesh_shader) || !frag_shader)
{
replayer_state->progress.pipelines.fetch_add(1, std::memory_order_release);
return false;
}
auto *ret = request_program(vert_shader, frag_shader,
reinterpret_cast<const ImmutableSamplerBank *>(info.layout));
Program *ret;
if (mesh_shader)
{
ret = request_program(task_shader, mesh_shader, frag_shader,
reinterpret_cast<const ImmutableSamplerBank *>(info.layout));
}
else
{
ret = request_program(vert_shader, frag_shader,
reinterpret_cast<const ImmutableSamplerBank *>(info.layout));
}
// The layout is dummy, resolve it here.
info.layout = ret->get_pipeline_layout()->get_layout();
// Resolve shader modules.
const_cast<VkPipelineShaderStageCreateInfo *>(info.pStages)[0].module = vert_shader->get_module();
const_cast<VkPipelineShaderStageCreateInfo *>(info.pStages)[1].module = frag_shader->get_module();
if (vert_index >= 0)
const_cast<VkPipelineShaderStageCreateInfo *>(info.pStages)[vert_index].module = vert_shader->get_module();
if (task_index >= 0)
const_cast<VkPipelineShaderStageCreateInfo *>(info.pStages)[task_index].module = task_shader->get_module();
if (mesh_index >= 0)
const_cast<VkPipelineShaderStageCreateInfo *>(info.pStages)[mesh_index].module = mesh_shader->get_module();
const_cast<VkPipelineShaderStageCreateInfo *>(info.pStages)[frag_index].module = frag_shader->get_module();
#ifdef VULKAN_DEBUG
LOGI("Replaying graphics pipeline.\n");
+30 -7
View File
@@ -75,19 +75,42 @@ void FenceHolder::wait()
bool FenceHolder::wait_timeout(uint64_t timeout)
{
bool ret = false;
bool ret;
auto &table = device->get_device_table();
// Waiting for the same VkFence in parallel is not allowed, and there seems to be some shenanigans on Intel
// when waiting for a timeline semaphore in parallel with same value as well.
std::lock_guard<std::mutex> holder{lock};
if (observed_wait)
return true;
if (timeline_value != 0)
{
VK_ASSERT(timeline_semaphore);
VkSemaphoreWaitInfoKHR info = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR };
info.semaphoreCount = 1;
info.pSemaphores = &timeline_semaphore;
info.pValues = &timeline_value;
ret = table.vkWaitSemaphoresKHR(device->get_device(), &info, timeout) == VK_SUCCESS;
if (timeout == 0)
{
uint64_t current_value = 0;
ret = table.vkGetSemaphoreCounterValueKHR(device->get_device(), timeline_semaphore, &current_value) == VK_SUCCESS &&
current_value >= timeline_value;
}
else
{
VkSemaphoreWaitInfoKHR info = {VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR};
info.semaphoreCount = 1;
info.pSemaphores = &timeline_semaphore;
info.pValues = &timeline_value;
ret = table.vkWaitSemaphoresKHR(device->get_device(), &info, timeout) == VK_SUCCESS;
}
}
else
ret = table.vkWaitForFences(device->get_device(), 1, &fence, VK_TRUE, timeout) == VK_SUCCESS;
{
if (timeout == 0)
ret = table.vkGetFenceStatus(device->get_device(), fence) == VK_SUCCESS;
else
ret = table.vkWaitForFences(device->get_device(), 1, &fence, VK_TRUE, timeout) == VK_SUCCESS;
}
if (ret)
observed_wait = true;
+1 -1
View File
@@ -23,7 +23,7 @@
#pragma once
#include "vulkan_headers.hpp"
#include "texture_format.hpp"
#include "texture/texture_format.hpp"
namespace Vulkan
{
+10 -1
View File
@@ -75,7 +75,16 @@ enum ImageMiscFlagBits
IMAGE_MISC_LINEAR_IMAGE_IGNORE_DEVICE_LOCAL_BIT = 1 << 9,
IMAGE_MISC_FORCE_NO_DEDICATED_BIT = 1 << 10,
IMAGE_MISC_NO_DEFAULT_VIEWS_BIT = 1 << 11,
IMAGE_MISC_EXTERNAL_MEMORY_BIT = 1 << 12
IMAGE_MISC_EXTERNAL_MEMORY_BIT = 1 << 12,
#ifdef VK_ENABLE_BETA_EXTENSIONS
IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_ENCODE_BIT = 1 << 13,
IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_DUPLEX =
IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_DECODE_BIT |
IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_ENCODE_BIT,
#else
IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_DUPLEX =
IMAGE_MISC_CONCURRENT_QUEUE_VIDEO_DECODE_BIT,
#endif
};
using ImageMiscFlags = uint32_t;
@@ -0,0 +1,102 @@
/* Copyright (c) 2017-2023 Hans-Kristian Arntzen
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "indirect_layout.hpp"
#include "device.hpp"
#include "small_vector.hpp"
namespace Vulkan
{
IndirectLayout::IndirectLayout(Device *device_, const IndirectLayoutToken *tokens, uint32_t num_tokens, uint32_t stride)
: device(device_)
{
VkIndirectCommandsLayoutCreateInfoNV info = { VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV };
info.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
info.pStreamStrides = &stride;
info.streamCount = 1;
Util::SmallVector<VkIndirectCommandsLayoutTokenNV, 8> nv_tokens;
nv_tokens.reserve(num_tokens);
for (uint32_t i = 0; i < num_tokens; i++)
{
VkIndirectCommandsLayoutTokenNV token = { VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_NV };
switch (tokens[i].type)
{
case IndirectLayoutToken::Type::VBO:
token.tokenType = VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV;
token.vertexBindingUnit = tokens[i].data.vbo.binding;
break;
case IndirectLayoutToken::Type::IBO:
token.tokenType = VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV;
break;
case IndirectLayoutToken::Type::PushConstant:
token.tokenType = VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV;
token.pushconstantSize = tokens[i].data.push.range;
token.pushconstantOffset = tokens[i].data.push.offset;
token.pushconstantPipelineLayout = tokens[i].data.push.layout->get_layout();
token.pushconstantShaderStageFlags = tokens[i].data.push.layout->get_resource_layout().push_constant_range.stageFlags;
break;
case IndirectLayoutToken::Type::Draw:
token.tokenType = VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV;
break;
case IndirectLayoutToken::Type::DrawIndexed:
token.tokenType = VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV;
break;
case IndirectLayoutToken::Type::Shader:
token.tokenType = VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV;
break;
case IndirectLayoutToken::Type::MeshTasks:
token.tokenType = VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_NV;
break;
default:
LOGE("Invalid token type.\n");
break;
}
token.offset = tokens[i].offset;
nv_tokens.push_back(token);
}
info.pTokens = nv_tokens.data();
info.tokenCount = num_tokens;
auto &table = device->get_device_table();
if (table.vkCreateIndirectCommandsLayoutNV(device->get_device(), &info, nullptr, &layout) != VK_SUCCESS)
{
LOGE("Failed to create indirect layout.\n");
}
}
IndirectLayout::~IndirectLayout()
{
device->get_device_table().vkDestroyIndirectCommandsLayoutNV(device->get_device(), layout, nullptr);
}
}
@@ -0,0 +1,84 @@
/* Copyright (c) 2017-2023 Hans-Kristian Arntzen
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include "vulkan_headers.hpp"
#include "vulkan_common.hpp"
#include "cookie.hpp"
namespace Vulkan
{
class Device;
class PipelineLayout;
struct IndirectLayoutToken
{
enum class Type
{
Invalid = 0,
Shader,
PushConstant,
VBO,
IBO,
Draw,
DrawIndexed,
MeshTasks,
};
Type type = Type::Invalid;
uint32_t offset = 0;
union
{
struct
{
uint32_t offset;
uint32_t range;
const PipelineLayout *layout;
} push;
struct
{
uint32_t binding;
} vbo;
} data = {};
};
class IndirectLayout : public HashedObject<IndirectLayout>
{
public:
IndirectLayout(Device *device, const IndirectLayoutToken *token, uint32_t num_tokens, uint32_t stride);
~IndirectLayout();
VkIndirectCommandsLayoutNV get_layout() const
{
return layout;
}
private:
friend class Device;
Device *device;
VkIndirectCommandsLayoutNV layout;
};
}
@@ -34,6 +34,22 @@
namespace Vulkan
{
static bool allocation_mode_supports_bda(AllocationMode mode)
{
switch (mode)
{
case AllocationMode::LinearDevice:
case AllocationMode::LinearHostMappable:
case AllocationMode::LinearDeviceHighPriority:
return true;
default:
break;
}
return false;
}
void DeviceAllocation::free_immediate()
{
if (!alloc)
@@ -634,6 +650,7 @@ bool DeviceAllocator::internal_allocate(
VkMemoryDedicatedAllocateInfo dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO };
VkExportMemoryAllocateInfo export_info = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO };
VkMemoryPriorityAllocateInfoEXT priority_info = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT };
VkMemoryAllocateFlagsInfo flags_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO };
#ifdef _WIN32
VkImportMemoryWin32HandleInfoKHR import_info = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR };
#else
@@ -697,6 +714,14 @@ bool DeviceAllocator::internal_allocate(
info.pNext = &priority_info;
}
if (device->get_device_features().buffer_device_address_features.bufferDeviceAddress &&
allocation_mode_supports_bda(mode))
{
flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
flags_info.pNext = info.pNext;
info.pNext = &flags_info;
}
VkDeviceMemory device_memory;
VkResult res;
{
+11 -4
View File
@@ -583,6 +583,16 @@ Program::Program(Device *device_, Shader *vertex, Shader *fragment, const Immuta
device->bake_program(*this, sampler_bank);
}
Program::Program(Device *device_, Shader *task, Shader *mesh, Shader *fragment, const ImmutableSamplerBank *sampler_bank)
: device(device_)
{
if (task)
set_shader(ShaderStage::Task, task);
set_shader(ShaderStage::Mesh, mesh);
set_shader(ShaderStage::Fragment, fragment);
device->bake_program(*this, sampler_bank);
}
Program::Program(Device *device_, Shader *compute_shader, const ImmutableSamplerBank *sampler_bank)
: device(device_)
{
@@ -603,10 +613,7 @@ Pipeline Program::add_pipeline(Hash hash, const Pipeline &pipeline)
void Program::destroy_pipeline(const Pipeline &pipeline)
{
if (internal_sync)
device->destroy_pipeline_nolock(pipeline.pipeline);
else
device->destroy_pipeline(pipeline.pipeline);
device->get_device_table().vkDestroyPipeline(device->get_device(), pipeline.pipeline, nullptr);
}
void Program::promote_read_write_to_read_only()
+7 -4
View File
@@ -47,6 +47,8 @@ enum class ShaderStage
Geometry = 3,
Fragment = 4,
Compute = 5,
Task = 6,
Mesh = 7,
Count
};
@@ -178,10 +180,11 @@ struct Pipeline
uint32_t dynamic_mask;
};
class Program : public HashedObject<Program>, public InternalSyncEnabled
class Program : public HashedObject<Program>
{
public:
Program(Device *device, Shader *vertex, Shader *fragment, const ImmutableSamplerBank *sampler_bank);
Program(Device *device, Shader *task, Shader *mesh, Shader *fragment, const ImmutableSamplerBank *sampler_bank);
Program(Device *device, Shader *compute, const ImmutableSamplerBank *sampler_bank);
~Program();
@@ -190,12 +193,12 @@ public:
return shaders[Util::ecast(stage)];
}
void set_pipeline_layout(PipelineLayout *new_layout)
void set_pipeline_layout(const PipelineLayout *new_layout)
{
layout = new_layout;
}
PipelineLayout *get_pipeline_layout() const
const PipelineLayout *get_pipeline_layout() const
{
return layout;
}
@@ -209,7 +212,7 @@ private:
void set_shader(ShaderStage stage, Shader *handle);
Device *device;
Shader *shaders[Util::ecast(ShaderStage::Count)] = {};
PipelineLayout *layout = nullptr;
const PipelineLayout *layout = nullptr;
VulkanCache<Util::IntrusivePODWrapper<Pipeline>> pipelines;
void destroy_pipeline(const Pipeline &pipeline);
};
@@ -44,6 +44,9 @@ enum QueueIndices
QUEUE_INDEX_COMPUTE,
QUEUE_INDEX_TRANSFER,
QUEUE_INDEX_VIDEO_DECODE,
#ifdef VK_ENABLE_BETA_EXTENSIONS
QUEUE_INDEX_VIDEO_ENCODE,
#endif
QUEUE_INDEX_COUNT
};
+14 -8
View File
@@ -248,6 +248,9 @@ bool WSI::init_context_from_platform(unsigned num_thread_indices, const Context:
#ifdef HAVE_FFMPEG_VULKAN
constexpr ContextCreationFlags video_context_flags =
CONTEXT_CREATION_ENABLE_VIDEO_DECODE_BIT |
#ifdef HAVE_FFMPEG_VULKAN_ENCODE
CONTEXT_CREATION_ENABLE_VIDEO_ENCODE_BIT |
#endif
CONTEXT_CREATION_ENABLE_VIDEO_H264_BIT |
CONTEXT_CREATION_ENABLE_VIDEO_H265_BIT;
#else
@@ -1109,20 +1112,18 @@ static bool init_surface_info(Device &device, WSIPlatform &platform,
baseline_image_count = std::max(3u, baseline_image_count);
// Make sure we query surface caps tied to the present mode for correct results.
if (ext.supports_surface_maintenance1 && ext.supports_surface_capabilities2)
if (ext.swapchain_maintenance1_features.swapchainMaintenance1 &&
ext.supports_surface_capabilities2)
{
VkSurfaceCapabilities2KHR surface_capabilities2 = { VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR };
VkSurfacePresentModeCompatibilityEXT present_mode_caps =
{ VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT };
std::vector<VkPresentModeKHR> present_mode_compat_group;
if (ext.supports_surface_maintenance1)
{
present_mode_compat_group.resize(32);
present_mode_caps.presentModeCount = present_mode_compat_group.size();
present_mode_caps.pPresentModes = present_mode_compat_group.data();
surface_capabilities2.pNext = &present_mode_caps;
}
present_mode_compat_group.resize(32);
present_mode_caps.presentModeCount = present_mode_compat_group.size();
present_mode_caps.pPresentModes = present_mode_compat_group.data();
surface_capabilities2.pNext = &present_mode_caps;
info.present_mode.pNext = const_cast<void *>(info.surface_info.pNext);
info.surface_info.pNext = &info.present_mode;
@@ -1477,6 +1478,11 @@ VkSurfaceTransformFlagBitsKHR WSI::get_current_prerotate() const
return swapchain_current_prerotate;
}
CommandBuffer::Type WSI::get_current_present_queue_type() const
{
return device->get_current_present_queue_type();
}
WSI::~WSI()
{
teardown();
+2
View File
@@ -243,6 +243,8 @@ public:
void set_external_frame(unsigned index, Semaphore acquire_semaphore, double frame_time);
Semaphore consume_external_release_semaphore();
CommandBuffer::Type get_current_present_queue_type() const;
// Equivalent to calling destructor.
void teardown();