[Vulkan] Optional functionality usage improvements
Functional changes: - Enable only actually used features, as drivers may take more optimal paths when certain features are disabled. - Support VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE. - Fix the separateStencilMaskRef check doing the opposite. - Support shaderRoundingModeRTEFloat32. - Fix vkGetDeviceBufferMemoryRequirements pointer not passed to the Vulkan Memory Allocator. Stylistic changes: - Move all device extensions, properties and features to one structure, especially simplifying portability subset feature checks, and also making it easier to request new extension functionality in the future. - Remove extension suffixes from usage of promoted extensions.
This commit is contained in:
@@ -866,9 +866,6 @@ bool VulkanImmediateDrawer::CreateTextureResource(
|
||||
size_t& pending_upload_index_out) {
|
||||
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
|
||||
VkDevice device = provider_.device();
|
||||
const VkPhysicalDevicePortabilitySubsetFeaturesKHR*
|
||||
device_portability_subset_features =
|
||||
provider_.device_portability_subset_features();
|
||||
|
||||
// Create the image and the descriptor.
|
||||
|
||||
@@ -913,8 +910,7 @@ bool VulkanImmediateDrawer::CreateTextureResource(
|
||||
// data == nullptr is a special case for (1, 1, 1, 1), though the image will
|
||||
// be cleared to (1, 1, 1, 1) anyway, just a micro-optimization.
|
||||
VkComponentSwizzle swizzle =
|
||||
(data || (device_portability_subset_features &&
|
||||
!device_portability_subset_features->imageViewFormatSwizzle))
|
||||
(data || !provider_.device_info().imageViewFormatSwizzle)
|
||||
? VK_COMPONENT_SWIZZLE_IDENTITY
|
||||
: VK_COMPONENT_SWIZZLE_ONE;
|
||||
image_view_create_info.components.r = swizzle;
|
||||
|
||||
@@ -27,8 +27,7 @@ VmaAllocator CreateVmaAllocator(const VulkanProvider& provider,
|
||||
const VulkanProvider::DeviceFunctions& dfn = provider.dfn();
|
||||
const VulkanProvider::InstanceExtensions& instance_extensions =
|
||||
provider.instance_extensions();
|
||||
const VulkanProvider::DeviceExtensions& device_extensions =
|
||||
provider.device_extensions();
|
||||
const VulkanProvider::DeviceInfo& device_info = provider.device_info();
|
||||
|
||||
VmaVulkanFunctions vma_vulkan_functions = {};
|
||||
VmaAllocatorCreateInfo allocator_create_info = {};
|
||||
@@ -58,31 +57,33 @@ VmaAllocator CreateVmaAllocator(const VulkanProvider& provider,
|
||||
vma_vulkan_functions.vkCreateImage = dfn.vkCreateImage;
|
||||
vma_vulkan_functions.vkDestroyImage = dfn.vkDestroyImage;
|
||||
vma_vulkan_functions.vkCmdCopyBuffer = dfn.vkCmdCopyBuffer;
|
||||
if (device_extensions.khr_get_memory_requirements2) {
|
||||
if (device_info.ext_1_1_VK_KHR_get_memory_requirements2) {
|
||||
vma_vulkan_functions.vkGetBufferMemoryRequirements2KHR =
|
||||
dfn.vkGetBufferMemoryRequirements2KHR;
|
||||
dfn.vkGetBufferMemoryRequirements2;
|
||||
vma_vulkan_functions.vkGetImageMemoryRequirements2KHR =
|
||||
dfn.vkGetImageMemoryRequirements2KHR;
|
||||
if (device_extensions.khr_dedicated_allocation) {
|
||||
dfn.vkGetImageMemoryRequirements2;
|
||||
if (device_info.ext_1_1_VK_KHR_dedicated_allocation) {
|
||||
allocator_create_info.flags |=
|
||||
VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT;
|
||||
}
|
||||
}
|
||||
if (device_extensions.khr_bind_memory2) {
|
||||
vma_vulkan_functions.vkBindBufferMemory2KHR = dfn.vkBindBufferMemory2KHR;
|
||||
vma_vulkan_functions.vkBindImageMemory2KHR = dfn.vkBindImageMemory2KHR;
|
||||
if (device_info.ext_1_1_VK_KHR_bind_memory2) {
|
||||
vma_vulkan_functions.vkBindBufferMemory2KHR = dfn.vkBindBufferMemory2;
|
||||
vma_vulkan_functions.vkBindImageMemory2KHR = dfn.vkBindImageMemory2;
|
||||
allocator_create_info.flags |= VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT;
|
||||
}
|
||||
if (instance_extensions.khr_get_physical_device_properties2) {
|
||||
vma_vulkan_functions.vkGetPhysicalDeviceMemoryProperties2KHR =
|
||||
ifn.vkGetPhysicalDeviceMemoryProperties2KHR;
|
||||
if (device_extensions.ext_memory_budget) {
|
||||
ifn.vkGetPhysicalDeviceMemoryProperties2;
|
||||
if (device_info.ext_VK_EXT_memory_budget) {
|
||||
allocator_create_info.flags |= VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT;
|
||||
}
|
||||
}
|
||||
if (device_extensions.khr_maintenance4) {
|
||||
if (device_info.ext_1_3_VK_KHR_maintenance4) {
|
||||
vma_vulkan_functions.vkGetDeviceBufferMemoryRequirements =
|
||||
dfn.vkGetDeviceBufferMemoryRequirements;
|
||||
vma_vulkan_functions.vkGetDeviceImageMemoryRequirements =
|
||||
dfn.vkGetDeviceImageMemoryRequirementsKHR;
|
||||
dfn.vkGetDeviceImageMemoryRequirements;
|
||||
}
|
||||
|
||||
if (externally_synchronized) {
|
||||
@@ -93,8 +94,7 @@ VmaAllocator CreateVmaAllocator(const VulkanProvider& provider,
|
||||
allocator_create_info.device = provider.device();
|
||||
allocator_create_info.pVulkanFunctions = &vma_vulkan_functions;
|
||||
allocator_create_info.instance = provider.instance();
|
||||
allocator_create_info.vulkanApiVersion =
|
||||
provider.device_properties().apiVersion;
|
||||
allocator_create_info.vulkanApiVersion = device_info.apiVersion;
|
||||
VmaAllocator allocator;
|
||||
if (vmaCreateAllocator(&allocator_create_info, &allocator) != VK_SUCCESS) {
|
||||
XELOGE("Failed to create a Vulkan Memory Allocator instance");
|
||||
|
||||
@@ -208,7 +208,7 @@ VulkanPresenter::~VulkanPresenter() {
|
||||
}
|
||||
|
||||
Surface::TypeFlags VulkanPresenter::GetSupportedSurfaceTypes() const {
|
||||
if (!provider_.device_extensions().khr_swapchain) {
|
||||
if (!provider_.device_info().ext_VK_KHR_swapchain) {
|
||||
return 0;
|
||||
}
|
||||
return GetSurfaceTypesSupportedByInstance(provider_.instance_extensions());
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -57,6 +57,160 @@ namespace vulkan {
|
||||
|
||||
class VulkanProvider : public GraphicsProvider {
|
||||
public:
|
||||
struct DeviceInfo {
|
||||
// "ext_1_X"-prefixed extension fields are set to true not only if the
|
||||
// extension itself is actually exposed, but also if it was promoted to the
|
||||
// device's API version. Therefore, merely the field being set to true
|
||||
// doesn't imply that all the required features in the extension are
|
||||
// supported - actual properties and features must be checked rather than
|
||||
// the extension itself where they matter.
|
||||
|
||||
// Vulkan 1.0.
|
||||
|
||||
uint32_t memory_types_device_local;
|
||||
uint32_t memory_types_host_visible;
|
||||
uint32_t memory_types_host_coherent;
|
||||
uint32_t memory_types_host_cached;
|
||||
|
||||
uint32_t apiVersion;
|
||||
uint32_t maxImageDimension2D;
|
||||
uint32_t maxImageDimension3D;
|
||||
uint32_t maxImageDimensionCube;
|
||||
uint32_t maxImageArrayLayers;
|
||||
uint32_t maxStorageBufferRange;
|
||||
uint32_t maxSamplerAllocationCount;
|
||||
uint32_t maxPerStageDescriptorSamplers;
|
||||
uint32_t maxPerStageDescriptorStorageBuffers;
|
||||
uint32_t maxPerStageDescriptorSampledImages;
|
||||
uint32_t maxPerStageResources;
|
||||
uint32_t maxVertexOutputComponents;
|
||||
uint32_t maxTessellationEvaluationOutputComponents;
|
||||
uint32_t maxGeometryInputComponents;
|
||||
uint32_t maxGeometryOutputComponents;
|
||||
uint32_t maxGeometryTotalOutputComponents;
|
||||
uint32_t maxFragmentInputComponents;
|
||||
uint32_t maxFragmentCombinedOutputResources;
|
||||
float maxSamplerAnisotropy;
|
||||
uint32_t maxViewportDimensions[2];
|
||||
float viewportBoundsRange[2];
|
||||
VkDeviceSize minUniformBufferOffsetAlignment;
|
||||
VkDeviceSize minStorageBufferOffsetAlignment;
|
||||
uint32_t maxFramebufferWidth;
|
||||
uint32_t maxFramebufferHeight;
|
||||
VkSampleCountFlags framebufferColorSampleCounts;
|
||||
VkSampleCountFlags framebufferDepthSampleCounts;
|
||||
VkSampleCountFlags framebufferStencilSampleCounts;
|
||||
VkSampleCountFlags framebufferNoAttachmentsSampleCounts;
|
||||
VkSampleCountFlags sampledImageColorSampleCounts;
|
||||
VkSampleCountFlags sampledImageIntegerSampleCounts;
|
||||
VkSampleCountFlags sampledImageDepthSampleCounts;
|
||||
VkSampleCountFlags sampledImageStencilSampleCounts;
|
||||
VkSampleCountFlags standardSampleLocations;
|
||||
VkDeviceSize optimalBufferCopyOffsetAlignment;
|
||||
VkDeviceSize optimalBufferCopyRowPitchAlignment;
|
||||
VkDeviceSize nonCoherentAtomSize;
|
||||
|
||||
bool fullDrawIndexUint32;
|
||||
bool independentBlend;
|
||||
bool geometryShader;
|
||||
bool tessellationShader;
|
||||
bool sampleRateShading;
|
||||
bool depthClamp;
|
||||
bool fillModeNonSolid;
|
||||
bool samplerAnisotropy;
|
||||
bool vertexPipelineStoresAndAtomics;
|
||||
bool fragmentStoresAndAtomics;
|
||||
bool shaderClipDistance;
|
||||
bool shaderCullDistance;
|
||||
bool sparseBinding;
|
||||
bool sparseResidencyBuffer;
|
||||
|
||||
// VK_KHR_swapchain (#2).
|
||||
|
||||
bool ext_VK_KHR_swapchain;
|
||||
|
||||
// VK_KHR_sampler_mirror_clamp_to_edge (#15, Vulkan 1.2).
|
||||
|
||||
bool ext_1_2_VK_KHR_sampler_mirror_clamp_to_edge;
|
||||
|
||||
bool samplerMirrorClampToEdge;
|
||||
|
||||
// VK_KHR_dedicated_allocation (#128, Vulkan 1.1).
|
||||
|
||||
bool ext_1_1_VK_KHR_dedicated_allocation;
|
||||
|
||||
// VK_EXT_shader_stencil_export (#141).
|
||||
|
||||
bool ext_VK_EXT_shader_stencil_export;
|
||||
|
||||
// VK_KHR_get_memory_requirements2 (#147, Vulkan 1.1).
|
||||
|
||||
bool ext_1_1_VK_KHR_get_memory_requirements2;
|
||||
|
||||
// VK_KHR_image_format_list (#148, Vulkan 1.2).
|
||||
|
||||
bool ext_1_2_VK_KHR_image_format_list;
|
||||
|
||||
// VK_KHR_sampler_ycbcr_conversion (#157, Vulkan 1.1).
|
||||
|
||||
bool ext_1_1_VK_KHR_sampler_ycbcr_conversion;
|
||||
|
||||
// VK_KHR_bind_memory2 (#158, Vulkan 1.1).
|
||||
|
||||
bool ext_1_1_VK_KHR_bind_memory2;
|
||||
|
||||
// VK_KHR_portability_subset (#164).
|
||||
|
||||
bool ext_VK_KHR_portability_subset;
|
||||
|
||||
bool constantAlphaColorBlendFactors;
|
||||
bool imageViewFormatReinterpretation;
|
||||
bool imageViewFormatSwizzle;
|
||||
bool pointPolygons;
|
||||
bool separateStencilMaskRef;
|
||||
bool shaderSampleRateInterpolationFunctions;
|
||||
bool triangleFans;
|
||||
|
||||
// VK_KHR_shader_float_controls (#198, Vulkan 1.2).
|
||||
|
||||
bool ext_1_2_VK_KHR_shader_float_controls;
|
||||
|
||||
bool shaderSignedZeroInfNanPreserveFloat32;
|
||||
bool shaderDenormFlushToZeroFloat32;
|
||||
bool shaderRoundingModeRTEFloat32;
|
||||
|
||||
// VK_KHR_spirv_1_4 (#237, Vulkan 1.2).
|
||||
|
||||
bool ext_1_2_VK_KHR_spirv_1_4;
|
||||
|
||||
// VK_EXT_memory_budget (#238).
|
||||
|
||||
bool ext_VK_EXT_memory_budget;
|
||||
|
||||
// VK_EXT_fragment_shader_interlock (#252).
|
||||
|
||||
bool ext_VK_EXT_fragment_shader_interlock;
|
||||
|
||||
bool fragmentShaderSampleInterlock;
|
||||
bool fragmentShaderPixelInterlock;
|
||||
|
||||
// VK_EXT_shader_demote_to_helper_invocation (#277, Vulkan 1.3).
|
||||
|
||||
bool ext_1_3_VK_EXT_shader_demote_to_helper_invocation;
|
||||
|
||||
bool shaderDemoteToHelperInvocation;
|
||||
|
||||
// VK_KHR_maintenance4 (#414, Vulkan 1.3).
|
||||
|
||||
bool ext_1_3_VK_KHR_maintenance4;
|
||||
|
||||
// VK_EXT_non_seamless_cube_map (#423).
|
||||
|
||||
bool ext_VK_EXT_non_seamless_cube_map;
|
||||
|
||||
bool nonSeamlessCubeMap;
|
||||
};
|
||||
|
||||
~VulkanProvider();
|
||||
|
||||
static std::unique_ptr<VulkanProvider> Create(bool is_surface_required);
|
||||
@@ -106,7 +260,7 @@ class VulkanProvider : public GraphicsProvider {
|
||||
struct InstanceFunctions {
|
||||
#define XE_UI_VULKAN_FUNCTION(name) PFN_##name name;
|
||||
#define XE_UI_VULKAN_FUNCTION_PROMOTED(extension_name, core_name) \
|
||||
PFN_##extension_name extension_name;
|
||||
PFN_##core_name core_name;
|
||||
#include "xenia/ui/vulkan/functions/instance_1_0.inc"
|
||||
#include "xenia/ui/vulkan/functions/instance_ext_debug_utils.inc"
|
||||
#include "xenia/ui/vulkan/functions/instance_khr_get_physical_device_properties2.inc"
|
||||
@@ -124,61 +278,9 @@ class VulkanProvider : public GraphicsProvider {
|
||||
const InstanceFunctions& ifn() const { return ifn_; }
|
||||
|
||||
VkPhysicalDevice physical_device() const { return physical_device_; }
|
||||
const VkPhysicalDeviceProperties& device_properties() const {
|
||||
return device_properties_;
|
||||
}
|
||||
const VkPhysicalDeviceFeatures& device_features() const {
|
||||
return device_features_;
|
||||
}
|
||||
struct DeviceExtensions {
|
||||
bool ext_fragment_shader_interlock;
|
||||
bool ext_memory_budget;
|
||||
// Core since 1.3.0.
|
||||
bool ext_shader_demote_to_helper_invocation;
|
||||
bool ext_shader_stencil_export;
|
||||
// Core since 1.1.0.
|
||||
bool khr_bind_memory2;
|
||||
// Core since 1.1.0.
|
||||
bool khr_dedicated_allocation;
|
||||
// Core since 1.1.0.
|
||||
bool khr_get_memory_requirements2;
|
||||
// Core since 1.2.0.
|
||||
bool khr_image_format_list;
|
||||
// Core since 1.3.0.
|
||||
bool khr_maintenance4;
|
||||
// Requires the VK_KHR_get_physical_device_properties2 instance extension.
|
||||
bool khr_portability_subset;
|
||||
// Core since 1.1.0.
|
||||
bool khr_sampler_ycbcr_conversion;
|
||||
// Core since 1.2.0.
|
||||
bool khr_shader_float_controls;
|
||||
// Core since 1.2.0.
|
||||
bool khr_spirv_1_4;
|
||||
bool khr_swapchain;
|
||||
};
|
||||
const DeviceExtensions& device_extensions() const {
|
||||
return device_extensions_;
|
||||
}
|
||||
// Returns nullptr if the device is fully compliant with Vulkan 1.0.
|
||||
const VkPhysicalDevicePortabilitySubsetFeaturesKHR*
|
||||
device_portability_subset_features() const {
|
||||
if (!device_extensions_.khr_portability_subset) {
|
||||
return nullptr;
|
||||
}
|
||||
return &device_portability_subset_features_;
|
||||
}
|
||||
uint32_t memory_types_device_local() const {
|
||||
return memory_types_device_local_;
|
||||
}
|
||||
uint32_t memory_types_host_visible() const {
|
||||
return memory_types_host_visible_;
|
||||
}
|
||||
uint32_t memory_types_host_coherent() const {
|
||||
return memory_types_host_coherent_;
|
||||
}
|
||||
uint32_t memory_types_host_cached() const {
|
||||
return memory_types_host_cached_;
|
||||
}
|
||||
|
||||
const DeviceInfo& device_info() const { return device_info_; }
|
||||
|
||||
struct QueueFamily {
|
||||
uint32_t queue_first_index = 0;
|
||||
uint32_t queue_count = 0;
|
||||
@@ -196,18 +298,6 @@ class VulkanProvider : public GraphicsProvider {
|
||||
uint32_t queue_family_sparse_binding() const {
|
||||
return queue_family_sparse_binding_;
|
||||
}
|
||||
const VkPhysicalDeviceFloatControlsPropertiesKHR&
|
||||
device_float_controls_properties() const {
|
||||
return device_float_controls_properties_;
|
||||
}
|
||||
const VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT&
|
||||
device_fragment_shader_interlock_features() const {
|
||||
return device_fragment_shader_interlock_features_;
|
||||
}
|
||||
const VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT&
|
||||
device_shader_demote_to_helper_invocation_features() const {
|
||||
return device_shader_demote_to_helper_invocation_features_;
|
||||
}
|
||||
|
||||
struct Queue {
|
||||
VkQueue queue = VK_NULL_HANDLE;
|
||||
@@ -235,7 +325,7 @@ class VulkanProvider : public GraphicsProvider {
|
||||
struct DeviceFunctions {
|
||||
#define XE_UI_VULKAN_FUNCTION(name) PFN_##name name;
|
||||
#define XE_UI_VULKAN_FUNCTION_PROMOTED(extension_name, core_name) \
|
||||
PFN_##extension_name extension_name;
|
||||
PFN_##core_name core_name;
|
||||
#include "xenia/ui/vulkan/functions/device_1_0.inc"
|
||||
#include "xenia/ui/vulkan/functions/device_khr_bind_memory2.inc"
|
||||
#include "xenia/ui/vulkan/functions/device_khr_get_memory_requirements2.inc"
|
||||
@@ -261,10 +351,6 @@ class VulkanProvider : public GraphicsProvider {
|
||||
ifn_.vkSetDebugUtilsObjectNameEXT(device_, &name_info);
|
||||
}
|
||||
|
||||
bool IsSparseBindingSupported() const {
|
||||
return queue_family_sparse_binding_ != UINT32_MAX;
|
||||
}
|
||||
|
||||
// Samplers that may be useful for host needs. Only these samplers should be
|
||||
// used in host, non-emulation contexts, because the total number of samplers
|
||||
// is heavily limited (4000) on Nvidia GPUs - the rest of samplers are
|
||||
@@ -298,6 +384,12 @@ class VulkanProvider : public GraphicsProvider {
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* callback_data,
|
||||
void* user_data);
|
||||
|
||||
// For the current `physical_device_`, sets up the members obtained from the
|
||||
// physical device info, and tries to create a device and get the needed
|
||||
// queues.
|
||||
// The call is successful if `device_` is not VK_NULL_HANDLE as a result.
|
||||
void TryCreateDevice();
|
||||
|
||||
bool is_surface_required_;
|
||||
|
||||
RenderdocApi renderdoc_api_;
|
||||
@@ -313,30 +405,21 @@ class VulkanProvider : public GraphicsProvider {
|
||||
InstanceExtensions instance_extensions_;
|
||||
VkInstance instance_ = VK_NULL_HANDLE;
|
||||
InstanceFunctions ifn_;
|
||||
|
||||
VkDebugUtilsMessengerEXT debug_messenger_ = VK_NULL_HANDLE;
|
||||
bool debug_names_used_ = false;
|
||||
|
||||
VkPhysicalDevice physical_device_ = VK_NULL_HANDLE;
|
||||
VkPhysicalDeviceProperties device_properties_;
|
||||
VkPhysicalDeviceFeatures device_features_;
|
||||
DeviceExtensions device_extensions_;
|
||||
VkPhysicalDevicePortabilitySubsetFeaturesKHR
|
||||
device_portability_subset_features_;
|
||||
uint32_t memory_types_device_local_;
|
||||
uint32_t memory_types_host_visible_;
|
||||
uint32_t memory_types_host_coherent_;
|
||||
uint32_t memory_types_host_cached_;
|
||||
|
||||
DeviceInfo device_info_ = {};
|
||||
|
||||
std::vector<QueueFamily> queue_families_;
|
||||
uint32_t queue_family_graphics_compute_;
|
||||
uint32_t queue_family_sparse_binding_;
|
||||
VkPhysicalDeviceFloatControlsPropertiesKHR device_float_controls_properties_;
|
||||
VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT
|
||||
device_fragment_shader_interlock_features_;
|
||||
VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT
|
||||
device_shader_demote_to_helper_invocation_features_;
|
||||
|
||||
VkDevice device_ = VK_NULL_HANDLE;
|
||||
DeviceFunctions dfn_ = {};
|
||||
|
||||
// Queues contain a mutex, can't use std::vector.
|
||||
std::unique_ptr<Queue[]> queues_;
|
||||
|
||||
|
||||
@@ -138,13 +138,13 @@ VulkanUploadBufferPool::CreatePageImplementation() {
|
||||
memory_allocate_info.pNext = nullptr;
|
||||
memory_allocate_info.allocationSize = allocation_size_;
|
||||
memory_allocate_info.memoryTypeIndex = memory_type_;
|
||||
VkMemoryDedicatedAllocateInfoKHR memory_dedicated_allocate_info;
|
||||
if (provider_.device_extensions().khr_dedicated_allocation) {
|
||||
VkMemoryDedicatedAllocateInfo memory_dedicated_allocate_info;
|
||||
if (provider_.device_info().ext_1_1_VK_KHR_dedicated_allocation) {
|
||||
memory_allocate_info_last->pNext = &memory_dedicated_allocate_info;
|
||||
memory_allocate_info_last = reinterpret_cast<VkMemoryAllocateInfo*>(
|
||||
&memory_dedicated_allocate_info);
|
||||
memory_dedicated_allocate_info.sType =
|
||||
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR;
|
||||
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
|
||||
memory_dedicated_allocate_info.pNext = nullptr;
|
||||
memory_dedicated_allocate_info.image = VK_NULL_HANDLE;
|
||||
memory_dedicated_allocate_info.buffer = buffer;
|
||||
|
||||
@@ -27,8 +27,8 @@ void FlushMappedMemoryRange(const VulkanProvider& provider,
|
||||
assert_false(size != VK_WHOLE_SIZE && memory_size == VK_WHOLE_SIZE);
|
||||
assert_true(memory_size == VK_WHOLE_SIZE || offset <= memory_size);
|
||||
assert_true(memory_size == VK_WHOLE_SIZE || size <= memory_size - offset);
|
||||
if (!size ||
|
||||
(provider.memory_types_host_coherent() & (uint32_t(1) << memory_type))) {
|
||||
if (!size || (provider.device_info().memory_types_host_coherent &
|
||||
(uint32_t(1) << memory_type))) {
|
||||
return;
|
||||
}
|
||||
VkMappedMemoryRange range;
|
||||
@@ -38,7 +38,7 @@ void FlushMappedMemoryRange(const VulkanProvider& provider,
|
||||
range.offset = offset;
|
||||
range.size = size;
|
||||
VkDeviceSize non_coherent_atom_size =
|
||||
provider.device_properties().limits.nonCoherentAtomSize;
|
||||
provider.device_info().nonCoherentAtomSize;
|
||||
// On some Android implementations, nonCoherentAtomSize is 0, not 1.
|
||||
if (non_coherent_atom_size > 1) {
|
||||
range.offset = offset / non_coherent_atom_size * non_coherent_atom_size;
|
||||
@@ -89,13 +89,13 @@ bool CreateDedicatedAllocationBuffer(
|
||||
memory_allocate_info.pNext = nullptr;
|
||||
memory_allocate_info.allocationSize = memory_requirements.size;
|
||||
memory_allocate_info.memoryTypeIndex = memory_type;
|
||||
VkMemoryDedicatedAllocateInfoKHR memory_dedicated_allocate_info;
|
||||
if (provider.device_extensions().khr_dedicated_allocation) {
|
||||
VkMemoryDedicatedAllocateInfo memory_dedicated_allocate_info;
|
||||
if (provider.device_info().ext_1_1_VK_KHR_dedicated_allocation) {
|
||||
memory_allocate_info_last->pNext = &memory_dedicated_allocate_info;
|
||||
memory_allocate_info_last = reinterpret_cast<VkMemoryAllocateInfo*>(
|
||||
&memory_dedicated_allocate_info);
|
||||
memory_dedicated_allocate_info.sType =
|
||||
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR;
|
||||
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
|
||||
memory_dedicated_allocate_info.pNext = nullptr;
|
||||
memory_dedicated_allocate_info.image = VK_NULL_HANDLE;
|
||||
memory_dedicated_allocate_info.buffer = buffer;
|
||||
@@ -154,13 +154,13 @@ bool CreateDedicatedAllocationImage(const VulkanProvider& provider,
|
||||
memory_allocate_info.pNext = nullptr;
|
||||
memory_allocate_info.allocationSize = memory_requirements.size;
|
||||
memory_allocate_info.memoryTypeIndex = memory_type;
|
||||
VkMemoryDedicatedAllocateInfoKHR memory_dedicated_allocate_info;
|
||||
if (provider.device_extensions().khr_dedicated_allocation) {
|
||||
VkMemoryDedicatedAllocateInfo memory_dedicated_allocate_info;
|
||||
if (provider.device_info().ext_1_1_VK_KHR_dedicated_allocation) {
|
||||
memory_allocate_info_last->pNext = &memory_dedicated_allocate_info;
|
||||
memory_allocate_info_last = reinterpret_cast<VkMemoryAllocateInfo*>(
|
||||
&memory_dedicated_allocate_info);
|
||||
memory_dedicated_allocate_info.sType =
|
||||
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR;
|
||||
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
|
||||
memory_dedicated_allocate_info.pNext = nullptr;
|
||||
memory_dedicated_allocate_info.image = image;
|
||||
memory_dedicated_allocate_info.buffer = VK_NULL_HANDLE;
|
||||
|
||||
@@ -50,7 +50,7 @@ enum class MemoryPurpose {
|
||||
inline VkDeviceSize GetMappableMemorySize(const VulkanProvider& provider,
|
||||
VkDeviceSize size) {
|
||||
VkDeviceSize non_coherent_atom_size =
|
||||
provider.device_properties().limits.nonCoherentAtomSize;
|
||||
provider.device_info().nonCoherentAtomSize;
|
||||
// On some Android implementations, nonCoherentAtomSize is 0, not 1.
|
||||
if (non_coherent_atom_size > 1) {
|
||||
size = xe::round_up(size, non_coherent_atom_size, false);
|
||||
@@ -61,8 +61,8 @@ inline VkDeviceSize GetMappableMemorySize(const VulkanProvider& provider,
|
||||
inline uint32_t ChooseHostMemoryType(const VulkanProvider& provider,
|
||||
uint32_t supported_types,
|
||||
bool is_readback) {
|
||||
supported_types &= provider.memory_types_host_visible();
|
||||
uint32_t host_cached = provider.memory_types_host_cached();
|
||||
supported_types &= provider.device_info().memory_types_host_visible;
|
||||
uint32_t host_cached = provider.device_info().memory_types_host_cached;
|
||||
uint32_t memory_type;
|
||||
// For upload, uncached is preferred so writes do not pollute the CPU cache.
|
||||
// For readback, cached is preferred so multiple CPU reads are fast.
|
||||
@@ -107,12 +107,12 @@ void FlushMappedMemoryRange(const VulkanProvider& provider,
|
||||
VkDeviceSize size = VK_WHOLE_SIZE);
|
||||
|
||||
inline VkExtent2D GetMax2DFramebufferExtent(const VulkanProvider& provider) {
|
||||
const VkPhysicalDeviceLimits& limits = provider.device_properties().limits;
|
||||
const VulkanProvider::DeviceInfo& device_info = provider.device_info();
|
||||
VkExtent2D max_extent;
|
||||
max_extent.width =
|
||||
std::min(limits.maxFramebufferWidth, limits.maxImageDimension2D);
|
||||
max_extent.height =
|
||||
std::min(limits.maxFramebufferHeight, limits.maxImageDimension2D);
|
||||
max_extent.width = std::min(device_info.maxFramebufferWidth,
|
||||
device_info.maxImageDimension2D);
|
||||
max_extent.height = std::min(device_info.maxFramebufferHeight,
|
||||
device_info.maxImageDimension2D);
|
||||
return max_extent;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user