Merge branch 'vk_transform_feedback'

This commit is contained in:
Philip Rebohle 2018-10-13 08:00:51 +02:00
commit 6b5aa0b928
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
43 changed files with 2056 additions and 207 deletions

View File

@ -43,7 +43,7 @@ extern "C" {
#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
// Version of this file
#define VK_HEADER_VERSION 84
#define VK_HEADER_VERSION 87
#define VK_NULL_HANDLE 0
@ -297,7 +297,11 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000,
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001,
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001,
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002,
VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000,
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000,
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000,
@ -404,18 +408,45 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004,
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002,
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005,
VK_STRUCTURE_TYPE_RAYTRACING_PIPELINE_CREATE_INFO_NVX = 1000165000,
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NVX = 1000165001,
VK_STRUCTURE_TYPE_GEOMETRY_INSTANCE_NVX = 1000165002,
VK_STRUCTURE_TYPE_GEOMETRY_NVX = 1000165003,
VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NVX = 1000165004,
VK_STRUCTURE_TYPE_GEOMETRY_AABB_NVX = 1000165005,
VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NVX = 1000165006,
VK_STRUCTURE_TYPE_DESCRIPTOR_ACCELERATION_STRUCTURE_INFO_NVX = 1000165007,
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NVX = 1000165008,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAYTRACING_PROPERTIES_NVX = 1000165009,
VK_STRUCTURE_TYPE_HIT_SHADER_MODULE_CREATE_INFO_NVX = 1000165010,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000,
VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001,
VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = 1000177000,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000,
VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = 1000180000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000,
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = 1000196000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000,
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002,
VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000,
VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000,
VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000,
VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
@ -806,6 +837,8 @@ typedef enum VkQueryType {
VK_QUERY_TYPE_OCCLUSION = 0,
VK_QUERY_TYPE_PIPELINE_STATISTICS = 1,
VK_QUERY_TYPE_TIMESTAMP = 2,
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT = 1000028004,
VK_QUERY_TYPE_COMPACTED_SIZE_NVX = 1000165000,
VK_QUERY_TYPE_BEGIN_RANGE = VK_QUERY_TYPE_OCCLUSION,
VK_QUERY_TYPE_END_RANGE = VK_QUERY_TYPE_TIMESTAMP,
VK_QUERY_TYPE_RANGE_SIZE = (VK_QUERY_TYPE_TIMESTAMP - VK_QUERY_TYPE_OCCLUSION + 1),
@ -835,6 +868,7 @@ typedef enum VkImageLayout {
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002,
VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000,
VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = 1000164003,
VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED,
@ -1068,6 +1102,9 @@ typedef enum VkDynamicState {
VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000,
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000,
VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000,
VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1000164004,
VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006,
VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001,
VK_DYNAMIC_STATE_BEGIN_RANGE = VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_END_RANGE = VK_DYNAMIC_STATE_STENCIL_REFERENCE,
VK_DYNAMIC_STATE_RANGE_SIZE = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1),
@ -1131,6 +1168,7 @@ typedef enum VkDescriptorType {
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9,
VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10,
VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000,
VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NVX = 1000165000,
VK_DESCRIPTOR_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_TYPE_SAMPLER,
VK_DESCRIPTOR_TYPE_END_RANGE = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
VK_DESCRIPTOR_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1),
@ -1159,6 +1197,7 @@ typedef enum VkAttachmentStoreOp {
typedef enum VkPipelineBindPoint {
VK_PIPELINE_BIND_POINT_GRAPHICS = 0,
VK_PIPELINE_BIND_POINT_COMPUTE = 1,
VK_PIPELINE_BIND_POINT_RAYTRACING_NVX = 1000165000,
VK_PIPELINE_BIND_POINT_BEGIN_RANGE = VK_PIPELINE_BIND_POINT_GRAPHICS,
VK_PIPELINE_BIND_POINT_END_RANGE = VK_PIPELINE_BIND_POINT_COMPUTE,
VK_PIPELINE_BIND_POINT_RANGE_SIZE = (VK_PIPELINE_BIND_POINT_COMPUTE - VK_PIPELINE_BIND_POINT_GRAPHICS + 1),
@ -1230,6 +1269,7 @@ typedef enum VkObjectType {
VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX = 1000086001,
VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000,
VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000,
VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NVX = 1000165000,
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_BEGIN_RANGE = VK_OBJECT_TYPE_UNKNOWN,
@ -1297,6 +1337,7 @@ typedef enum VkImageUsageFlagBits {
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020,
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040,
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080,
VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00000100,
VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkImageUsageFlagBits;
typedef VkFlags VkImageUsageFlags;
@ -1314,6 +1355,7 @@ typedef enum VkImageCreateFlagBits {
VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 0x00000100,
VK_IMAGE_CREATE_PROTECTED_BIT = 0x00000800,
VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200,
VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000,
VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000,
VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT,
VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT,
@ -1391,8 +1433,13 @@ typedef enum VkPipelineStageFlagBits {
VK_PIPELINE_STAGE_HOST_BIT = 0x00004000,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000,
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000,
VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000,
VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = 0x00020000,
VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00400000,
VK_PIPELINE_STAGE_RAYTRACING_BIT_NVX = 0x00200000,
VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = 0x00080000,
VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = 0x00100000,
VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkPipelineStageFlagBits;
typedef VkFlags VkPipelineStageFlags;
@ -1480,7 +1527,10 @@ typedef enum VkBufferUsageFlagBits {
VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080,
VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100,
VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800,
VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000,
VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200,
VK_BUFFER_USAGE_RAYTRACING_BIT_NVX = 0x00000400,
VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkBufferUsageFlagBits;
typedef VkFlags VkBufferUsageFlags;
@ -1495,6 +1545,7 @@ typedef enum VkPipelineCreateFlagBits {
VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004,
VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008,
VK_PIPELINE_CREATE_DISPATCH_BASE = 0x00000010,
VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NVX = 0x00000020,
VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT,
VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE,
VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
@ -1511,6 +1562,14 @@ typedef enum VkShaderStageFlagBits {
VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020,
VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F,
VK_SHADER_STAGE_ALL = 0x7FFFFFFF,
VK_SHADER_STAGE_RAYGEN_BIT_NVX = 0x00000100,
VK_SHADER_STAGE_ANY_HIT_BIT_NVX = 0x00000200,
VK_SHADER_STAGE_CLOSEST_HIT_BIT_NVX = 0x00000400,
VK_SHADER_STAGE_MISS_BIT_NVX = 0x00000800,
VK_SHADER_STAGE_INTERSECTION_BIT_NVX = 0x00001000,
VK_SHADER_STAGE_CALLABLE_BIT_NVX = 0x00002000,
VK_SHADER_STAGE_TASK_BIT_NV = 0x00000040,
VK_SHADER_STAGE_MESH_BIT_NV = 0x00000080,
VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkShaderStageFlagBits;
typedef VkFlags VkPipelineVertexInputStateCreateFlags;
@ -1592,10 +1651,16 @@ typedef enum VkAccessFlagBits {
VK_ACCESS_HOST_WRITE_BIT = 0x00004000,
VK_ACCESS_MEMORY_READ_BIT = 0x00008000,
VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000,
VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000,
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000,
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000,
VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000,
VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 0x00020000,
VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 0x00040000,
VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000,
VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000,
VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NVX = 0x00200000,
VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NVX = 0x00400000,
VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkAccessFlagBits;
typedef VkFlags VkAccessFlags;
@ -4062,6 +4127,8 @@ typedef struct VkMemoryRequirements2 {
VkMemoryRequirements memoryRequirements;
} VkMemoryRequirements2;
typedef VkMemoryRequirements2 VkMemoryRequirements2KHR;
typedef struct VkSparseImageMemoryRequirements2 {
VkStructureType sType;
void* pNext;
@ -5826,8 +5893,6 @@ typedef VkImageMemoryRequirementsInfo2 VkImageMemoryRequirementsInfo2KHR;
typedef VkImageSparseMemoryRequirementsInfo2 VkImageSparseMemoryRequirementsInfo2KHR;
typedef VkMemoryRequirements2 VkMemoryRequirements2KHR;
typedef VkSparseImageMemoryRequirements2 VkSparseImageMemoryRequirements2KHR;
@ -5992,6 +6057,60 @@ typedef struct VkPhysicalDevice8BitStorageFeaturesKHR {
#define VK_KHR_shader_atomic_int64 1
#define VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION 1
#define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME "VK_KHR_shader_atomic_int64"
typedef struct VkPhysicalDeviceShaderAtomicInt64FeaturesKHR {
VkStructureType sType;
void* pNext;
VkBool32 shaderBufferInt64Atomics;
VkBool32 shaderSharedInt64Atomics;
} VkPhysicalDeviceShaderAtomicInt64FeaturesKHR;
#define VK_KHR_driver_properties 1
#define VK_MAX_DRIVER_NAME_SIZE_KHR 256
#define VK_MAX_DRIVER_INFO_SIZE_KHR 256
#define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1
#define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties"
typedef enum VkDriverIdKHR {
VK_DRIVER_ID_AMD_PROPRIETARY_KHR = 1,
VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = 2,
VK_DRIVER_ID_MESA_RADV_KHR = 3,
VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = 4,
VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = 5,
VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = 6,
VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = 7,
VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = 8,
VK_DRIVER_ID_ARM_PROPRIETARY_KHR = 9,
VK_DRIVER_ID_BEGIN_RANGE_KHR = VK_DRIVER_ID_AMD_PROPRIETARY_KHR,
VK_DRIVER_ID_END_RANGE_KHR = VK_DRIVER_ID_ARM_PROPRIETARY_KHR,
VK_DRIVER_ID_RANGE_SIZE_KHR = (VK_DRIVER_ID_ARM_PROPRIETARY_KHR - VK_DRIVER_ID_AMD_PROPRIETARY_KHR + 1),
VK_DRIVER_ID_MAX_ENUM_KHR = 0x7FFFFFFF
} VkDriverIdKHR;
typedef struct VkConformanceVersionKHR {
uint8_t major;
uint8_t minor;
uint8_t subminor;
uint8_t patch;
} VkConformanceVersionKHR;
typedef struct VkPhysicalDeviceDriverPropertiesKHR {
VkStructureType sType;
void* pNext;
uint32_t driverID;
char driverName[VK_MAX_DRIVER_NAME_SIZE_KHR];
char driverInfo[VK_MAX_DRIVER_INFO_SIZE_KHR];
VkConformanceVersionKHR conformanceVersion;
} VkPhysicalDeviceDriverPropertiesKHR;
#define VK_KHR_vulkan_memory_model 1
#define VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION 2
#define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model"
@ -6049,6 +6168,7 @@ typedef enum VkDebugReportObjectTypeEXT {
VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33,
VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000,
VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000,
VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NVX_EXT = 1000165000,
VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT,
VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT,
VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT,
@ -6250,6 +6370,95 @@ typedef struct VkDedicatedAllocationMemoryAllocateInfoNV {
#define VK_EXT_transform_feedback 1
#define VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION 1
#define VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME "VK_EXT_transform_feedback"
typedef VkFlags VkPipelineRasterizationStateStreamCreateFlagsEXT;
typedef struct VkPhysicalDeviceTransformFeedbackFeaturesEXT {
VkStructureType sType;
void* pNext;
VkBool32 transformFeedback;
VkBool32 geometryStreams;
} VkPhysicalDeviceTransformFeedbackFeaturesEXT;
typedef struct VkPhysicalDeviceTransformFeedbackPropertiesEXT {
VkStructureType sType;
void* pNext;
uint32_t maxTransformFeedbackStreams;
uint32_t maxTransformFeedbackBuffers;
VkDeviceSize maxTransformFeedbackBufferSize;
uint32_t maxTransformFeedbackStreamDataSize;
uint32_t maxTransformFeedbackBufferDataSize;
uint32_t maxTransformFeedbackBufferDataStride;
VkBool32 transformFeedbackQueries;
VkBool32 transformFeedbackStreamsLinesTriangles;
VkBool32 transformFeedbackRasterizationStreamSelect;
VkBool32 transformFeedbackDraw;
} VkPhysicalDeviceTransformFeedbackPropertiesEXT;
typedef struct VkPipelineRasterizationStateStreamCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkPipelineRasterizationStateStreamCreateFlagsEXT flags;
uint32_t rasterizationStream;
} VkPipelineRasterizationStateStreamCreateInfoEXT;
typedef void (VKAPI_PTR *PFN_vkCmdBindTransformFeedbackBuffersEXT)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes);
typedef void (VKAPI_PTR *PFN_vkCmdBeginTransformFeedbackEXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets);
typedef void (VKAPI_PTR *PFN_vkCmdEndTransformFeedbackEXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets);
typedef void (VKAPI_PTR *PFN_vkCmdBeginQueryIndexedEXT)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags, uint32_t index);
typedef void (VKAPI_PTR *PFN_vkCmdEndQueryIndexedEXT)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, uint32_t index);
typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectByteCountEXT)(VkCommandBuffer commandBuffer, uint32_t instanceCount, uint32_t firstInstance, VkBuffer counterBuffer, VkDeviceSize counterBufferOffset, uint32_t counterOffset, uint32_t vertexStride);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR void VKAPI_CALL vkCmdBindTransformFeedbackBuffersEXT(
VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer* pBuffers,
const VkDeviceSize* pOffsets,
const VkDeviceSize* pSizes);
VKAPI_ATTR void VKAPI_CALL vkCmdBeginTransformFeedbackEXT(
VkCommandBuffer commandBuffer,
uint32_t firstCounterBuffer,
uint32_t counterBufferCount,
const VkBuffer* pCounterBuffers,
const VkDeviceSize* pCounterBufferOffsets);
VKAPI_ATTR void VKAPI_CALL vkCmdEndTransformFeedbackEXT(
VkCommandBuffer commandBuffer,
uint32_t firstCounterBuffer,
uint32_t counterBufferCount,
const VkBuffer* pCounterBuffers,
const VkDeviceSize* pCounterBufferOffsets);
VKAPI_ATTR void VKAPI_CALL vkCmdBeginQueryIndexedEXT(
VkCommandBuffer commandBuffer,
VkQueryPool queryPool,
uint32_t query,
VkQueryControlFlags flags,
uint32_t index);
VKAPI_ATTR void VKAPI_CALL vkCmdEndQueryIndexedEXT(
VkCommandBuffer commandBuffer,
VkQueryPool queryPool,
uint32_t query,
uint32_t index);
VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectByteCountEXT(
VkCommandBuffer commandBuffer,
uint32_t instanceCount,
uint32_t firstInstance,
VkBuffer counterBuffer,
VkDeviceSize counterBufferOffset,
uint32_t counterOffset,
uint32_t vertexStride);
#endif
#define VK_AMD_draw_indirect_count 1
#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 1
#define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count"
@ -6355,6 +6564,18 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderInfoAMD(
#define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME "VK_AMD_shader_image_load_store_lod"
#define VK_NV_corner_sampled_image 1
#define VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION 2
#define VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME "VK_NV_corner_sampled_image"
typedef struct VkPhysicalDeviceCornerSampledImageFeaturesNV {
VkStructureType sType;
void* pNext;
VkBool32 cornerSampledImage;
} VkPhysicalDeviceCornerSampledImageFeaturesNV;
#define VK_IMG_format_pvrtc 1
#define VK_IMG_FORMAT_PVRTC_SPEC_VERSION 1
#define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc"
@ -7711,6 +7932,397 @@ typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupportEXT {
#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer"
#define VK_NV_shading_rate_image 1
#define VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION 3
#define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image"
typedef enum VkShadingRatePaletteEntryNV {
VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV = 0,
VK_SHADING_RATE_PALETTE_ENTRY_16_INVOCATIONS_PER_PIXEL_NV = 1,
VK_SHADING_RATE_PALETTE_ENTRY_8_INVOCATIONS_PER_PIXEL_NV = 2,
VK_SHADING_RATE_PALETTE_ENTRY_4_INVOCATIONS_PER_PIXEL_NV = 3,
VK_SHADING_RATE_PALETTE_ENTRY_2_INVOCATIONS_PER_PIXEL_NV = 4,
VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV = 5,
VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV = 6,
VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV = 7,
VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV = 8,
VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV = 9,
VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV = 10,
VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV = 11,
VK_SHADING_RATE_PALETTE_ENTRY_BEGIN_RANGE_NV = VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV,
VK_SHADING_RATE_PALETTE_ENTRY_END_RANGE_NV = VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV,
VK_SHADING_RATE_PALETTE_ENTRY_RANGE_SIZE_NV = (VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV - VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV + 1),
VK_SHADING_RATE_PALETTE_ENTRY_MAX_ENUM_NV = 0x7FFFFFFF
} VkShadingRatePaletteEntryNV;
typedef enum VkCoarseSampleOrderTypeNV {
VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV = 0,
VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV = 1,
VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV = 2,
VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV = 3,
VK_COARSE_SAMPLE_ORDER_TYPE_BEGIN_RANGE_NV = VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV,
VK_COARSE_SAMPLE_ORDER_TYPE_END_RANGE_NV = VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV,
VK_COARSE_SAMPLE_ORDER_TYPE_RANGE_SIZE_NV = (VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV - VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV + 1),
VK_COARSE_SAMPLE_ORDER_TYPE_MAX_ENUM_NV = 0x7FFFFFFF
} VkCoarseSampleOrderTypeNV;
typedef struct VkShadingRatePaletteNV {
uint32_t shadingRatePaletteEntryCount;
const VkShadingRatePaletteEntryNV* pShadingRatePaletteEntries;
} VkShadingRatePaletteNV;
typedef struct VkPipelineViewportShadingRateImageStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkBool32 shadingRateImageEnable;
uint32_t viewportCount;
const VkShadingRatePaletteNV* pShadingRatePalettes;
} VkPipelineViewportShadingRateImageStateCreateInfoNV;
typedef struct VkPhysicalDeviceShadingRateImageFeaturesNV {
VkStructureType sType;
void* pNext;
VkBool32 shadingRateImage;
VkBool32 shadingRateCoarseSampleOrder;
} VkPhysicalDeviceShadingRateImageFeaturesNV;
typedef struct VkPhysicalDeviceShadingRateImagePropertiesNV {
VkStructureType sType;
void* pNext;
VkExtent2D shadingRateTexelSize;
uint32_t shadingRatePaletteSize;
uint32_t shadingRateMaxCoarseSamples;
} VkPhysicalDeviceShadingRateImagePropertiesNV;
typedef struct VkCoarseSampleLocationNV {
uint32_t pixelX;
uint32_t pixelY;
uint32_t sample;
} VkCoarseSampleLocationNV;
typedef struct VkCoarseSampleOrderCustomNV {
VkShadingRatePaletteEntryNV shadingRate;
uint32_t sampleCount;
uint32_t sampleLocationCount;
const VkCoarseSampleLocationNV* pSampleLocations;
} VkCoarseSampleOrderCustomNV;
typedef struct VkPipelineViewportCoarseSampleOrderStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkCoarseSampleOrderTypeNV sampleOrderType;
uint32_t customSampleOrderCount;
const VkCoarseSampleOrderCustomNV* pCustomSampleOrders;
} VkPipelineViewportCoarseSampleOrderStateCreateInfoNV;
typedef void (VKAPI_PTR *PFN_vkCmdBindShadingRateImageNV)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout);
typedef void (VKAPI_PTR *PFN_vkCmdSetViewportShadingRatePaletteNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkShadingRatePaletteNV* pShadingRatePalettes);
typedef void (VKAPI_PTR *PFN_vkCmdSetCoarseSampleOrderNV)(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, uint32_t customSampleOrderCount, const VkCoarseSampleOrderCustomNV* pCustomSampleOrders);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR void VKAPI_CALL vkCmdBindShadingRateImageNV(
VkCommandBuffer commandBuffer,
VkImageView imageView,
VkImageLayout imageLayout);
VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportShadingRatePaletteNV(
VkCommandBuffer commandBuffer,
uint32_t firstViewport,
uint32_t viewportCount,
const VkShadingRatePaletteNV* pShadingRatePalettes);
VKAPI_ATTR void VKAPI_CALL vkCmdSetCoarseSampleOrderNV(
VkCommandBuffer commandBuffer,
VkCoarseSampleOrderTypeNV sampleOrderType,
uint32_t customSampleOrderCount,
const VkCoarseSampleOrderCustomNV* pCustomSampleOrders);
#endif
#define VK_NVX_raytracing 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNVX)
#define VK_NVX_RAYTRACING_SPEC_VERSION 1
#define VK_NVX_RAYTRACING_EXTENSION_NAME "VK_NVX_raytracing"
typedef enum VkGeometryTypeNVX {
VK_GEOMETRY_TYPE_TRIANGLES_NVX = 0,
VK_GEOMETRY_TYPE_AABBS_NVX = 1,
VK_GEOMETRY_TYPE_BEGIN_RANGE_NVX = VK_GEOMETRY_TYPE_TRIANGLES_NVX,
VK_GEOMETRY_TYPE_END_RANGE_NVX = VK_GEOMETRY_TYPE_AABBS_NVX,
VK_GEOMETRY_TYPE_RANGE_SIZE_NVX = (VK_GEOMETRY_TYPE_AABBS_NVX - VK_GEOMETRY_TYPE_TRIANGLES_NVX + 1),
VK_GEOMETRY_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF
} VkGeometryTypeNVX;
typedef enum VkAccelerationStructureTypeNVX {
VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NVX = 0,
VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NVX = 1,
VK_ACCELERATION_STRUCTURE_TYPE_BEGIN_RANGE_NVX = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NVX,
VK_ACCELERATION_STRUCTURE_TYPE_END_RANGE_NVX = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NVX,
VK_ACCELERATION_STRUCTURE_TYPE_RANGE_SIZE_NVX = (VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NVX - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NVX + 1),
VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF
} VkAccelerationStructureTypeNVX;
typedef enum VkCopyAccelerationStructureModeNVX {
VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NVX = 0,
VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NVX = 1,
VK_COPY_ACCELERATION_STRUCTURE_MODE_BEGIN_RANGE_NVX = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NVX,
VK_COPY_ACCELERATION_STRUCTURE_MODE_END_RANGE_NVX = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NVX,
VK_COPY_ACCELERATION_STRUCTURE_MODE_RANGE_SIZE_NVX = (VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NVX - VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NVX + 1),
VK_COPY_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_NVX = 0x7FFFFFFF
} VkCopyAccelerationStructureModeNVX;
typedef enum VkGeometryFlagBitsNVX {
VK_GEOMETRY_OPAQUE_BIT_NVX = 0x00000001,
VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NVX = 0x00000002,
VK_GEOMETRY_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF
} VkGeometryFlagBitsNVX;
typedef VkFlags VkGeometryFlagsNVX;
typedef enum VkGeometryInstanceFlagBitsNVX {
VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NVX = 0x00000001,
VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_FLIP_WINDING_BIT_NVX = 0x00000002,
VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NVX = 0x00000004,
VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NVX = 0x00000008,
VK_GEOMETRY_INSTANCE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF
} VkGeometryInstanceFlagBitsNVX;
typedef VkFlags VkGeometryInstanceFlagsNVX;
typedef enum VkBuildAccelerationStructureFlagBitsNVX {
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NVX = 0x00000001,
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NVX = 0x00000002,
VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NVX = 0x00000004,
VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NVX = 0x00000008,
VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NVX = 0x00000010,
VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF
} VkBuildAccelerationStructureFlagBitsNVX;
typedef VkFlags VkBuildAccelerationStructureFlagsNVX;
typedef struct VkRaytracingPipelineCreateInfoNVX {
VkStructureType sType;
const void* pNext;
VkPipelineCreateFlags flags;
uint32_t stageCount;
const VkPipelineShaderStageCreateInfo* pStages;
const uint32_t* pGroupNumbers;
uint32_t maxRecursionDepth;
VkPipelineLayout layout;
VkPipeline basePipelineHandle;
int32_t basePipelineIndex;
} VkRaytracingPipelineCreateInfoNVX;
typedef struct VkGeometryTrianglesNVX {
VkStructureType sType;
const void* pNext;
VkBuffer vertexData;
VkDeviceSize vertexOffset;
uint32_t vertexCount;
VkDeviceSize vertexStride;
VkFormat vertexFormat;
VkBuffer indexData;
VkDeviceSize indexOffset;
uint32_t indexCount;
VkIndexType indexType;
VkBuffer transformData;
VkDeviceSize transformOffset;
} VkGeometryTrianglesNVX;
typedef struct VkGeometryAABBNVX {
VkStructureType sType;
const void* pNext;
VkBuffer aabbData;
uint32_t numAABBs;
uint32_t stride;
VkDeviceSize offset;
} VkGeometryAABBNVX;
typedef struct VkGeometryDataNVX {
VkGeometryTrianglesNVX triangles;
VkGeometryAABBNVX aabbs;
} VkGeometryDataNVX;
typedef struct VkGeometryNVX {
VkStructureType sType;
const void* pNext;
VkGeometryTypeNVX geometryType;
VkGeometryDataNVX geometry;
VkGeometryFlagsNVX flags;
} VkGeometryNVX;
typedef struct VkAccelerationStructureCreateInfoNVX {
VkStructureType sType;
const void* pNext;
VkAccelerationStructureTypeNVX type;
VkBuildAccelerationStructureFlagsNVX flags;
VkDeviceSize compactedSize;
uint32_t instanceCount;
uint32_t geometryCount;
const VkGeometryNVX* pGeometries;
} VkAccelerationStructureCreateInfoNVX;
typedef struct VkBindAccelerationStructureMemoryInfoNVX {
VkStructureType sType;
const void* pNext;
VkAccelerationStructureNVX accelerationStructure;
VkDeviceMemory memory;
VkDeviceSize memoryOffset;
uint32_t deviceIndexCount;
const uint32_t* pDeviceIndices;
} VkBindAccelerationStructureMemoryInfoNVX;
typedef struct VkDescriptorAccelerationStructureInfoNVX {
VkStructureType sType;
const void* pNext;
uint32_t accelerationStructureCount;
const VkAccelerationStructureNVX* pAccelerationStructures;
} VkDescriptorAccelerationStructureInfoNVX;
typedef struct VkAccelerationStructureMemoryRequirementsInfoNVX {
VkStructureType sType;
const void* pNext;
VkAccelerationStructureNVX accelerationStructure;
} VkAccelerationStructureMemoryRequirementsInfoNVX;
typedef struct VkPhysicalDeviceRaytracingPropertiesNVX {
VkStructureType sType;
void* pNext;
uint32_t shaderHeaderSize;
uint32_t maxRecursionDepth;
uint32_t maxGeometryCount;
} VkPhysicalDeviceRaytracingPropertiesNVX;
typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureNVX)(VkDevice device, const VkAccelerationStructureCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNVX* pAccelerationStructure);
typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureNVX)(VkDevice device, VkAccelerationStructureNVX accelerationStructure, const VkAllocationCallbacks* pAllocator);
typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsNVX)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNVX* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements);
typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureScratchMemoryRequirementsNVX)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNVX* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements);
typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryNVX)(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNVX* pBindInfos);
typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureNVX)(VkCommandBuffer commandBuffer, VkAccelerationStructureTypeNVX type, uint32_t instanceCount, VkBuffer instanceData, VkDeviceSize instanceOffset, uint32_t geometryCount, const VkGeometryNVX* pGeometries, VkBuildAccelerationStructureFlagsNVX flags, VkBool32 update, VkAccelerationStructureNVX dst, VkAccelerationStructureNVX src, VkBuffer scratch, VkDeviceSize scratchOffset);
typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNVX)(VkCommandBuffer commandBuffer, VkAccelerationStructureNVX dst, VkAccelerationStructureNVX src, VkCopyAccelerationStructureModeNVX mode);
typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysNVX)(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer, VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer, VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride, VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset, VkDeviceSize hitShaderBindingStride, uint32_t width, uint32_t height);
typedef VkResult (VKAPI_PTR *PFN_vkCreateRaytracingPipelinesNVX)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRaytracingPipelineCreateInfoNVX* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
typedef VkResult (VKAPI_PTR *PFN_vkGetRaytracingShaderHandlesNVX)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData);
typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureHandleNVX)(VkDevice device, VkAccelerationStructureNVX accelerationStructure, size_t dataSize, void* pData);
typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructurePropertiesNVX)(VkCommandBuffer commandBuffer, VkAccelerationStructureNVX accelerationStructure, VkQueryType queryType, VkQueryPool queryPool, uint32_t query);
typedef VkResult (VKAPI_PTR *PFN_vkCompileDeferredNVX)(VkDevice device, VkPipeline pipeline, uint32_t shader);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureNVX(
VkDevice device,
const VkAccelerationStructureCreateInfoNVX* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkAccelerationStructureNVX* pAccelerationStructure);
VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureNVX(
VkDevice device,
VkAccelerationStructureNVX accelerationStructure,
const VkAllocationCallbacks* pAllocator);
VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureMemoryRequirementsNVX(
VkDevice device,
const VkAccelerationStructureMemoryRequirementsInfoNVX* pInfo,
VkMemoryRequirements2KHR* pMemoryRequirements);
VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureScratchMemoryRequirementsNVX(
VkDevice device,
const VkAccelerationStructureMemoryRequirementsInfoNVX* pInfo,
VkMemoryRequirements2KHR* pMemoryRequirements);
VKAPI_ATTR VkResult VKAPI_CALL vkBindAccelerationStructureMemoryNVX(
VkDevice device,
uint32_t bindInfoCount,
const VkBindAccelerationStructureMemoryInfoNVX* pBindInfos);
VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureNVX(
VkCommandBuffer commandBuffer,
VkAccelerationStructureTypeNVX type,
uint32_t instanceCount,
VkBuffer instanceData,
VkDeviceSize instanceOffset,
uint32_t geometryCount,
const VkGeometryNVX* pGeometries,
VkBuildAccelerationStructureFlagsNVX flags,
VkBool32 update,
VkAccelerationStructureNVX dst,
VkAccelerationStructureNVX src,
VkBuffer scratch,
VkDeviceSize scratchOffset);
VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureNVX(
VkCommandBuffer commandBuffer,
VkAccelerationStructureNVX dst,
VkAccelerationStructureNVX src,
VkCopyAccelerationStructureModeNVX mode);
VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysNVX(
VkCommandBuffer commandBuffer,
VkBuffer raygenShaderBindingTableBuffer,
VkDeviceSize raygenShaderBindingOffset,
VkBuffer missShaderBindingTableBuffer,
VkDeviceSize missShaderBindingOffset,
VkDeviceSize missShaderBindingStride,
VkBuffer hitShaderBindingTableBuffer,
VkDeviceSize hitShaderBindingOffset,
VkDeviceSize hitShaderBindingStride,
uint32_t width,
uint32_t height);
VKAPI_ATTR VkResult VKAPI_CALL vkCreateRaytracingPipelinesNVX(
VkDevice device,
VkPipelineCache pipelineCache,
uint32_t createInfoCount,
const VkRaytracingPipelineCreateInfoNVX* pCreateInfos,
const VkAllocationCallbacks* pAllocator,
VkPipeline* pPipelines);
VKAPI_ATTR VkResult VKAPI_CALL vkGetRaytracingShaderHandlesNVX(
VkDevice device,
VkPipeline pipeline,
uint32_t firstGroup,
uint32_t groupCount,
size_t dataSize,
void* pData);
VKAPI_ATTR VkResult VKAPI_CALL vkGetAccelerationStructureHandleNVX(
VkDevice device,
VkAccelerationStructureNVX accelerationStructure,
size_t dataSize,
void* pData);
VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructurePropertiesNVX(
VkCommandBuffer commandBuffer,
VkAccelerationStructureNVX accelerationStructure,
VkQueryType queryType,
VkQueryPool queryPool,
uint32_t query);
VKAPI_ATTR VkResult VKAPI_CALL vkCompileDeferredNVX(
VkDevice device,
VkPipeline pipeline,
uint32_t shader);
#endif
#define VK_NV_representative_fragment_test 1
#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 1
#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME "VK_NV_representative_fragment_test"
typedef struct VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV {
VkStructureType sType;
void* pNext;
VkBool32 representativeFragmentTest;
} VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV;
typedef struct VkPipelineRepresentativeFragmentTestStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkBool32 representativeFragmentTestEnable;
} VkPipelineRepresentativeFragmentTestStateCreateInfoNV;
#define VK_EXT_global_priority 1
#define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2
#define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority"
@ -7845,6 +8457,133 @@ typedef struct VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT {
#define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned"
#define VK_NV_compute_shader_derivatives 1
#define VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION 1
#define VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_NV_compute_shader_derivatives"
typedef struct VkPhysicalDeviceComputeShaderDerivativesFeaturesNV {
VkStructureType sType;
void* pNext;
VkBool32 computeDerivativeGroupQuads;
VkBool32 computeDerivativeGroupLinear;
} VkPhysicalDeviceComputeShaderDerivativesFeaturesNV;
#define VK_NV_mesh_shader 1
#define VK_NV_MESH_SHADER_SPEC_VERSION 1
#define VK_NV_MESH_SHADER_EXTENSION_NAME "VK_NV_mesh_shader"
typedef struct VkPhysicalDeviceMeshShaderFeaturesNV {
VkStructureType sType;
void* pNext;
VkBool32 taskShader;
VkBool32 meshShader;
} VkPhysicalDeviceMeshShaderFeaturesNV;
typedef struct VkPhysicalDeviceMeshShaderPropertiesNV {
VkStructureType sType;
void* pNext;
uint32_t maxDrawMeshTasksCount;
uint32_t maxTaskWorkGroupInvocations;
uint32_t maxTaskWorkGroupSize[3];
uint32_t maxTaskTotalMemorySize;
uint32_t maxTaskOutputCount;
uint32_t maxMeshWorkGroupInvocations;
uint32_t maxMeshWorkGroupSize[3];
uint32_t maxMeshTotalMemorySize;
uint32_t maxMeshOutputVertices;
uint32_t maxMeshOutputPrimitives;
uint32_t maxMeshMultiviewViewCount;
uint32_t meshOutputPerVertexGranularity;
uint32_t meshOutputPerPrimitiveGranularity;
} VkPhysicalDeviceMeshShaderPropertiesNV;
typedef struct VkDrawMeshTasksIndirectCommandNV {
uint32_t taskCount;
uint32_t firstTask;
} VkDrawMeshTasksIndirectCommandNV;
typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksNV)(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask);
typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCountNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksNV(
VkCommandBuffer commandBuffer,
uint32_t taskCount,
uint32_t firstTask);
VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectNV(
VkCommandBuffer commandBuffer,
VkBuffer buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride);
VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountNV(
VkCommandBuffer commandBuffer,
VkBuffer buffer,
VkDeviceSize offset,
VkBuffer countBuffer,
VkDeviceSize countBufferOffset,
uint32_t maxDrawCount,
uint32_t stride);
#endif
#define VK_NV_fragment_shader_barycentric 1
#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1
#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_NV_fragment_shader_barycentric"
typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV {
VkStructureType sType;
void* pNext;
VkBool32 fragmentShaderBarycentric;
} VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV;
#define VK_NV_shader_image_footprint 1
#define VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION 1
#define VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME "VK_NV_shader_image_footprint"
typedef struct VkPhysicalDeviceShaderImageFootprintFeaturesNV {
VkStructureType sType;
void* pNext;
VkBool32 imageFootprint;
} VkPhysicalDeviceShaderImageFootprintFeaturesNV;
#define VK_NV_scissor_exclusive 1
#define VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION 1
#define VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME "VK_NV_scissor_exclusive"
typedef struct VkPipelineViewportExclusiveScissorStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
uint32_t exclusiveScissorCount;
const VkRect2D* pExclusiveScissors;
} VkPipelineViewportExclusiveScissorStateCreateInfoNV;
typedef struct VkPhysicalDeviceExclusiveScissorFeaturesNV {
VkStructureType sType;
void* pNext;
VkBool32 exclusiveScissor;
} VkPhysicalDeviceExclusiveScissorFeaturesNV;
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 vkCmdSetExclusiveScissorNV(
VkCommandBuffer commandBuffer,
uint32_t firstExclusiveScissor,
uint32_t exclusiveScissorCount,
const VkRect2D* pExclusiveScissors);
#endif
#define VK_NV_device_diagnostic_checkpoints 1
#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION 2
#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME "VK_NV_device_diagnostic_checkpoints"

View File

@ -1671,7 +1671,10 @@ namespace dxvk {
D3D10DeviceLock lock = LockDevice();
ID3D11Buffer* d3d11Buffers[D3D10_SO_BUFFER_SLOT_COUNT];
m_context->SOGetTargets(NumBuffers, ppSOTargets ? d3d11Buffers : nullptr);
m_context->SOGetTargetsWithOffsets(NumBuffers,
ppSOTargets ? d3d11Buffers : nullptr,
pOffsets);
if (ppSOTargets != nullptr) {
for (uint32_t i = 0; i < NumBuffers; i++) {
@ -1680,9 +1683,6 @@ namespace dxvk {
: nullptr;
}
}
if (pOffsets != nullptr)
Logger::warn("D3D10: SOGetTargets: Reporting buffer offsets not supported");
}

View File

@ -11,15 +11,99 @@ namespace dxvk {
const D3D11_BUFFER_DESC* pDesc)
: m_device (pDevice),
m_desc (*pDesc),
m_buffer (CreateBuffer(pDesc)),
m_mappedSlice (m_buffer->slice()),
m_d3d10 (this, pDevice->GetD3D10Interface()) {
DxvkBufferCreateInfo info;
info.size = pDesc->ByteWidth;
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT;
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
info.access = VK_ACCESS_TRANSFER_READ_BIT
| VK_ACCESS_TRANSFER_WRITE_BIT;
if (pDesc->BindFlags & D3D11_BIND_VERTEX_BUFFER) {
info.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
info.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
info.access |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
}
if (pDesc->BindFlags & D3D11_BIND_INDEX_BUFFER) {
info.usage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
info.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
info.access |= VK_ACCESS_INDEX_READ_BIT;
}
if (pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER) {
info.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
info.stages |= m_device->GetEnabledShaderStages();
info.access |= VK_ACCESS_UNIFORM_READ_BIT;
}
if (pDesc->BindFlags & D3D11_BIND_SHADER_RESOURCE) {
info.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
info.stages |= m_device->GetEnabledShaderStages();
info.access |= VK_ACCESS_SHADER_READ_BIT;
}
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT) {
info.usage |= VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
info.stages |= VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
info.access |= VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT;
}
if (pDesc->BindFlags & D3D11_BIND_UNORDERED_ACCESS) {
info.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
info.stages |= m_device->GetEnabledShaderStages();
info.access |= VK_ACCESS_SHADER_READ_BIT
| VK_ACCESS_SHADER_WRITE_BIT;
}
if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_WRITE) {
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
info.access |= VK_ACCESS_HOST_WRITE_BIT;
}
if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_READ) {
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
info.access |= VK_ACCESS_HOST_READ_BIT;
}
if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS) {
info.usage |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
info.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
info.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
}
// Default constant buffers may get updated frequently, in which
// case mapping the buffer is faster than using update commands.
VkMemoryPropertyFlags memoryFlags = GetMemoryFlagsForUsage(pDesc->Usage);
if ((pDesc->Usage == D3D11_USAGE_DEFAULT) && (pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER)) {
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
info.access |= VK_ACCESS_HOST_WRITE_BIT;
memoryFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
}
// AMD cards have a device-local, host-visible memory type where
// we can put dynamic resources that need fast access by the GPU
if (pDesc->Usage == D3D11_USAGE_DYNAMIC && pDesc->BindFlags)
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
// Create the buffer and set the entire buffer slice as mapped,
// so that we only have to update it when invalidating th buffer
m_buffer = m_device->GetDXVKDevice()->createBuffer(info, memoryFlags);
m_mapped = m_buffer->slice();
// For Stream Output buffers we need a counter
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT)
m_soCounter = m_device->AllocXfbCounterSlice();
}
D3D11Buffer::~D3D11Buffer() {
if (m_soCounter.defined())
m_device->FreeXfbCounterSlice(m_soCounter);
}
@ -95,88 +179,6 @@ namespace dxvk {
}
Rc<DxvkBuffer> D3D11Buffer::CreateBuffer(
const D3D11_BUFFER_DESC* pDesc) const {
DxvkBufferCreateInfo info;
info.size = pDesc->ByteWidth;
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT;
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
info.access = VK_ACCESS_TRANSFER_READ_BIT
| VK_ACCESS_TRANSFER_WRITE_BIT;
if (pDesc->BindFlags & D3D11_BIND_VERTEX_BUFFER) {
info.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
info.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
info.access |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
}
if (pDesc->BindFlags & D3D11_BIND_INDEX_BUFFER) {
info.usage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
info.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
info.access |= VK_ACCESS_INDEX_READ_BIT;
}
if (pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER) {
info.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
info.stages |= m_device->GetEnabledShaderStages();
info.access |= VK_ACCESS_UNIFORM_READ_BIT;
}
if (pDesc->BindFlags & D3D11_BIND_SHADER_RESOURCE) {
info.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
info.stages |= m_device->GetEnabledShaderStages();
info.access |= VK_ACCESS_SHADER_READ_BIT;
}
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT) {
Logger::err("D3D11Device::CreateBuffer: D3D11_BIND_STREAM_OUTPUT not supported");
}
if (pDesc->BindFlags & D3D11_BIND_UNORDERED_ACCESS) {
info.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
info.stages |= m_device->GetEnabledShaderStages();
info.access |= VK_ACCESS_SHADER_READ_BIT
| VK_ACCESS_SHADER_WRITE_BIT;
}
if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_WRITE) {
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
info.access |= VK_ACCESS_HOST_WRITE_BIT;
}
if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_READ) {
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
info.access |= VK_ACCESS_HOST_READ_BIT;
}
if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS) {
info.usage |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
info.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
info.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
}
// Default constant buffers may get updated frequently, in which
// case mapping the buffer is faster than using update commands.
VkMemoryPropertyFlags memoryFlags = GetMemoryFlagsForUsage(pDesc->Usage);
if ((pDesc->Usage == D3D11_USAGE_DEFAULT) && (pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER)) {
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
info.access |= VK_ACCESS_HOST_WRITE_BIT;
memoryFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
}
// AMD cards have a device-local, host-visible memory type where
// we can put dynamic resources that need fast access by the GPU
if (pDesc->Usage == D3D11_USAGE_DYNAMIC && pDesc->BindFlags)
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
return m_device->GetDXVKDevice()->createBuffer(info, memoryFlags);
}
BOOL D3D11Buffer::CheckFormatFeatureSupport(
VkFormat Format,
VkFormatFeatureFlags Features) const {

View File

@ -11,6 +11,18 @@ namespace dxvk {
class D3D11Device;
class D3D11DeviceContext;
/**
* \brief Stream output buffer offset
*
* A byte offset into the buffer that
* stores the byte offset where new
* data will be written to.
*/
struct D3D11SOCounter {
uint32_t byteOffset;
};
class D3D11Buffer : public D3D11DeviceChild<ID3D11Buffer> {
@ -62,17 +74,21 @@ namespace dxvk {
DxvkBufferSlice GetBufferSlice(VkDeviceSize offset, VkDeviceSize length) const {
return DxvkBufferSlice(m_buffer, offset, length);
}
DxvkBufferSlice GetSOCounter() {
return m_soCounter;
}
VkDeviceSize GetSize() const {
return m_buffer->info().size;
}
DxvkPhysicalBufferSlice GetMappedSlice() const {
return m_mappedSlice;
return m_mapped;
}
void SetMappedSlice(const DxvkPhysicalBufferSlice& slice) {
m_mappedSlice = slice;
m_mapped = slice;
}
D3D10Buffer* GetD3D10Iface() {
@ -85,12 +101,10 @@ namespace dxvk {
const D3D11_BUFFER_DESC m_desc;
Rc<DxvkBuffer> m_buffer;
DxvkPhysicalBufferSlice m_mappedSlice;
DxvkBufferSlice m_soCounter;
DxvkPhysicalBufferSlice m_mapped;
D3D10Buffer m_d3d10;
Rc<DxvkBuffer> CreateBuffer(
const D3D11_BUFFER_DESC* pDesc) const;
BOOL CheckFormatFeatureSupport(
VkFormat Format,

View File

@ -208,8 +208,10 @@ namespace dxvk {
}
// Default SO state
for (uint32_t i = 0; i < D3D11_SO_STREAM_COUNT; i++)
m_state.so.targets[i] = nullptr;
for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) {
m_state.so.targets[i].buffer = nullptr;
m_state.so.targets[i].offset = 0;
}
// Default predication
m_state.pr.predicateObject = nullptr;
@ -1265,7 +1267,22 @@ namespace dxvk {
void STDMETHODCALLTYPE D3D11DeviceContext::DrawAuto() {
Logger::err("D3D11DeviceContext::DrawAuto: Not implemented");
D3D11Buffer* buffer = m_state.ia.vertexBuffers[0].buffer.ptr();
if (buffer == nullptr)
return;
DxvkBufferSlice vtxBuf = buffer->GetBufferSlice();
DxvkBufferSlice ctrBuf = buffer->GetSOCounter();
if (!ctrBuf.defined())
return;
EmitCs([=] (DxvkContext* ctx) {
ctx->drawIndirectXfb(ctrBuf,
vtxBuf.buffer()->getXfbVertexStride(),
0); // FIXME offset?
});
}
@ -2509,17 +2526,29 @@ namespace dxvk {
*pNumRects = m_state.rs.numScissors;
}
void STDMETHODCALLTYPE D3D11DeviceContext::SOSetTargets(
UINT NumBuffers,
ID3D11Buffer* const* ppSOTargets,
const UINT* pOffsets) {
// TODO implement properly, including pOffsets
for (uint32_t i = 0; i < D3D11_SO_STREAM_COUNT; i++) {
m_state.so.targets[i] = (ppSOTargets != nullptr && i < NumBuffers)
? static_cast<D3D11Buffer*>(ppSOTargets[i])
: nullptr;
for (uint32_t i = 0; i < NumBuffers; i++) {
D3D11Buffer* buffer = static_cast<D3D11Buffer*>(ppSOTargets[i]);
UINT offset = pOffsets != nullptr ? pOffsets[i] : 0;
m_state.so.targets[i].buffer = buffer;
m_state.so.targets[i].offset = offset;
}
for (uint32_t i = NumBuffers; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) {
m_state.so.targets[i].buffer = nullptr;
m_state.so.targets[i].offset = 0;
}
for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) {
BindXfbBuffer(i,
m_state.so.targets[i].buffer.ptr(),
m_state.so.targets[i].offset);
}
}
@ -2528,10 +2557,24 @@ namespace dxvk {
UINT NumBuffers,
ID3D11Buffer** ppSOTargets) {
for (uint32_t i = 0; i < NumBuffers; i++)
ppSOTargets[i] = m_state.so.targets[i].ref();
ppSOTargets[i] = m_state.so.targets[i].buffer.ref();
}
void STDMETHODCALLTYPE D3D11DeviceContext::SOGetTargetsWithOffsets(
UINT NumBuffers,
ID3D11Buffer** ppSOTargets,
UINT* pOffsets) {
for (uint32_t i = 0; i < NumBuffers; i++) {
if (ppSOTargets != nullptr)
ppSOTargets[i] = m_state.so.targets[i].buffer.ref();
if (pOffsets != nullptr)
pOffsets[i] = m_state.so.targets[i].offset;
}
}
void STDMETHODCALLTYPE D3D11DeviceContext::TransitionSurfaceLayout(
IDXGIVkInteropSurface* pSurface,
const VkImageSubresourceRange* pSubresources,
@ -2862,7 +2905,38 @@ namespace dxvk {
});
}
void D3D11DeviceContext::BindXfbBuffer(
UINT Slot,
D3D11Buffer* pBuffer,
UINT Offset) {
DxvkBufferSlice bufferSlice;
DxvkBufferSlice counterSlice;
if (pBuffer != nullptr) {
bufferSlice = pBuffer->GetBufferSlice();
counterSlice = pBuffer->GetSOCounter();
}
EmitCs([
cSlotId = Slot,
cOffset = Offset,
cBufferSlice = bufferSlice,
cCounterSlice = counterSlice
] (DxvkContext* ctx) {
if (cCounterSlice.defined() && cOffset != ~0u) {
ctx->updateBuffer(
cCounterSlice.buffer(),
cCounterSlice.offset(),
sizeof(cOffset),
&cOffset);
}
ctx->bindXfbBuffer(cSlotId, cBufferSlice, cCounterSlice);
});
}
void D3D11DeviceContext::BindConstantBuffer(
UINT Slot,
const D3D11ConstantBufferBinding* pBufferBinding) {
@ -3141,6 +3215,9 @@ namespace dxvk {
m_state.ia.vertexBuffers[i].offset,
m_state.ia.vertexBuffers[i].stride);
}
for (uint32_t i = 0; i < m_state.so.targets.size(); i++)
BindXfbBuffer(i, m_state.so.targets[i].buffer.ptr(), ~0u);
RestoreConstantBuffers(DxbcProgramType::VertexShader, m_state.vs.constantBuffers);
RestoreConstantBuffers(DxbcProgramType::HullShader, m_state.hs.constantBuffers);

View File

@ -631,6 +631,11 @@ namespace dxvk {
UINT NumBuffers,
ID3D11Buffer** ppSOTargets) final;
void STDMETHODCALLTYPE SOGetTargetsWithOffsets(
UINT NumBuffers,
ID3D11Buffer** ppSOTargets,
UINT* pOffsets);
void STDMETHODCALLTYPE TransitionSurfaceLayout(
IDXGIVkInteropSurface* pSurface,
const VkImageSubresourceRange* pSubresources,
@ -690,6 +695,11 @@ namespace dxvk {
UINT Offset,
DXGI_FORMAT Format);
void BindXfbBuffer(
UINT Slot,
D3D11Buffer* pBuffer,
UINT Offset);
void BindConstantBuffer(
UINT Slot,
const D3D11ConstantBufferBinding* pBufferBinding);

View File

@ -139,10 +139,16 @@ namespace dxvk {
Com<D3D11RasterizerState> state;
};
struct D3D11ContextSoTarget {
Com<D3D11Buffer> buffer;
UINT offset;
};
struct D3D11ContextStateSO {
std::array<Com<D3D11Buffer>, D3D11_SO_STREAM_COUNT> targets;
std::array<D3D11ContextSoTarget, D3D11_SO_BUFFER_SLOT_COUNT> targets;
};

View File

@ -117,6 +117,7 @@ namespace dxvk {
m_d3d10Device = new D3D10Device(this, m_context);
m_uavCounters = CreateUAVCounterBuffer();
m_xfbCounters = CreateXFBCounterBuffer();
}
@ -622,6 +623,7 @@ namespace dxvk {
DxbcModuleInfo moduleInfo;
moduleInfo.options = m_dxbcOptions;
moduleInfo.tess = nullptr;
moduleInfo.xfb = nullptr;
if (FAILED(this->CreateShaderModule(&module,
pShaderBytecode, BytecodeLength, pClassLinkage,
@ -647,6 +649,7 @@ namespace dxvk {
DxbcModuleInfo moduleInfo;
moduleInfo.options = m_dxbcOptions;
moduleInfo.tess = nullptr;
moduleInfo.xfb = nullptr;
if (FAILED(this->CreateShaderModule(&module,
pShaderBytecode, BytecodeLength, pClassLinkage,
@ -672,11 +675,75 @@ namespace dxvk {
ID3D11ClassLinkage* pClassLinkage,
ID3D11GeometryShader** ppGeometryShader) {
InitReturnPtr(ppGeometryShader);
Logger::err("D3D11Device::CreateGeometryShaderWithStreamOutput: Not implemented");
D3D11CommonShader module;
if (!m_dxvkDevice->features().extTransformFeedback.transformFeedback) {
Logger::err(
"D3D11: CreateGeometryShaderWithStreamOutput:"
"\n Transform feedback not supoorted by device");
return m_d3d11Options.fakeStreamOutSupport ? S_OK : E_NOTIMPL;
}
// Zero-init some counterss so that we can increment
// them while walking over the stream output entries
DxbcXfbInfo xfb;
xfb.entryCount = 0;
for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++)
xfb.strides[i] = 0;
// Returning S_OK instead of an error fixes some issues
// with Overwatch until this is properly implemented
return m_d3d11Options.fakeStreamOutSupport ? S_OK : E_NOTIMPL;
for (uint32_t i = 0; i < NumEntries; i++) {
const D3D11_SO_DECLARATION_ENTRY* so = &pSODeclaration[i];
if (so->OutputSlot >= D3D11_SO_BUFFER_SLOT_COUNT)
return E_INVALIDARG;
if (so->SemanticName != nullptr) {
if (so->Stream >= D3D11_SO_BUFFER_SLOT_COUNT
|| so->StartComponent >= 4
|| so->ComponentCount < 1
|| so->ComponentCount > 4)
return E_INVALIDARG;
DxbcXfbEntry* entry = &xfb.entries[xfb.entryCount++];
entry->semanticName = so->SemanticName;
entry->semanticIndex = so->SemanticIndex;
entry->componentIndex = so->StartComponent;
entry->componentCount = so->ComponentCount;
entry->streamId = so->Stream;
entry->bufferId = so->OutputSlot;
entry->offset = xfb.strides[so->OutputSlot];
}
xfb.strides[so->OutputSlot] += so->ComponentCount * sizeof(uint32_t);
}
// If necessary, override the buffer strides
for (uint32_t i = 0; i < NumStrides; i++)
xfb.strides[i] = pBufferStrides[i];
// Set stream to rasterize, if any
xfb.rasterizedStream = -1;
if (RasterizedStream != D3D11_SO_NO_RASTERIZED_STREAM)
Logger::err("D3D11: CreateGeometryShaderWithStreamOutput: Rasterized stream not supported");
// Create the actual shader module
DxbcModuleInfo moduleInfo;
moduleInfo.options = m_dxbcOptions;
moduleInfo.tess = nullptr;
moduleInfo.xfb = &xfb;
if (FAILED(this->CreateShaderModule(&module,
pShaderBytecode, BytecodeLength, pClassLinkage,
&moduleInfo, DxbcProgramType::GeometryShader)))
return E_INVALIDARG;
if (ppGeometryShader == nullptr)
return S_FALSE;
*ppGeometryShader = ref(new D3D11GeometryShader(this, module));
return S_OK;
}
@ -691,6 +758,7 @@ namespace dxvk {
DxbcModuleInfo moduleInfo;
moduleInfo.options = m_dxbcOptions;
moduleInfo.tess = nullptr;
moduleInfo.xfb = nullptr;
if (FAILED(this->CreateShaderModule(&module,
pShaderBytecode, BytecodeLength, pClassLinkage,
@ -719,6 +787,7 @@ namespace dxvk {
DxbcModuleInfo moduleInfo;
moduleInfo.options = m_dxbcOptions;
moduleInfo.tess = nullptr;
moduleInfo.xfb = nullptr;
if (tessInfo.maxTessFactor >= 8.0f)
moduleInfo.tess = &tessInfo;
@ -747,6 +816,7 @@ namespace dxvk {
DxbcModuleInfo moduleInfo;
moduleInfo.options = m_dxbcOptions;
moduleInfo.tess = nullptr;
moduleInfo.xfb = nullptr;
if (FAILED(this->CreateShaderModule(&module,
pShaderBytecode, BytecodeLength, pClassLinkage,
@ -772,6 +842,7 @@ namespace dxvk {
DxbcModuleInfo moduleInfo;
moduleInfo.options = m_dxbcOptions;
moduleInfo.tess = nullptr;
moduleInfo.xfb = nullptr;
if (FAILED(this->CreateShaderModule(&module,
pShaderBytecode, BytecodeLength, pClassLinkage,
@ -914,16 +985,6 @@ namespace dxvk {
ID3D11Query** ppQuery) {
InitReturnPtr(ppQuery);
if (pQueryDesc->Query != D3D11_QUERY_EVENT
&& pQueryDesc->Query != D3D11_QUERY_OCCLUSION
&& pQueryDesc->Query != D3D11_QUERY_TIMESTAMP
&& pQueryDesc->Query != D3D11_QUERY_TIMESTAMP_DISJOINT
&& pQueryDesc->Query != D3D11_QUERY_PIPELINE_STATISTICS
&& pQueryDesc->Query != D3D11_QUERY_OCCLUSION_PREDICATE) {
Logger::warn(str::format("D3D11Query: Unsupported query type ", pQueryDesc->Query));
return E_INVALIDARG;
}
if (ppQuery == nullptr)
return S_FALSE;
@ -1332,6 +1393,9 @@ namespace dxvk {
enabled.core.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
enabled.core.pNext = nullptr;
enabled.extTransformFeedback.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;
enabled.extTransformFeedback.pNext = nullptr;
enabled.extVertexAttributeDivisor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
enabled.extVertexAttributeDivisor.pNext = nullptr;
@ -1364,6 +1428,8 @@ namespace dxvk {
enabled.core.features.shaderImageGatherExtended = VK_TRUE;
enabled.core.features.textureCompressionBC = VK_TRUE;
enabled.core.features.variableMultisampleRate = supported.core.features.variableMultisampleRate;
enabled.extTransformFeedback.transformFeedback = supported.extTransformFeedback.transformFeedback;
enabled.extTransformFeedback.geometryStreams = supported.extTransformFeedback.geometryStreams;
}
if (featureLevel >= D3D_FEATURE_LEVEL_10_1) {
@ -1421,6 +1487,27 @@ namespace dxvk {
return new D3D11CounterBuffer(m_dxvkDevice,
uavCounterInfo, uavCounterSliceLength);
}
Rc<D3D11CounterBuffer> D3D11Device::CreateXFBCounterBuffer() {
DxvkBufferCreateInfo xfbCounterInfo;
xfbCounterInfo.size = 4096 * sizeof(D3D11SOCounter);
xfbCounterInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
| VK_BUFFER_USAGE_TRANSFER_SRC_BIT
| VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
| VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
xfbCounterInfo.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
| VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
| VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
xfbCounterInfo.access = VK_ACCESS_TRANSFER_READ_BIT
| VK_ACCESS_TRANSFER_WRITE_BIT
| VK_ACCESS_INDIRECT_COMMAND_READ_BIT
| VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT
| VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT;
return new D3D11CounterBuffer(m_dxvkDevice,
xfbCounterInfo, sizeof(D3D11SOCounter));
}
HRESULT D3D11Device::CreateShaderModule(
@ -1475,8 +1562,22 @@ namespace dxvk {
|| Format == DXGI_FORMAT_R32_UINT)
flags1 |= D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER;
// TODO implement stream output
// D3D11_FORMAT_SUPPORT_SO_BUFFER
// These formats are technically irrelevant since
// SO buffers are passed in as raw buffers and not
// as views, but the feature flag exists regardless
if (Format == DXGI_FORMAT_R32_FLOAT
|| Format == DXGI_FORMAT_R32_UINT
|| Format == DXGI_FORMAT_R32_SINT
|| Format == DXGI_FORMAT_R32G32_FLOAT
|| Format == DXGI_FORMAT_R32G32_UINT
|| Format == DXGI_FORMAT_R32G32_SINT
|| Format == DXGI_FORMAT_R32G32B32_FLOAT
|| Format == DXGI_FORMAT_R32G32B32_UINT
|| Format == DXGI_FORMAT_R32G32B32_SINT
|| Format == DXGI_FORMAT_R32G32B32A32_FLOAT
|| Format == DXGI_FORMAT_R32G32B32A32_UINT
|| Format == DXGI_FORMAT_R32G32B32A32_SINT)
flags1 |= D3D11_FORMAT_SUPPORT_SO_BUFFER;
if (fmtSupport.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
|| fmtSupport.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {

View File

@ -333,14 +333,6 @@ namespace dxvk {
DXGI_FORMAT Format,
DXGI_VK_FORMAT_MODE Mode) const;
DxvkBufferSlice AllocCounterSlice() {
return m_uavCounters->AllocSlice();
}
void FreeCounterSlice(const DxvkBufferSlice& Slice) {
m_uavCounters->FreeSlice(Slice);
}
DxvkCsChunkRef AllocCsChunk() {
DxvkCsChunk* chunk = m_csChunkPool.allocChunk();
return DxvkCsChunkRef(chunk, &m_csChunkPool);
@ -354,6 +346,12 @@ namespace dxvk {
return m_d3d10Device;
}
DxvkBufferSlice AllocUavCounterSlice() { return m_uavCounters->AllocSlice(); }
DxvkBufferSlice AllocXfbCounterSlice() { return m_xfbCounters->AllocSlice(); }
void FreeUavCounterSlice(const DxvkBufferSlice& Slice) { m_uavCounters->FreeSlice(Slice); }
void FreeXfbCounterSlice(const DxvkBufferSlice& Slice) { m_xfbCounters->FreeSlice(Slice); }
static bool CheckFeatureLevelSupport(
const Rc<DxvkAdapter>& adapter,
D3D_FEATURE_LEVEL featureLevel);
@ -383,6 +381,7 @@ namespace dxvk {
D3D10Device* m_d3d10Device = nullptr;
Rc<D3D11CounterBuffer> m_uavCounters;
Rc<D3D11CounterBuffer> m_xfbCounters;
D3D11StateObjectSet<D3D11BlendState> m_bsStateObjects;
D3D11StateObjectSet<D3D11DepthStencilState> m_dsStateObjects;
@ -391,6 +390,7 @@ namespace dxvk {
D3D11ShaderModuleSet m_shaderModules;
Rc<D3D11CounterBuffer> CreateUAVCounterBuffer();
Rc<D3D11CounterBuffer> CreateXFBCounterBuffer();
HRESULT CreateShaderModule(
D3D11CommonShader* pShaderModule,

View File

@ -37,6 +37,35 @@ namespace dxvk {
VK_QUERY_TYPE_PIPELINE_STATISTICS, 0);
break;
case D3D11_QUERY_SO_STATISTICS:
case D3D11_QUERY_SO_STATISTICS_STREAM0:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0:
// FIXME it is technically incorrect to map
// SO_OVERFLOW_PREDICATE to the first stream,
// but this is good enough for D3D10 behaviour
m_query = new DxvkQuery(
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 0);
break;
case D3D11_QUERY_SO_STATISTICS_STREAM1:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1:
m_query = new DxvkQuery(
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 1);
break;
case D3D11_QUERY_SO_STATISTICS_STREAM2:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2:
m_query = new DxvkQuery(
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 2);
break;
case D3D11_QUERY_SO_STATISTICS_STREAM3:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3:
m_query = new DxvkQuery(
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 3);
break;
default:
throw DxvkError(str::format("D3D11: Unhandled query type: ", desc.Query));
}
@ -247,7 +276,27 @@ namespace dxvk {
data->DSInvocations = queryData.statistic.tesInvocations;
data->CSInvocations = queryData.statistic.csInvocations;
} return S_OK;
case D3D11_QUERY_SO_STATISTICS:
case D3D11_QUERY_SO_STATISTICS_STREAM0:
case D3D11_QUERY_SO_STATISTICS_STREAM1:
case D3D11_QUERY_SO_STATISTICS_STREAM2:
case D3D11_QUERY_SO_STATISTICS_STREAM3: {
auto data = static_cast<D3D11_QUERY_DATA_SO_STATISTICS*>(pData);
data->NumPrimitivesWritten = queryData.xfbStream.primitivesWritten;
data->PrimitivesStorageNeeded = queryData.xfbStream.primitivesNeeded;
} return S_OK;
case D3D11_QUERY_SO_OVERFLOW_PREDICATE:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2:
case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3: {
auto data = static_cast<BOOL*>(pData);
*data = queryData.xfbStream.primitivesNeeded
> queryData.xfbStream.primitivesWritten;
} return S_OK;
default:
Logger::err(str::format("D3D11: Unhandled query type in GetData: ", m_desc.Query));
return E_INVALIDARG;

View File

@ -31,7 +31,14 @@ namespace dxvk {
std::ios_base::binary | std::ios_base::trunc));
}
m_shader = module.compile(*pDxbcModuleInfo, name);
// Decide whether we need to create a pass-through
// geometry shader for vertex shader stream output
bool passthroughShader = pDxbcModuleInfo->xfb != nullptr
&& module.programInfo().type() != DxbcProgramType::GeometryShader;
m_shader = passthroughShader
? module.compilePassthroughShader(*pDxbcModuleInfo, name)
: module.compile (*pDxbcModuleInfo, name);
m_shader->setShaderKey(*pShaderKey);
if (dumpPath.size() != 0) {

View File

@ -38,7 +38,7 @@ namespace dxvk {
}
if (pDesc->Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND | D3D11_BUFFER_UAV_FLAG_COUNTER))
m_counterSlice = pDevice->AllocCounterSlice();
m_counterSlice = pDevice->AllocUavCounterSlice();
m_bufferView = pDevice->GetDXVKDevice()->createBufferView(
buffer->GetBuffer(), viewInfo);
@ -109,7 +109,7 @@ namespace dxvk {
ResourceReleasePrivate(m_resource);
if (m_counterSlice.defined())
m_device->FreeCounterSlice(m_counterSlice);
m_device->FreeUavCounterSlice(m_counterSlice);
}

View File

@ -177,6 +177,36 @@ namespace dxvk {
ins.op));
}
}
void DxbcCompiler::processXfbPassthrough() {
m_module.setExecutionMode (m_entryPointId, spv::ExecutionModeInputPoints);
m_module.setExecutionMode (m_entryPointId, spv::ExecutionModeOutputPoints);
m_module.setOutputVertices(m_entryPointId, 1);
m_module.setInvocations (m_entryPointId, 1);
for (auto e = m_isgn->begin(); e != m_isgn->end(); e++) {
emitDclInput(e->registerId, 1,
e->componentMask, e->systemValue,
DxbcInterpolationMode::Undefined);
}
// Figure out which streams to enable
uint32_t streamMask = 0;
for (size_t i = 0; i < m_xfbVars.size(); i++)
streamMask |= 1u << m_xfbVars[i].streamId;
for (uint32_t mask = streamMask; mask != 0; mask &= mask - 1) {
const uint32_t streamId = bit::tzcnt(mask);
emitXfbOutputSetup(streamId, true);
m_module.opEmitVertex(m_module.constu32(streamId));
}
// End the main function
emitFunctionEnd();
}
Rc<DxvkShader> DxbcCompiler::finalize() {
@ -199,7 +229,16 @@ namespace dxvk {
m_entryPointInterfaces.size(),
m_entryPointInterfaces.data());
m_module.setDebugName(m_entryPointId, "main");
DxvkShaderOptions shaderOptions = { };
if (m_moduleInfo.xfb != nullptr) {
shaderOptions.rasterizedStream = m_moduleInfo.xfb->rasterizedStream;
for (uint32_t i = 0; i < 4; i++)
shaderOptions.xfbStrides[i] = m_moduleInfo.xfb->strides[i];
}
// Create the shader module object
return new DxvkShader(
m_programInfo.shaderStage(),
@ -207,6 +246,7 @@ namespace dxvk {
m_resourceSlots.data(),
m_interfaceSlots,
m_module.compile(),
shaderOptions,
std::move(m_immConstData));
}
@ -667,12 +707,19 @@ namespace dxvk {
info.type.ccount = regType.ccount;
info.type.alength = regDim;
info.sclass = spv::StorageClassOutput;
// In xfb mode, we set up the actual
// output vars when emitting a vertex
if (m_moduleInfo.xfb != nullptr)
info.sclass = spv::StorageClassPrivate;
const uint32_t varId = this->emitNewVariable(info);
m_module.decorateLocation(varId, regIdx);
m_module.setDebugName(varId, str::format("o", regIdx).c_str());
m_entryPointInterfaces.push_back(varId);
if (info.sclass == spv::StorageClassOutput) {
m_module.decorateLocation(varId, regIdx);
m_entryPointInterfaces.push_back(varId);
}
m_oRegs.at(regIdx) = { regType, varId };
@ -790,7 +837,7 @@ namespace dxvk {
void DxbcCompiler::emitDclStream(const DxbcShaderInstruction& ins) {
if (ins.dst[0].idx[0].offset != 0)
if (ins.dst[0].idx[0].offset != 0 && m_moduleInfo.xfb == nullptr)
Logger::err("Dxbc: Multiple streams not supported");
}
@ -2047,6 +2094,16 @@ namespace dxvk {
void DxbcCompiler::emitGeometryEmit(const DxbcShaderInstruction& ins) {
// In xfb mode we might have multiple streams, so
// we have to figure out which stream to write to
uint32_t streamId = 0;
uint32_t streamVar = 0;
if (m_moduleInfo.xfb != nullptr) {
streamId = ins.dstCount > 0 ? ins.dst[0].idx[0].offset : 0;
streamVar = m_module.constu32(streamId);
}
// Checking the negation is easier for EmitThenCut/EmitThenCutStream
bool doEmit = ins.op != DxbcOpcode::Cut && ins.op != DxbcOpcode::CutStream;
bool doCut = ins.op != DxbcOpcode::Emit && ins.op != DxbcOpcode::EmitStream;
@ -2055,11 +2112,12 @@ namespace dxvk {
emitOutputSetup();
emitClipCullStore(DxbcSystemValue::ClipDistance, m_clipDistances);
emitClipCullStore(DxbcSystemValue::CullDistance, m_cullDistances);
m_module.opEmitVertex();
emitXfbOutputSetup(streamId, false);
m_module.opEmitVertex(streamVar);
}
if (doCut)
m_module.opEndPrimitive();
m_module.opEndPrimitive(streamVar);
}
@ -4230,6 +4288,21 @@ namespace dxvk {
}
DxbcRegisterPointer DxbcCompiler::emitArrayAccess(
DxbcRegisterPointer pointer,
spv::StorageClass sclass,
uint32_t index) {
uint32_t ptrTypeId = m_module.defPointerType(
getVectorTypeId(pointer.type), sclass);
DxbcRegisterPointer result;
result.type = pointer.type;
result.id = m_module.opAccessChain(
ptrTypeId, pointer.id, 1, &index);
return result;
}
uint32_t DxbcCompiler::emitLoadSampledImage(
const DxbcShaderResource& textureResource,
const DxbcSampler& samplerResource,
@ -6002,6 +6075,14 @@ namespace dxvk {
m_module.enableCapability(spv::CapabilityGeometry);
m_module.enableCapability(spv::CapabilityClipDistance);
m_module.enableCapability(spv::CapabilityCullDistance);
// Enable capabilities for xfb mode if necessary
if (m_moduleInfo.xfb != nullptr) {
m_module.enableCapability(spv::CapabilityGeometryStreams);
m_module.enableCapability(spv::CapabilityTransformFeedback);
m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeXfb);
}
// Declare the per-vertex output block. Outputs are not
// declared as arrays, instead they will be flushed when
@ -6026,6 +6107,10 @@ namespace dxvk {
spv::BuiltInCullDistance,
spv::StorageClassOutput);
// Emit Xfb variables if necessary
if (m_moduleInfo.xfb != nullptr)
emitXfbOutputDeclarations();
// Main function of the vertex shader
m_gs.functionId = m_module.allocateId();
m_module.setDebugName(m_gs.functionId, "gs_main");
@ -6202,6 +6287,88 @@ namespace dxvk {
}
void DxbcCompiler::emitXfbOutputDeclarations() {
for (uint32_t i = 0; i < m_moduleInfo.xfb->entryCount; i++) {
const DxbcXfbEntry* xfbEntry = m_moduleInfo.xfb->entries + i;
const DxbcSgnEntry* sigEntry = m_osgn->find(
xfbEntry->semanticName,
xfbEntry->semanticIndex,
xfbEntry->streamId);
if (sigEntry == nullptr)
continue;
DxbcRegisterInfo varInfo;
varInfo.type.ctype = DxbcScalarType::Float32;
varInfo.type.ccount = xfbEntry->componentCount;
varInfo.type.alength = 0;
varInfo.sclass = spv::StorageClassOutput;
uint32_t dstComponentMask = (1 << xfbEntry->componentCount) - 1;
uint32_t srcComponentMask = dstComponentMask
<< sigEntry->componentMask.firstSet()
<< xfbEntry->componentIndex;
DxbcXfbVar xfbVar;
xfbVar.varId = emitNewVariable(varInfo);
xfbVar.streamId = xfbEntry->streamId;
xfbVar.outputId = sigEntry->registerId;
xfbVar.srcMask = DxbcRegMask(srcComponentMask);
xfbVar.dstMask = DxbcRegMask(dstComponentMask);
m_xfbVars.push_back(xfbVar);
m_entryPointInterfaces.push_back(xfbVar.varId);
m_module.setDebugName(xfbVar.varId,
str::format("xfb", i).c_str());
m_module.decorateXfb(xfbVar.varId,
xfbEntry->streamId, xfbEntry->bufferId, xfbEntry->offset,
m_moduleInfo.xfb->strides[xfbEntry->bufferId]);
}
// TODO Compact location/component assignment
for (uint32_t i = 0; i < m_xfbVars.size(); i++) {
m_xfbVars[i].location = i;
m_xfbVars[i].component = 0;
}
for (uint32_t i = 0; i < m_xfbVars.size(); i++) {
const DxbcXfbVar* var = &m_xfbVars[i];
m_module.decorateLocation (var->varId, var->location);
m_module.decorateComponent(var->varId, var->component);
}
}
void DxbcCompiler::emitXfbOutputSetup(
uint32_t streamId,
bool passthrough) {
for (size_t i = 0; i < m_xfbVars.size(); i++) {
if (m_xfbVars[i].streamId == streamId) {
DxbcRegisterPointer srcPtr = passthrough
? m_vRegs[m_xfbVars[i].outputId]
: m_oRegs[m_xfbVars[i].outputId];
if (passthrough) {
srcPtr = emitArrayAccess(srcPtr,
spv::StorageClassInput,
m_module.constu32(0));
}
DxbcRegisterPointer dstPtr;
dstPtr.type.ctype = DxbcScalarType::Float32;
dstPtr.type.ccount = m_xfbVars[i].dstMask.popCount();
dstPtr.id = m_xfbVars[i].varId;
DxbcRegisterValue value = emitRegisterExtract(
emitValueLoad(srcPtr), m_xfbVars[i].srcMask);
emitValueStore(dstPtr, value, m_xfbVars[i].dstMask);
}
}
}
void DxbcCompiler::emitHsControlPointPhase(
const DxbcCompilerHsControlPointPhase& phase) {
m_module.opFunctionCall(

View File

@ -122,6 +122,17 @@ namespace dxvk {
uint32_t labelElse = 0;
uint32_t labelEnd = 0;
};
struct DxbcXfbVar {
uint32_t varId = 0;
uint32_t streamId = 0;
uint32_t outputId = 0;
DxbcRegMask srcMask = 0;
DxbcRegMask dstMask = 0;
uint32_t location = 0;
uint32_t component = 0;
};
/**
@ -371,6 +382,15 @@ namespace dxvk {
void processInstruction(
const DxbcShaderInstruction& ins);
/**
* \brief Emits transform feedback passthrough
*
* Writes all captured input variables to the
* corresponding xfb outputs, and sets up the
* geometry shader for point-to-point mode.
*/
void processXfbPassthrough();
/**
* \brief Finalizes the shader
* \returns The final shader object
@ -419,6 +439,10 @@ namespace dxvk {
DxbcRegisterPointer,
DxbcMaxInterfaceRegs> m_oRegs;
std::vector<DxbcSvMapping> m_oMappings;
/////////////////////////////////////////////
// xfb output registers for geometry shaders
std::vector<DxbcXfbVar> m_xfbVars;
//////////////////////////////////////////////////////
// Shader resource variables. These provide access to
@ -488,7 +512,7 @@ namespace dxvk {
// Inter-stage shader interface slots. Also
// covers vertex input and fragment output.
DxvkInterfaceSlots m_interfaceSlots;
///////////////////////////////////
// Shader-specific data structures
DxbcCompilerVsPart m_vs;
@ -836,6 +860,13 @@ namespace dxvk {
DxbcRegisterValue value,
DxbcOpModifiers modifiers);
////////////////////////////////
// Pointer manipulation methods
DxbcRegisterPointer emitArrayAccess(
DxbcRegisterPointer pointer,
spv::StorageClass sclass,
uint32_t index);
///////////////////////////////////////
// Image register manipulation methods
uint32_t emitLoadSampledImage(
@ -1044,6 +1075,14 @@ namespace dxvk {
void emitGsFinalize();
void emitPsFinalize();
void emitCsFinalize();
///////////////////////
// Xfb related methods
void emitXfbOutputDeclarations();
void emitXfbOutputSetup(
uint32_t streamId,
bool passthrough);
///////////////////////////////
// Hull shader phase methods

View File

@ -14,6 +14,35 @@ namespace dxvk {
float maxTessFactor;
};
/**
* \brief Xfb capture entry
*
* Stores an output variable to capture,
* as well as the buffer to write it to.
*/
struct DxbcXfbEntry {
const char* semanticName;
uint32_t semanticIndex;
uint32_t componentIndex;
uint32_t componentCount;
uint32_t streamId;
uint32_t bufferId;
uint32_t offset;
};
/**
* \brief Xfb info
*
* Stores capture entries and output buffer
* strides. This structure must only be
* defined if \c entryCount is non-zero.
*/
struct DxbcXfbInfo {
uint32_t entryCount;
DxbcXfbEntry entries[128];
uint32_t strides[4];
int32_t rasterizedStream;
};
/**
* \brief Shader module info
@ -24,6 +53,7 @@ namespace dxvk {
struct DxbcModuleInfo {
DxbcOptions options;
DxbcTessInfo* tess;
DxbcXfbInfo* xfb;
};
}

View File

@ -64,6 +64,25 @@ namespace dxvk {
}
Rc<DxvkShader> DxbcModule::compilePassthroughShader(
const DxbcModuleInfo& moduleInfo,
const std::string& fileName) const {
if (m_shexChunk == nullptr)
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
DxbcAnalysisInfo analysisInfo;
DxbcCompiler compiler(
fileName, moduleInfo,
DxbcProgramType::GeometryShader,
m_osgnChunk, m_osgnChunk,
analysisInfo);
compiler.processXfbPassthrough();
return compiler.finalize();
}
void DxbcModule::runAnalyzer(
DxbcAnalyzer& analyzer,
DxbcCodeSlice slice) const {

View File

@ -60,6 +60,20 @@ namespace dxvk {
const DxbcModuleInfo& moduleInfo,
const std::string& fileName) const;
/**
* \brief Compiles a pass-through geometry shader
*
* Applications can pass a vertex shader to create
* a geometry shader with stream output. In this
* case, we have to create a passthrough geometry
* shader, which operates in point to point mode.
* \param [in] moduleInfo DXBC module info
* \param [in] fileName SPIR-V shader name
*/
Rc<DxvkShader> compilePassthroughShader(
const DxbcModuleInfo& moduleInfo,
const std::string& fileName) const;
private:
DxbcHeader m_header;

View File

@ -183,6 +183,8 @@ namespace dxvk {
|| !required.core.features.variableMultisampleRate)
&& (m_deviceFeatures.core.features.inheritedQueries
|| !required.core.features.inheritedQueries)
&& (m_deviceFeatures.extTransformFeedback.transformFeedback
|| !required.extTransformFeedback.transformFeedback)
&& (m_deviceFeatures.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor
|| !required.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor)
&& (m_deviceFeatures.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor
@ -193,8 +195,9 @@ namespace dxvk {
Rc<DxvkDevice> DxvkAdapter::createDevice(DxvkDeviceFeatures enabledFeatures) {
DxvkDeviceExtensions devExtensions;
std::array<DxvkExt*, 11> devExtensionList = {{
std::array<DxvkExt*, 12> devExtensionList = {{
&devExtensions.extShaderViewportIndexLayer,
&devExtensions.extTransformFeedback,
&devExtensions.extVertexAttributeDivisor,
&devExtensions.khrDedicatedAllocation,
&devExtensions.khrDescriptorUpdateTemplate,
@ -225,6 +228,11 @@ namespace dxvk {
// Create pNext chain for additional device features
enabledFeatures.core.pNext = nullptr;
if (devExtensions.extTransformFeedback) {
enabledFeatures.extTransformFeedback.pNext = enabledFeatures.core.pNext;
enabledFeatures.core.pNext = &enabledFeatures.extTransformFeedback;
}
if (devExtensions.extVertexAttributeDivisor.revision() >= 3) {
enabledFeatures.extVertexAttributeDivisor.pNext = enabledFeatures.core.pNext;
enabledFeatures.core.pNext = &enabledFeatures.extVertexAttributeDivisor;
@ -324,6 +332,11 @@ namespace dxvk {
m_deviceInfo.core.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
m_deviceInfo.core.pNext = nullptr;
if (m_deviceExtensions.supports(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
m_deviceInfo.extTransformFeedback.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT;
m_deviceInfo.extTransformFeedback.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extTransformFeedback);
}
if (m_deviceExtensions.supports(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) {
m_deviceInfo.extVertexAttributeDivisor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;
m_deviceInfo.extVertexAttributeDivisor.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extVertexAttributeDivisor);
@ -346,6 +359,11 @@ namespace dxvk {
m_deviceFeatures.core.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
m_deviceFeatures.core.pNext = nullptr;
if (m_deviceExtensions.supports(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
m_deviceFeatures.extTransformFeedback.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;
m_deviceFeatures.extTransformFeedback.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extTransformFeedback);
}
if (m_deviceExtensions.supports(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) >= 3) {
m_deviceFeatures.extVertexAttributeDivisor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
m_deviceFeatures.extVertexAttributeDivisor.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extVertexAttributeDivisor);

View File

@ -149,7 +149,8 @@ namespace dxvk {
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
| VK_ACCESS_TRANSFER_READ_BIT
| VK_ACCESS_HOST_READ_BIT
| VK_ACCESS_MEMORY_READ_BIT;
| VK_ACCESS_MEMORY_READ_BIT
| VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT;
const VkAccessFlags wflags
= VK_ACCESS_SHADER_WRITE_BIT
@ -157,7 +158,9 @@ namespace dxvk {
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
| VK_ACCESS_TRANSFER_WRITE_BIT
| VK_ACCESS_HOST_WRITE_BIT
| VK_ACCESS_MEMORY_WRITE_BIT;
| VK_ACCESS_MEMORY_WRITE_BIT
| VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT
| VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT;
DxvkAccessFlags result;
if (flags & rflags) result.set(DxvkAccess::Read);

View File

@ -146,6 +146,28 @@ namespace dxvk {
return prevSlice;
}
/**
* \brief Transform feedback vertex stride
*
* Used when drawing after transform feedback,
* \returns The current xfb vertex stride
*/
uint32_t getXfbVertexStride() const {
return m_vertexStride;
}
/**
* \brief Set transform feedback vertex stride
*
* When the buffer is used as a transform feedback
* buffer, this will be set to the vertex stride
* defined by the geometry shader.
* \param [in] stride Vertex stride
*/
void setXfbVertexStride(uint32_t stride) {
m_vertexStride = stride;
}
/**
* \brief Allocates new physical resource
* \returns The new backing buffer slice
@ -170,7 +192,8 @@ namespace dxvk {
VkMemoryPropertyFlags m_memFlags;
DxvkPhysicalBufferSlice m_physSlice;
uint32_t m_revision = 0;
uint32_t m_revision = 0;
uint32_t m_vertexStride = 0;
sync::Spinlock m_freeMutex;
sync::Spinlock m_swapMutex;
@ -273,7 +296,9 @@ namespace dxvk {
* \returns The physical buffer slice
*/
DxvkPhysicalBufferSlice physicalSlice() const {
return m_buffer->subSlice(m_offset, m_length);
return m_buffer != nullptr
? m_buffer->subSlice(m_offset, m_length)
: DxvkPhysicalBufferSlice();
}
/**
@ -301,7 +326,9 @@ namespace dxvk {
* \returns Pointer into mapped buffer memory
*/
void* mapPtr(VkDeviceSize offset) const {
return m_buffer->mapPtr(m_offset + offset);
return m_buffer != nullptr
? m_buffer->mapPtr(m_offset + offset)
: nullptr;
}
/**

View File

@ -134,7 +134,9 @@ namespace dxvk {
* \returns Buffer handle
*/
VkBuffer handle() const {
return m_buffer->handle();
return m_buffer != nullptr
? m_buffer->handle()
: VK_NULL_HANDLE;
}
/**

View File

@ -221,12 +221,32 @@ namespace dxvk {
}
void cmdBeginQueryIndexed(
VkQueryPool queryPool,
uint32_t query,
VkQueryControlFlags flags,
uint32_t index) {
m_vkd->vkCmdBeginQueryIndexedEXT(
m_execBuffer, queryPool, query, flags, index);
}
void cmdBeginRenderPass(
const VkRenderPassBeginInfo* pRenderPassBegin,
VkSubpassContents contents) {
m_vkd->vkCmdBeginRenderPass(m_execBuffer,
pRenderPassBegin, contents);
}
void cmdBeginTransformFeedback(
uint32_t firstBuffer,
uint32_t bufferCount,
const VkBuffer* counterBuffers,
const VkDeviceSize* counterOffsets) {
m_vkd->vkCmdBeginTransformFeedbackEXT(m_execBuffer,
firstBuffer, bufferCount, counterBuffers, counterOffsets);
}
void cmdBindDescriptorSet(
@ -256,6 +276,17 @@ namespace dxvk {
m_vkd->vkCmdBindPipeline(m_execBuffer,
pipelineBindPoint, pipeline);
}
void cmdBindTransformFeedbackBuffers(
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer* pBuffers,
const VkDeviceSize* pOffsets,
const VkDeviceSize* pSizes) {
m_vkd->vkCmdBindTransformFeedbackBuffersEXT(m_execBuffer,
firstBinding, bindingCount, pBuffers, pOffsets, pSizes);
}
void cmdBindVertexBuffers(
@ -425,6 +456,19 @@ namespace dxvk {
m_vkd->vkCmdDrawIndexedIndirect(m_execBuffer,
buffer, offset, drawCount, stride);
}
void cmdDrawIndirectVertexCount(
uint32_t instanceCount,
uint32_t firstInstance,
VkBuffer counterBuffer,
VkDeviceSize counterBufferOffset,
uint32_t counterOffset,
uint32_t vertexStride) {
m_vkd->vkCmdDrawIndirectByteCountEXT(m_execBuffer,
instanceCount, firstInstance, counterBuffer,
counterBufferOffset, counterOffset, vertexStride);
}
void cmdEndQuery(
@ -432,6 +476,15 @@ namespace dxvk {
uint32_t query) {
m_vkd->vkCmdEndQuery(m_execBuffer, queryPool, query);
}
void cmdEndQueryIndexed(
VkQueryPool queryPool,
uint32_t query,
uint32_t index) {
m_vkd->vkCmdEndQueryIndexedEXT(
m_execBuffer, queryPool, query, index);
}
void cmdEndRenderPass() {
@ -439,6 +492,16 @@ namespace dxvk {
}
void cmdEndTransformFeedback(
uint32_t firstBuffer,
uint32_t bufferCount,
const VkBuffer* counterBuffers,
const VkDeviceSize* counterOffsets) {
m_vkd->vkCmdEndTransformFeedbackEXT(m_execBuffer,
firstBuffer, bufferCount, counterBuffers, counterOffsets);
}
void cmdFillBuffer(
VkBuffer dstBuffer,
VkDeviceSize dstOffset,

View File

@ -36,6 +36,7 @@ namespace dxvk {
// before any draw or dispatch command is recorded.
m_flags.clr(
DxvkContextFlag::GpRenderPassBound,
DxvkContextFlag::GpXfbActive,
DxvkContextFlag::GpClearRenderTargets);
m_flags.set(
@ -44,6 +45,7 @@ namespace dxvk {
DxvkContextFlag::GpDirtyResources,
DxvkContextFlag::GpDirtyVertexBuffers,
DxvkContextFlag::GpDirtyIndexBuffer,
DxvkContextFlag::GpDirtyXfbBuffers,
DxvkContextFlag::CpDirtyPipeline,
DxvkContextFlag::CpDirtyPipelineState,
DxvkContextFlag::CpDirtyResources,
@ -218,6 +220,19 @@ namespace dxvk {
}
void DxvkContext::bindXfbBuffer(
uint32_t binding,
const DxvkBufferSlice& buffer,
const DxvkBufferSlice& counter) {
this->spillRenderPass();
m_state.xfb.buffers [binding] = buffer;
m_state.xfb.counters[binding] = counter;
m_flags.set(DxvkContextFlag::GpDirtyXfbBuffers);
}
void DxvkContext::clearBuffer(
const Rc<DxvkBuffer>& buffer,
VkDeviceSize offset,
@ -1005,6 +1020,25 @@ namespace dxvk {
}
void DxvkContext::drawIndirectXfb(
const DxvkBufferSlice& counterBuffer,
uint32_t counterDivisor,
uint32_t counterBias) {
this->commitGraphicsState();
if (this->validateGraphicsState()) {
auto physicalSlice = counterBuffer.physicalSlice();
m_cmd->cmdDrawIndirectVertexCount(1, 0,
physicalSlice.handle(),
physicalSlice.offset(),
counterBias, counterDivisor);
}
m_cmd->addStatCtr(DxvkStatCounter::CmdDrawCalls, 1);
}
void DxvkContext::initImage(
const Rc<DxvkImage>& image,
const VkImageSubresourceRange& subresources) {
@ -1140,6 +1174,9 @@ namespace dxvk {
if (usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers);
if (usage & VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT)
m_flags.set(DxvkContextFlag::GpDirtyXfbBuffers);
if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
| VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) {
m_flags.set(DxvkContextFlag::GpDirtyResources,
@ -2152,10 +2189,14 @@ namespace dxvk {
if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
m_flags.clr(DxvkContextFlag::GpRenderPassBound);
this->pauseTransformFeedback();
m_queries.endQueries(m_cmd, VK_QUERY_TYPE_OCCLUSION);
m_queries.endQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS);
this->renderPassUnbindFramebuffer();
m_flags.clr(DxvkContextFlag::GpDirtyXfbCounters);
}
}
@ -2232,6 +2273,70 @@ namespace dxvk {
}
void DxvkContext::startTransformFeedback() {
if (!m_flags.test(DxvkContextFlag::GpXfbActive)) {
m_flags.set(DxvkContextFlag::GpXfbActive);
if (m_flags.test(DxvkContextFlag::GpDirtyXfbCounters)) {
m_flags.clr(DxvkContextFlag::GpDirtyXfbCounters);
this->emitMemoryBarrier(
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, /* XXX */
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT);
}
VkBuffer ctrBuffers[MaxNumXfbBuffers];
VkDeviceSize ctrOffsets[MaxNumXfbBuffers];
for (uint32_t i = 0; i < MaxNumXfbBuffers; i++) {
auto physSlice = m_state.xfb.counters[i].physicalSlice();
ctrBuffers[i] = physSlice.handle();
ctrOffsets[i] = physSlice.offset();
if (physSlice.handle() != VK_NULL_HANDLE)
m_cmd->trackResource(physSlice.resource());
}
m_cmd->cmdBeginTransformFeedback(
0, MaxNumXfbBuffers, ctrBuffers, ctrOffsets);
m_queries.beginQueries(m_cmd,
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT);
}
}
void DxvkContext::pauseTransformFeedback() {
if (m_flags.test(DxvkContextFlag::GpXfbActive)) {
m_flags.clr(DxvkContextFlag::GpXfbActive);
VkBuffer ctrBuffers[MaxNumXfbBuffers];
VkDeviceSize ctrOffsets[MaxNumXfbBuffers];
for (uint32_t i = 0; i < MaxNumXfbBuffers; i++) {
auto physSlice = m_state.xfb.counters[i].physicalSlice();
ctrBuffers[i] = physSlice.handle();
ctrOffsets[i] = physSlice.offset();
if (physSlice.handle() != VK_NULL_HANDLE)
m_cmd->trackResource(physSlice.resource());
}
m_queries.endQueries(m_cmd,
VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT);
m_cmd->cmdEndTransformFeedback(
0, MaxNumXfbBuffers, ctrBuffers, ctrOffsets);
m_flags.set(DxvkContextFlag::GpDirtyXfbCounters);
}
}
void DxvkContext::unbindComputePipeline() {
m_flags.set(
DxvkContextFlag::CpDirtyPipeline,
@ -2278,7 +2383,8 @@ namespace dxvk {
DxvkContextFlag::GpDirtyPipelineState,
DxvkContextFlag::GpDirtyResources,
DxvkContextFlag::GpDirtyVertexBuffers,
DxvkContextFlag::GpDirtyIndexBuffer);
DxvkContextFlag::GpDirtyIndexBuffer,
DxvkContextFlag::GpDirtyXfbBuffers);
m_gpActivePipeline = VK_NULL_HANDLE;
}
@ -2304,6 +2410,8 @@ namespace dxvk {
if (m_flags.test(DxvkContextFlag::GpDirtyPipelineState)) {
m_flags.clr(DxvkContextFlag::GpDirtyPipelineState);
this->pauseTransformFeedback();
for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) {
const uint32_t binding = m_state.gp.state.ilBindings[i].binding;
@ -2666,6 +2774,56 @@ namespace dxvk {
}
}
}
void DxvkContext::updateTransformFeedbackBuffers() {
auto gsOptions = m_state.gp.gs.shader->shaderOptions();
VkBuffer xfbBuffers[MaxNumXfbBuffers];
VkDeviceSize xfbOffsets[MaxNumXfbBuffers];
VkDeviceSize xfbLengths[MaxNumXfbBuffers];
for (size_t i = 0; i < MaxNumXfbBuffers; i++) {
auto physSlice = m_state.xfb.buffers[i].physicalSlice();
xfbBuffers[i] = physSlice.handle();
xfbOffsets[i] = physSlice.offset();
xfbLengths[i] = physSlice.length();
if (physSlice.handle() == VK_NULL_HANDLE)
xfbBuffers[i] = m_device->dummyBufferHandle();
if (physSlice.handle() != VK_NULL_HANDLE) {
auto buffer = m_state.xfb.buffers[i].buffer();
buffer->setXfbVertexStride(gsOptions.xfbStrides[i]);
m_cmd->trackResource(physSlice.resource());
}
}
m_cmd->cmdBindTransformFeedbackBuffers(
0, MaxNumXfbBuffers,
xfbBuffers, xfbOffsets, xfbLengths);
}
void DxvkContext::updateTransformFeedbackState() {
bool hasTransformFeedback =
m_state.gp.pipeline != nullptr
&& m_state.gp.pipeline->flags().test(DxvkGraphicsPipelineFlag::HasTransformFeedback);
if (!hasTransformFeedback)
return;
if (m_flags.test(DxvkContextFlag::GpDirtyXfbBuffers)) {
m_flags.clr(DxvkContextFlag::GpDirtyXfbBuffers);
this->pauseTransformFeedback();
this->updateTransformFeedbackBuffers();
}
this->startTransformFeedback();
}
void DxvkContext::updateDynamicState() {
@ -2732,6 +2890,7 @@ namespace dxvk {
this->updateVertexBufferBindings();
this->updateGraphicsShaderResources();
this->updateGraphicsPipelineState();
this->updateTransformFeedbackState();
this->updateGraphicsShaderDescriptors();
this->updateDynamicState();
}
@ -2853,6 +3012,22 @@ namespace dxvk {
}
void DxvkContext::emitMemoryBarrier(
VkPipelineStageFlags srcStages,
VkAccessFlags srcAccess,
VkPipelineStageFlags dstStages,
VkAccessFlags dstAccess) {
VkMemoryBarrier barrier;
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
barrier.pNext = nullptr;
barrier.srcAccessMask = srcAccess;
barrier.dstAccessMask = dstAccess;
m_cmd->cmdPipelineBarrier(srcStages, dstStages,
0, 1, &barrier, 0, nullptr, 0, nullptr);
}
void DxvkContext::trackDrawBuffer() {
if (m_flags.test(DxvkContextFlag::DirtyDrawBuffer)) {
m_flags.clr(DxvkContextFlag::DirtyDrawBuffer);

View File

@ -173,6 +173,18 @@ namespace dxvk {
const DxvkBufferSlice& buffer,
uint32_t stride);
/**
* \brief Binds transform feedback buffer
*
* \param [in] binding Xfb buffer binding
* \param [in] buffer The buffer to bind
* \param [in] counter Xfb counter buffer
*/
void bindXfbBuffer(
uint32_t binding,
const DxvkBufferSlice& buffer,
const DxvkBufferSlice& counter);
/**
* \brief Clears a buffer with a fixed value
*
@ -474,6 +486,18 @@ namespace dxvk {
uint32_t count,
uint32_t stride);
/**
* \brief Transform feddback draw call
* \param [in] counterBuffer Xfb counter buffer
* \param [in] counterDivisor Vertex stride
* \param [in] counterBias Counter bias
*/
void drawIndirectXfb(
const DxvkBufferSlice& counterBuffer,
uint32_t counterDivisor,
uint32_t counterBias);
/**
* \brief Generates mip maps
*
@ -776,6 +800,9 @@ namespace dxvk {
const DxvkRenderTargets& renderTargets,
DxvkRenderPassOps& renderPassOps);
void startTransformFeedback();
void pauseTransformFeedback();
void unbindComputePipeline();
void updateComputePipeline();
void updateComputePipelineState();
@ -808,6 +835,9 @@ namespace dxvk {
void updateIndexBufferBinding();
void updateVertexBufferBindings();
void updateTransformFeedbackBuffers();
void updateTransformFeedbackState();
void updateDynamicState();
@ -820,6 +850,12 @@ namespace dxvk {
void commitComputeInitBarriers();
void commitComputePostBarriers();
void emitMemoryBarrier(
VkPipelineStageFlags srcStages,
VkAccessFlags srcAccess,
VkPipelineStageFlags dstStages,
VkAccessFlags dstAccess);
void trackDrawBuffer();
};

View File

@ -22,6 +22,7 @@ namespace dxvk {
*/
enum class DxvkContextFlag : uint64_t {
GpRenderPassBound, ///< Render pass is currently bound
GpXfbActive, ///< Transform feedback is enabled
GpClearRenderTargets, ///< Render targets need to be cleared
GpDirtyFramebuffer, ///< Framebuffer binding is out of date
GpDirtyPipeline, ///< Graphics pipeline binding is out of date
@ -31,6 +32,8 @@ namespace dxvk {
GpDirtyDescriptorSet, ///< Graphics descriptor set needs to be updated
GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date
GpDirtyIndexBuffer, ///< Index buffer binding are out of date
GpDirtyXfbBuffers, ///< Transform feedback buffer bindings are out of date
GpDirtyXfbCounters, ///< Counter buffer values are dirty
GpDirtyBlendConstants, ///< Blend constants have changed
GpDirtyStencilRef, ///< Stencil reference has changed
GpDirtyViewport, ///< Viewport state has changed
@ -86,6 +89,12 @@ namespace dxvk {
DxvkBlendConstants blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f };
uint32_t stencilReference = 0;
};
struct DxvkXfbState {
std::array<DxvkBufferSlice, MaxNumXfbBuffers> buffers;
std::array<DxvkBufferSlice, MaxNumXfbBuffers> counters;
};
struct DxvkShaderStage {
@ -125,6 +134,7 @@ namespace dxvk {
DxvkViewportState vp;
DxvkDynamicDepthState ds;
DxvkOutputMergerState om;
DxvkXfbState xfb;
DxvkGraphicsPipelineState gp;
DxvkComputePipelineState cp;

View File

@ -186,8 +186,9 @@ namespace dxvk {
const DxvkInterfaceSlots& iface,
const SpirvCodeBuffer& code) {
return new DxvkShader(stage,
slotCount, slotInfos, iface,
code, DxvkShaderConstData());
slotCount, slotInfos, iface, code,
DxvkShaderOptions(),
DxvkShaderConstData());
}

View File

@ -14,6 +14,7 @@ namespace dxvk {
*/
struct DxvkDeviceInfo {
VkPhysicalDeviceProperties2KHR core;
VkPhysicalDeviceTransformFeedbackPropertiesEXT extTransformFeedback;
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT extVertexAttributeDivisor;
};
@ -27,6 +28,7 @@ namespace dxvk {
*/
struct DxvkDeviceFeatures {
VkPhysicalDeviceFeatures2KHR core;
VkPhysicalDeviceTransformFeedbackFeaturesEXT extTransformFeedback;
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT extVertexAttributeDivisor;
};

View File

@ -258,6 +258,7 @@ namespace dxvk {
*/
struct DxvkDeviceExtensions {
DxvkExt extShaderViewportIndexLayer = { VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, DxvkExtMode::Optional };
DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional };
DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional };
DxvkExt khrDedicatedAllocation = { VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, DxvkExtMode::Required };
DxvkExt khrDescriptorUpdateTemplate = { VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, DxvkExtMode::Required };

View File

@ -69,6 +69,9 @@ namespace dxvk {
m_vsIn = vs != nullptr ? vs->interfaceSlots().inputSlots : 0;
m_fsOut = fs != nullptr ? fs->interfaceSlots().outputSlots : 0;
if (gs != nullptr && gs->hasCapability(spv::CapabilityTransformFeedback))
m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback);
m_common.msSampleShadingEnable = fs != nullptr && fs->hasCapability(spv::CapabilitySampleRateShading);
m_common.msSampleShadingFactor = 1.0f;
@ -81,6 +84,25 @@ namespace dxvk {
}
Rc<DxvkShader> DxvkGraphicsPipeline::getShader(
VkShaderStageFlagBits stage) const {
switch (stage) {
case VK_SHADER_STAGE_VERTEX_BIT:
return m_vs != nullptr ? m_vs->shader() : nullptr;
case VK_SHADER_STAGE_GEOMETRY_BIT:
return m_gs != nullptr ? m_gs->shader() : nullptr;
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
return m_tcs != nullptr ? m_tcs->shader() : nullptr;
case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
return m_tes != nullptr ? m_tes->shader() : nullptr;
case VK_SHADER_STAGE_FRAGMENT_BIT:
return m_fs != nullptr ? m_fs->shader() : nullptr;
default:
return nullptr;
}
}
VkPipeline DxvkGraphicsPipeline::getPipelineHandle(
const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass) {
@ -207,7 +229,11 @@ namespace dxvk {
viDivisorDesc[id].divisor = state.ilDivisors[i];
}
}
int32_t rasterizedStream = m_gs != nullptr
? m_gs->shader()->shaderOptions().rasterizedStream
: 0;
VkPipelineVertexInputDivisorStateCreateInfoEXT viDivisorInfo;
viDivisorInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
viDivisorInfo.pNext = nullptr;
@ -252,12 +278,18 @@ namespace dxvk {
vpInfo.scissorCount = state.rsViewportCount;
vpInfo.pScissors = nullptr;
VkPipelineRasterizationStateStreamCreateInfoEXT xfbStreamInfo;
xfbStreamInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT;
xfbStreamInfo.pNext = nullptr;
xfbStreamInfo.flags = 0;
xfbStreamInfo.rasterizationStream = uint32_t(rasterizedStream);
VkPipelineRasterizationStateCreateInfo rsInfo;
rsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rsInfo.pNext = nullptr;
rsInfo.flags = 0;
rsInfo.depthClampEnable = state.rsDepthClampEnable;
rsInfo.rasterizerDiscardEnable= VK_FALSE;
rsInfo.rasterizerDiscardEnable = rasterizedStream < 0;
rsInfo.polygonMode = state.rsPolygonMode;
rsInfo.cullMode = state.rsCullMode;
rsInfo.frontFace = state.rsFrontFace;
@ -267,6 +299,9 @@ namespace dxvk {
rsInfo.depthBiasSlopeFactor = 0.0f;
rsInfo.lineWidth = 1.0f;
if (rasterizedStream > 0)
rsInfo.pNext = &xfbStreamInfo;
VkPipelineMultisampleStateCreateInfo msInfo;
msInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
msInfo.pNext = nullptr;

View File

@ -15,6 +15,16 @@ namespace dxvk {
class DxvkDevice;
class DxvkPipelineManager;
/**
* \brief Flags that describe pipeline properties
*/
enum class DxvkGraphicsPipelineFlag {
HasTransformFeedback,
};
using DxvkGraphicsCommonPipelineFlags = Flags<DxvkGraphicsPipelineFlag>;
/**
* \brief Graphics pipeline state info
@ -156,6 +166,14 @@ namespace dxvk {
const Rc<DxvkShader>& fs);
~DxvkGraphicsPipeline();
/**
* \brief Returns graphics pipeline flags
* \returns Graphics pipeline property flags
*/
DxvkGraphicsCommonPipelineFlags flags() const {
return m_flags;
}
/**
* \brief Pipeline layout
*
@ -168,6 +186,17 @@ namespace dxvk {
return m_layout.ptr();
}
/**
* \brief Queries shader for a given stage
*
* In case no shader is specified for the
* given stage, \c nullptr will be returned.
* \param [in] stage The shader stage
* \returns Shader of the given stage
*/
Rc<DxvkShader> getShader(
VkShaderStageFlagBits stage) const;
/**
* \brief Pipeline handle
*
@ -202,6 +231,7 @@ namespace dxvk {
uint32_t m_vsIn = 0;
uint32_t m_fsOut = 0;
DxvkGraphicsCommonPipelineFlags m_flags;
DxvkGraphicsCommonPipelineStateInfo m_common;
// List of pipeline instances, shared between threads

View File

@ -8,7 +8,8 @@ namespace dxvk {
MaxNumRenderTargets = 8,
MaxNumVertexAttributes = 32,
MaxNumVertexBindings = 32,
MaxNumOutputStreams = 4,
MaxNumXfbBuffers = 4,
MaxNumXfbStreams = 4,
MaxNumViewports = 16,
MaxNumResourceSlots = 1216,
MaxNumActiveBindings = 128,

View File

@ -4,8 +4,11 @@ namespace dxvk {
DxvkQuery::DxvkQuery(
VkQueryType type,
VkQueryControlFlags flags)
: m_type(type), m_flags(flags) {
VkQueryControlFlags flags,
uint32_t index)
: m_type (type),
m_flags (flags),
m_index (index) {
}
@ -15,6 +18,11 @@ namespace dxvk {
}
bool DxvkQuery::isIndexed() const {
return m_type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT;
}
uint32_t DxvkQuery::reset() {
std::unique_lock<std::mutex> lock(m_mutex);
@ -104,6 +112,11 @@ namespace dxvk {
m_data.statistic.csInvocations += data.statistic.csInvocations;
break;
case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT:
m_data.xfbStream.primitivesWritten += data.xfbStream.primitivesWritten;
m_data.xfbStream.primitivesNeeded += data.xfbStream.primitivesNeeded;
break;
default:
Logger::err(str::format("DxvkQuery: Unhandled query type: ", m_type));
}

View File

@ -58,6 +58,19 @@ namespace dxvk {
uint64_t tesInvocations;
uint64_t csInvocations;
};
/**
* \brief Transform feedback stream query
*
* Stores the number of primitives written to the
* buffer, as well as the number of primitives
* generated. The latter can be used to check for
* overflow.
*/
struct DxvkQueryXfbStreamData {
uint64_t primitivesWritten;
uint64_t primitivesNeeded;
};
/**
* \brief Query data
@ -69,6 +82,7 @@ namespace dxvk {
DxvkQueryOcclusionData occlusion;
DxvkQueryTimestampData timestamp;
DxvkQueryStatisticData statistic;
DxvkQueryXfbStreamData xfbStream;
};
/**
@ -81,6 +95,7 @@ namespace dxvk {
VkQueryPool queryPool = VK_NULL_HANDLE;
uint32_t queryId = 0;
VkQueryControlFlags flags = 0;
uint32_t index = 0;
};
/**
@ -91,12 +106,13 @@ namespace dxvk {
* submissions, we need to
*/
class DxvkQuery : public RcObject {
public:
DxvkQuery(
VkQueryType type,
VkQueryControlFlags flags);
VkQueryControlFlags flags,
uint32_t index = ~0u);
~DxvkQuery();
/**
@ -117,6 +133,24 @@ namespace dxvk {
VkQueryControlFlags flags() const {
return m_flags;
}
/**
* \brief Query type index
*
* The query type index. Will be undefined if the
* query type is not indexed. Not to be confused
* with the query index within the query pool.
* \returns Query type index
*/
uint32_t index() const {
return m_index;
}
/**
* \brief Checks whether the query type is indexed
* \returns \c true if the query type is indexed
*/
bool isIndexed() const;
/**
* \brief Resets the query object
@ -188,6 +222,7 @@ namespace dxvk {
const VkQueryType m_type;
const VkQueryControlFlags m_flags;
const uint32_t m_index;
std::mutex m_mutex;

View File

@ -44,14 +44,8 @@ namespace dxvk {
const DxvkQueryRevision& query) {
m_activeQueries.push_back(query);
if (m_activeTypes & getDxvkQueryTypeBit(query.query->type())) {
DxvkQueryHandle handle = this->allocQuery(cmd, query);
cmd->cmdBeginQuery(
handle.queryPool,
handle.queryId,
handle.flags);
}
if (m_activeTypes & getDxvkQueryTypeBit(query.query->type()))
this->beginVulkanQuery(cmd, query);
}
@ -69,13 +63,8 @@ namespace dxvk {
}
if (iter != m_activeQueries.end()) {
if (m_activeTypes & getDxvkQueryTypeBit(iter->query->type())) {
DxvkQueryHandle handle = iter->query->getHandle();
cmd->cmdEndQuery(
handle.queryPool,
handle.queryId);
}
if (m_activeTypes & getDxvkQueryTypeBit(iter->query->type()))
this->endVulkanQuery(cmd, query);
m_activeQueries.erase(iter);
}
@ -88,14 +77,8 @@ namespace dxvk {
m_activeTypes |= getDxvkQueryTypeBit(type);
for (const DxvkQueryRevision& query : m_activeQueries) {
if (type == query.query->type()) {
DxvkQueryHandle handle = this->allocQuery(cmd, query);
cmd->cmdBeginQuery(
handle.queryPool,
handle.queryId,
handle.flags);
}
if (type == query.query->type())
this->beginVulkanQuery(cmd, query);
}
}
@ -106,13 +89,8 @@ namespace dxvk {
m_activeTypes &= ~getDxvkQueryTypeBit(type);
for (const DxvkQueryRevision& query : m_activeQueries) {
if (type == query.query->type()) {
DxvkQueryHandle handle = query.query->getHandle();
cmd->cmdEndQuery(
handle.queryPool,
handle.queryId);
}
if (type == query.query->type())
this->endVulkanQuery(cmd, query);
}
}
@ -121,6 +99,7 @@ namespace dxvk {
this->trackQueryPool(cmd, m_occlusion);
this->trackQueryPool(cmd, m_pipeStats);
this->trackQueryPool(cmd, m_timestamp);
this->trackQueryPool(cmd, m_xfbStream);
}
@ -136,6 +115,44 @@ namespace dxvk {
}
void DxvkQueryManager::beginVulkanQuery(
const Rc<DxvkCommandList>& cmd,
const DxvkQueryRevision& query) {
DxvkQueryHandle handle = this->allocQuery(cmd, query);
if (query.query->isIndexed()) {
cmd->cmdBeginQueryIndexed(
handle.queryPool,
handle.queryId,
handle.flags,
handle.index);
} else {
cmd->cmdBeginQuery(
handle.queryPool,
handle.queryId,
handle.flags);
}
}
void DxvkQueryManager::endVulkanQuery(
const Rc<DxvkCommandList>& cmd,
const DxvkQueryRevision& query) {
DxvkQueryHandle handle = query.query->getHandle();
if (query.query->isIndexed()) {
cmd->cmdEndQueryIndexed(
handle.queryPool,
handle.queryId,
handle.index);
} else {
cmd->cmdEndQuery(
handle.queryPool,
handle.queryId);
}
}
Rc<DxvkQueryPool>& DxvkQueryManager::getQueryPool(VkQueryType type) {
switch (type) {
case VK_QUERY_TYPE_OCCLUSION:
@ -146,6 +163,9 @@ namespace dxvk {
case VK_QUERY_TYPE_TIMESTAMP:
return m_timestamp;
case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT:
return m_xfbStream;
default:
throw DxvkError("DXVK: Invalid query type");
@ -155,10 +175,11 @@ namespace dxvk {
uint32_t DxvkQueryManager::getDxvkQueryTypeBit(VkQueryType type) {
switch (type) {
case VK_QUERY_TYPE_OCCLUSION: return 0x01;
case VK_QUERY_TYPE_PIPELINE_STATISTICS: return 0x02;
case VK_QUERY_TYPE_TIMESTAMP: return 0x04;
default: return 0;
case VK_QUERY_TYPE_OCCLUSION: return 0x01;
case VK_QUERY_TYPE_PIPELINE_STATISTICS: return 0x02;
case VK_QUERY_TYPE_TIMESTAMP: return 0x04;
case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT: return 0x08;
default: return 0;
}
}

View File

@ -101,6 +101,7 @@ namespace dxvk {
Rc<DxvkQueryPool> m_occlusion;
Rc<DxvkQueryPool> m_pipeStats;
Rc<DxvkQueryPool> m_timestamp;
Rc<DxvkQueryPool> m_xfbStream;
std::vector<DxvkQueryRevision> m_activeQueries;
@ -108,6 +109,14 @@ namespace dxvk {
const Rc<DxvkCommandList>& cmd,
const Rc<DxvkQueryPool>& pool);
void beginVulkanQuery(
const Rc<DxvkCommandList>& cmd,
const DxvkQueryRevision& query);
void endVulkanQuery(
const Rc<DxvkCommandList>& cmd,
const DxvkQueryRevision& query);
Rc<DxvkQueryPool>& getQueryPool(
VkQueryType type);

View File

@ -54,6 +54,7 @@ namespace dxvk {
result.queryPool = m_queryPool;
result.queryId = queryIndex;
result.flags = query.query->flags();
result.index = query.query->index();
query.query->associateQuery(query.revision, result);
m_queries.at(queryIndex) = query;

View File

@ -121,7 +121,7 @@ namespace dxvk {
if (m_format.depth.format == VK_FORMAT_UNDEFINED)
subpass.pDepthStencilAttachment = nullptr;
const std::array<VkSubpassDependency, 2> subpassDeps = {{
const std::array<VkSubpassDependency, 3> subpassDeps = {{
{ VK_SUBPASS_EXTERNAL, 0,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
@ -130,11 +130,18 @@ namespace dxvk {
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 0 },
{ 0, 0,
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, /* XXX */
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT, 0 },
{ 0, VK_SUBPASS_EXTERNAL,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT |
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT |
VK_ACCESS_SHADER_WRITE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
@ -144,7 +151,8 @@ namespace dxvk {
VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_TRANSFER_READ_BIT |
VK_ACCESS_UNIFORM_READ_BIT |
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, 0 },
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT, 0 },
}};
VkRenderPassCreateInfo info;

View File

@ -81,9 +81,10 @@ namespace dxvk {
const DxvkResourceSlot* slotInfos,
const DxvkInterfaceSlots& iface,
const SpirvCodeBuffer& code,
const DxvkShaderOptions& options,
DxvkShaderConstData&& constData)
: m_stage(stage), m_code(code), m_interface(iface),
m_constData(std::move(constData)) {
m_options(options), m_constData(std::move(constData)) {
// Write back resource slot infos
for (uint32_t i = 0; i < slotCount; i++)
m_slots.push_back(slotInfos[i]);

View File

@ -50,6 +50,20 @@ namespace dxvk {
};
/**
* \brief Additional shader options
*
* Contains additional properties that should be
* taken into account when creating pipelines.
*/
struct DxvkShaderOptions {
/// Rasterized stream, or -1
int32_t rasterizedStream;
/// Xfb vertex strides
uint32_t xfbStrides[MaxNumXfbBuffers];
};
/**
* \brief Shader constants
*
@ -107,6 +121,7 @@ namespace dxvk {
const DxvkResourceSlot* slotInfos,
const DxvkInterfaceSlots& iface,
const SpirvCodeBuffer& code,
const DxvkShaderOptions& options,
DxvkShaderConstData&& constData);
~DxvkShader();
@ -164,6 +179,14 @@ namespace dxvk {
return m_interface;
}
/**
* \brief Shader options
* \returns Shader options
*/
DxvkShaderOptions shaderOptions() const {
return m_options;
}
/**
* \brief Shader constant data
*
@ -216,6 +239,7 @@ namespace dxvk {
std::vector<DxvkResourceSlot> m_slots;
std::vector<size_t> m_idOffsets;
DxvkInterfaceSlots m_interface;
DxvkShaderOptions m_options;
DxvkShaderConstData m_constData;
DxvkShaderKey m_key;

View File

@ -284,6 +284,15 @@ namespace dxvk::vk {
VULKAN_FN(vkGetBufferMemoryRequirements2KHR);
VULKAN_FN(vkGetImageMemoryRequirements2KHR);
#endif
#ifdef VK_EXT_transform_feedback
VULKAN_FN(vkCmdBindTransformFeedbackBuffersEXT);
VULKAN_FN(vkCmdBeginTransformFeedbackEXT);
VULKAN_FN(vkCmdEndTransformFeedbackEXT);
VULKAN_FN(vkCmdDrawIndirectByteCountEXT);
VULKAN_FN(vkCmdBeginQueryIndexedEXT);
VULKAN_FN(vkCmdEndQueryIndexedEXT);
#endif
};
}

View File

@ -438,6 +438,34 @@ namespace dxvk {
m_annotations.putInt32(specId);
}
void SpirvModule::decorateXfb(
uint32_t object,
uint32_t streamId,
uint32_t bufferId,
uint32_t offset,
uint32_t stride) {
m_annotations.putIns (spv::OpDecorate, 4);
m_annotations.putWord (object);
m_annotations.putWord (spv::DecorationStream);
m_annotations.putInt32(streamId);
m_annotations.putIns (spv::OpDecorate, 4);
m_annotations.putWord (object);
m_annotations.putWord (spv::DecorationXfbBuffer);
m_annotations.putInt32(bufferId);
m_annotations.putIns (spv::OpDecorate, 4);
m_annotations.putWord (object);
m_annotations.putWord (spv::DecorationXfbStride);
m_annotations.putInt32(stride);
m_annotations.putIns (spv::OpDecorate, 4);
m_annotations.putWord (object);
m_annotations.putWord (spv::DecorationOffset);
m_annotations.putInt32(offset);
}
void SpirvModule::memberDecorateBuiltIn(
uint32_t structId,
@ -2937,13 +2965,25 @@ namespace dxvk {
}
void SpirvModule::opEmitVertex() {
m_code.putIns (spv::OpEmitVertex, 1);
void SpirvModule::opEmitVertex(
uint32_t streamId) {
if (streamId == 0) {
m_code.putIns (spv::OpEmitVertex, 1);
} else {
m_code.putIns (spv::OpEmitStreamVertex, 2);
m_code.putWord(streamId);
}
}
void SpirvModule::opEndPrimitive() {
m_code.putIns (spv::OpEndPrimitive, 1);
void SpirvModule::opEndPrimitive(
uint32_t streamId) {
if (streamId == 0) {
m_code.putIns (spv::OpEndPrimitive, 1);
} else {
m_code.putIns (spv::OpEndStreamPrimitive, 2);
m_code.putWord(streamId);
}
}

View File

@ -197,6 +197,13 @@ namespace dxvk {
uint32_t object,
uint32_t specId);
void decorateXfb(
uint32_t object,
uint32_t streamId,
uint32_t bufferId,
uint32_t offset,
uint32_t stride);
void memberDecorateBuiltIn(
uint32_t structId,
uint32_t memberId,
@ -1022,9 +1029,11 @@ namespace dxvk {
void opKill();
void opEmitVertex();
void opEmitVertex(
uint32_t streamId);
void opEndPrimitive();
void opEndPrimitive(
uint32_t streamId);
private:

View File

@ -43,6 +43,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
DxbcModuleInfo moduleInfo;
moduleInfo.options = DxbcOptions();
moduleInfo.xfb = nullptr;
Rc<DxvkShader> shader = module.compile(moduleInfo, ifileName);
std::ofstream ofile(str::fromws(argv[2]), std::ios::binary);