mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-20 08:18:59 +02:00
[vk, gl, spv] Opcode Promotion path emulation
This commit is contained in:
parent
4cc99b9ff5
commit
178a0ce571
11 changed files with 391 additions and 75 deletions
|
|
@ -207,6 +207,7 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
|||
device.HasNvViewportArray2() || device.HasVertexViewportLayer(),
|
||||
.support_viewport_mask = device.HasNvViewportArray2(),
|
||||
.support_typeless_image_loads = device.HasImageLoadFormatted(),
|
||||
.support_sampled_1d = true,
|
||||
.support_demote_to_helper_invocation = false,
|
||||
.support_int64_atomics = false,
|
||||
.support_derivative_control = device.HasDerivativeControl(),
|
||||
|
|
@ -249,6 +250,7 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
|||
.needs_demote_reorder = device.IsAmd(),
|
||||
.support_snorm_render_buffer = false,
|
||||
.support_viewport_index_layer = device.HasVertexViewportLayer(),
|
||||
.support_sampled_1d = true,
|
||||
.min_ssbo_alignment = static_cast<u32>(device.GetShaderStorageBufferAlignment()),
|
||||
.support_geometry_shader_passthrough = device.HasGeometryShaderPassthrough(),
|
||||
.support_conditional_barrier = device.SupportsConditionalBarriers(),
|
||||
|
|
|
|||
|
|
@ -401,6 +401,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
|||
device.IsExtShaderViewportIndexLayerSupported(),
|
||||
.support_viewport_mask = device.IsNvViewportArray2Supported(),
|
||||
.support_typeless_image_loads = device.IsFormatlessImageLoadSupported(),
|
||||
.support_sampled_1d = device.SupportsSampled1D(),
|
||||
.support_demote_to_helper_invocation =
|
||||
device.IsExtShaderDemoteToHelperInvocationSupported(),
|
||||
.support_int64_atomics = device.IsExtShaderAtomicInt64Supported(),
|
||||
|
|
@ -444,6 +445,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
|||
driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY,
|
||||
.support_snorm_render_buffer = true,
|
||||
.support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(),
|
||||
.support_sampled_1d = device.SupportsSampled1D(),
|
||||
.min_ssbo_alignment = static_cast<u32>(device.GetStorageBufferAlignment()),
|
||||
.support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(),
|
||||
.support_conditional_barrier = device.SupportsConditionalBarriers(),
|
||||
|
|
|
|||
|
|
@ -126,9 +126,18 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
|
|||
return usage;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool Needs1DPromotion(const Device& device, ImageType type) {
|
||||
return type == ImageType::e1D && !device.SupportsSampled1D();
|
||||
}
|
||||
|
||||
[[nodiscard]] ImageType HostImageType(const Device& device, ImageType type) {
|
||||
return Needs1DPromotion(device, type) ? ImageType::e2D : type;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info) {
|
||||
const auto format_info =
|
||||
MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, false, info.format);
|
||||
const ImageType host_type = HostImageType(device, info.type);
|
||||
VkImageCreateFlags flags{};
|
||||
if (info.type == ImageType::e2D && info.resources.layers >= 6 &&
|
||||
info.size.width == info.size.height && !device.HasBrokenCubeImageCompatibility()) {
|
||||
|
|
@ -142,7 +151,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
|
|||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = flags,
|
||||
.imageType = ConvertImageType(info.type),
|
||||
.imageType = ConvertImageType(host_type),
|
||||
.format = format_info.format,
|
||||
.extent{
|
||||
.width = info.size.width >> samples_x,
|
||||
|
|
@ -273,10 +282,11 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
|
|||
return VK_COMPONENT_SWIZZLE_ZERO;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkImageViewType ImageViewType(Shader::TextureType type) {
|
||||
[[nodiscard]] VkImageViewType ImageViewType(const Device& device, Shader::TextureType type) {
|
||||
const bool promote_1d = !device.SupportsSampled1D();
|
||||
switch (type) {
|
||||
case Shader::TextureType::Color1D:
|
||||
return VK_IMAGE_VIEW_TYPE_1D;
|
||||
return promote_1d ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_1D;
|
||||
case Shader::TextureType::Color2D:
|
||||
case Shader::TextureType::Color2DRect:
|
||||
return VK_IMAGE_VIEW_TYPE_2D;
|
||||
|
|
@ -285,7 +295,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
|
|||
case Shader::TextureType::Color3D:
|
||||
return VK_IMAGE_VIEW_TYPE_3D;
|
||||
case Shader::TextureType::ColorArray1D:
|
||||
return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
|
||||
return promote_1d ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_1D_ARRAY;
|
||||
case Shader::TextureType::ColorArray2D:
|
||||
return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
case Shader::TextureType::ColorArrayCube:
|
||||
|
|
@ -2083,7 +2093,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
|||
};
|
||||
const auto create = [&](TextureType tex_type) {
|
||||
VkImageViewCreateInfo ci{create_info};
|
||||
ci.viewType = ImageViewType(tex_type);
|
||||
ci.viewType = ImageViewType(*device, tex_type);
|
||||
if (const auto override_layers = LayerCountOverride(tex_type)) {
|
||||
ci.subresourceRange.layerCount = *override_layers;
|
||||
}
|
||||
|
|
@ -2304,7 +2314,7 @@ vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_
|
|||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.image = image_handle,
|
||||
.viewType = ImageViewType(texture_type),
|
||||
.viewType = ImageViewType(*device, texture_type),
|
||||
.format = vk_format,
|
||||
.components{
|
||||
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
|
|
|
|||
|
|
@ -440,6 +440,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
|||
const bool is_turnip = driver_id == VK_DRIVER_ID_MESA_TURNIP;
|
||||
const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
|
||||
|
||||
// Qualcomm hardware (both proprietary and Turnip drivers) rejects Sampled1D capability.
|
||||
supports_sampled_1d = !(is_qualcomm || is_turnip);
|
||||
|
||||
if (!is_suitable)
|
||||
LOG_WARNING(Render_Vulkan, "Unsuitable driver - continuing anyways");
|
||||
|
||||
|
|
|
|||
|
|
@ -881,6 +881,10 @@ public:
|
|||
return features2.features.multiViewport;
|
||||
}
|
||||
|
||||
bool SupportsSampled1D() const {
|
||||
return supports_sampled_1d;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_KHR_maintenance1.
|
||||
bool IsKhrMaintenance1Supported() const {
|
||||
return extensions.maintenance1;
|
||||
|
|
@ -1108,6 +1112,7 @@ private:
|
|||
bool dynamic_state3_alpha_to_coverage{};
|
||||
bool dynamic_state3_alpha_to_one{};
|
||||
bool supports_conditional_barriers{}; ///< Allows barriers in conditional control flow.
|
||||
bool supports_sampled_1d{true}; ///< Supports declaring Sampled1D in shaders.
|
||||
size_t sampler_heap_budget{}; ///< Sampler budget for buggy drivers (0 = unlimited).
|
||||
VkDeviceSize uniform_buffer_alignment_minimum{}; ///< Minimum enforced UBO alignment.
|
||||
VkDeviceSize storage_buffer_alignment_minimum{}; ///< Minimum enforced SSBO alignment.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue