mirror of
https://github.com/skyline-emu/skyline.git
synced 2025-02-11 22:18:45 +03:00
Implement Maxwell3D Samplers
Maxwell3D `TextureSamplerControl` (TSC) are fully converted into Vulkan samplers with extension backing for all aspects that require them (border color/reduction mode) and approximations where Vulkan doesn't support certain functionality (sampler address mode) alongside cases where extensions may not be present (border color).
This commit is contained in:
parent
e48a7d7009
commit
87c8dc94d2
@ -120,7 +120,7 @@ namespace skyline::gpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vk::raii::Device GPU::CreateDevice(const vk::raii::PhysicalDevice &physicalDevice, decltype(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex, QuirkManager &quirks) {
|
vk::raii::Device GPU::CreateDevice(const vk::raii::PhysicalDevice &physicalDevice, decltype(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex, QuirkManager &quirks) {
|
||||||
auto deviceFeatures2{physicalDevice.getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vk::PhysicalDeviceShaderFloat16Int8Features, vk::PhysicalDeviceShaderAtomicInt64Features>()};
|
auto deviceFeatures2{physicalDevice.getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceCustomBorderColorFeaturesEXT, vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vk::PhysicalDeviceShaderFloat16Int8Features, vk::PhysicalDeviceShaderAtomicInt64Features>()};
|
||||||
decltype(deviceFeatures2) enabledFeatures2{}; // We only want to enable features we required due to potential overhead from unused features
|
decltype(deviceFeatures2) enabledFeatures2{}; // We only want to enable features we required due to potential overhead from unused features
|
||||||
|
|
||||||
#define FEAT_REQ(structName, feature) \
|
#define FEAT_REQ(structName, feature) \
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <soc/gm20b/engines/maxwell/types.h>
|
#include <soc/gm20b/engines/maxwell/types.h>
|
||||||
|
|
||||||
#include "command_executor.h"
|
#include "command_executor.h"
|
||||||
|
#include "types/tsc.h"
|
||||||
|
|
||||||
namespace skyline::gpu::interconnect {
|
namespace skyline::gpu::interconnect {
|
||||||
namespace maxwell3d = soc::gm20b::engine::maxwell3d::type;
|
namespace maxwell3d = soc::gm20b::engine::maxwell3d::type;
|
||||||
@ -1547,6 +1548,211 @@ namespace skyline::gpu::interconnect {
|
|||||||
private:
|
private:
|
||||||
u32 bindlessTextureConstantBufferIndex{};
|
u32 bindlessTextureConstantBufferIndex{};
|
||||||
|
|
||||||
|
/* Samplers */
|
||||||
|
private:
|
||||||
|
struct Sampler : public vk::raii::Sampler, public FenceCycleDependency {
|
||||||
|
using vk::raii::Sampler::Sampler;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SamplerPool {
|
||||||
|
IOVA iova;
|
||||||
|
u32 maximumIndex;
|
||||||
|
span<TextureSamplerControl> samplerControls;
|
||||||
|
std::unordered_map<TextureSamplerControl, std::shared_ptr<Sampler>, util::ObjectHash<TextureSamplerControl>> samplers;
|
||||||
|
} samplerPool{};
|
||||||
|
|
||||||
|
public:
|
||||||
|
void SetSamplerPoolIovaHigh(u32 high) {
|
||||||
|
samplerPool.iova.high = high;
|
||||||
|
samplerPool.samplerControls = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSamplerPoolIovaLow(u32 low) {
|
||||||
|
samplerPool.iova.low = low;
|
||||||
|
samplerPool.samplerControls = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSamplerPoolMaximumIndex(u32 index) {
|
||||||
|
samplerPool.maximumIndex = index;
|
||||||
|
samplerPool.samplerControls = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::Filter ConvertSamplerFilter(TextureSamplerControl::Filter filter) {
|
||||||
|
using TscFilter = TextureSamplerControl::Filter;
|
||||||
|
using VkFilter = vk::Filter;
|
||||||
|
switch (filter) {
|
||||||
|
// @fmt:off
|
||||||
|
|
||||||
|
case TscFilter::Nearest: return VkFilter::eNearest;
|
||||||
|
case TscFilter::Linear: return VkFilter::eLinear;
|
||||||
|
|
||||||
|
// @fmt:on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::SamplerMipmapMode ConvertSamplerMipFilter(TextureSamplerControl::MipFilter filter) {
|
||||||
|
using TscFilter = TextureSamplerControl::MipFilter;
|
||||||
|
using VkMode = vk::SamplerMipmapMode;
|
||||||
|
switch (filter) {
|
||||||
|
// @fmt:off
|
||||||
|
|
||||||
|
case TscFilter::None: return VkMode{};
|
||||||
|
case TscFilter::Nearest: return VkMode::eNearest;
|
||||||
|
case TscFilter::Linear: return VkMode::eLinear;
|
||||||
|
|
||||||
|
// @fmt:on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::SamplerAddressMode ConvertSamplerAddressMode(TextureSamplerControl::AddressMode mode) {
|
||||||
|
using TscMode = TextureSamplerControl::AddressMode;
|
||||||
|
using VkMode = vk::SamplerAddressMode;
|
||||||
|
switch (mode) {
|
||||||
|
// @fmt:off
|
||||||
|
|
||||||
|
case TscMode::Repeat: return VkMode::eRepeat;
|
||||||
|
case TscMode::MirroredRepeat: return VkMode::eMirroredRepeat;
|
||||||
|
|
||||||
|
case TscMode::ClampToEdge: return VkMode::eClampToEdge;
|
||||||
|
case TscMode::ClampToBorder: return VkMode::eClampToBorder;
|
||||||
|
case TscMode::Clamp: return VkMode::eClampToEdge; // Vulkan doesn't support 'GL_CLAMP' so this is an approximation
|
||||||
|
|
||||||
|
case TscMode::MirrorClampToEdge: return VkMode::eMirrorClampToEdge;
|
||||||
|
case TscMode::MirrorClampToBorder: return VkMode::eMirrorClampToEdge; // Only supported mirror clamps are to edges so this is an approximation
|
||||||
|
case TscMode::MirrorClamp: return VkMode::eMirrorClampToEdge; // Same as above
|
||||||
|
|
||||||
|
// @fmt:on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::CompareOp ConvertSamplerCompareOp(TextureSamplerControl::CompareOp compareOp) {
|
||||||
|
using TscOp = TextureSamplerControl::CompareOp;
|
||||||
|
using VkOp = vk::CompareOp;
|
||||||
|
switch (compareOp) {
|
||||||
|
// @fmt:off
|
||||||
|
|
||||||
|
case TscOp::Never: return VkOp::eNever;
|
||||||
|
case TscOp::Less: return VkOp::eLess;
|
||||||
|
case TscOp::Equal: return VkOp::eEqual;
|
||||||
|
case TscOp::LessOrEqual: return VkOp::eLessOrEqual;
|
||||||
|
case TscOp::Greater: return VkOp::eGreater;
|
||||||
|
case TscOp::NotEqual: return VkOp::eNotEqual;
|
||||||
|
case TscOp::GreaterOrEqual: return VkOp::eGreaterOrEqual;
|
||||||
|
case TscOp::Always: return VkOp::eAlways;
|
||||||
|
|
||||||
|
// @fmt:on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::SamplerReductionMode ConvertSamplerReductionFilter(TextureSamplerControl::SamplerReduction reduction) {
|
||||||
|
using TscReduction = TextureSamplerControl::SamplerReduction;
|
||||||
|
using VkReduction = vk::SamplerReductionMode;
|
||||||
|
switch (reduction) {
|
||||||
|
// @fmt:off
|
||||||
|
|
||||||
|
case TscReduction::WeightedAverage: return VkReduction::eWeightedAverage;
|
||||||
|
case TscReduction::Min: return VkReduction::eMin;
|
||||||
|
case TscReduction::Max: return VkReduction::eMax;
|
||||||
|
|
||||||
|
// @fmt:on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::BorderColor ConvertBorderColorWithCustom(float red, float green, float blue, float alpha) {
|
||||||
|
if (alpha == 1.0f) {
|
||||||
|
if (red == 1.0f && green == 1.0f && blue == 1.0f)
|
||||||
|
return vk::BorderColor::eFloatOpaqueWhite;
|
||||||
|
else if (red == 0.0f && green == 0.0f && blue == 0.0f)
|
||||||
|
return vk::BorderColor::eFloatOpaqueBlack;
|
||||||
|
} else if (red == 1.0f && green == 1.0f && blue == 1.0f && alpha == 0.0f) {
|
||||||
|
return vk::BorderColor::eFloatTransparentBlack;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vk::BorderColor::eFloatCustomEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::BorderColor ConvertBorderColorFixed(float red, float green, float blue, float alpha) {
|
||||||
|
if (alpha == 1.0f) {
|
||||||
|
if (red == 1.0f && green == 1.0f && blue == 1.0f)
|
||||||
|
return vk::BorderColor::eFloatOpaqueWhite;
|
||||||
|
else if (red == 0.0f && green == 0.0f && blue == 0.0f)
|
||||||
|
return vk::BorderColor::eFloatOpaqueBlack;
|
||||||
|
} else if (red == 1.0f && green == 1.0f && blue == 1.0f && alpha == 0.0f) {
|
||||||
|
return vk::BorderColor::eFloatTransparentBlack;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Approximations of a custom color using fixed colors
|
||||||
|
if (red + green + blue > 1.0f)
|
||||||
|
return vk::BorderColor::eFloatOpaqueWhite;
|
||||||
|
else if (alpha > 0.0f)
|
||||||
|
return vk::BorderColor::eFloatOpaqueBlack;
|
||||||
|
else
|
||||||
|
return vk::BorderColor::eFloatTransparentBlack;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Sampler> GetSampler(u32 index) {
|
||||||
|
if (!samplerPool.samplerControls.valid()) {
|
||||||
|
auto mappings{channelCtx.asCtx->gmmu.TranslateRange(samplerPool.iova, samplerPool.maximumIndex * sizeof(TextureSamplerControl))};
|
||||||
|
if (mappings.size() != 1)
|
||||||
|
throw exception("Sampler pool mapping count is unexpected: {}", mappings.size());
|
||||||
|
samplerPool.samplerControls = mappings.front().cast<TextureSamplerControl>();
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureSamplerControl &samplerControl{samplerPool.samplerControls[index]};
|
||||||
|
auto &sampler{samplerPool.samplers[samplerControl]};
|
||||||
|
if (sampler)
|
||||||
|
return sampler;
|
||||||
|
|
||||||
|
auto convertAddressModeWithCheck{[&](TextureSamplerControl::AddressMode mode) {
|
||||||
|
auto vkMode{ConvertSamplerAddressMode(mode)};
|
||||||
|
if (vkMode == vk::SamplerAddressMode::eMirrorClampToEdge && !gpu.quirks.supportsSamplerMirrorClampToEdge) [[unlikely]] {
|
||||||
|
Logger::Warn("Cannot use Mirror Clamp To Edge as Sampler Address Mode without host GPU support");
|
||||||
|
return vk::SamplerAddressMode::eClampToEdge; // We use a normal clamp to edge to approximate it
|
||||||
|
}
|
||||||
|
return vkMode;
|
||||||
|
}};
|
||||||
|
|
||||||
|
auto maxAnisotropy{samplerControl.MaxAnisotropy()};
|
||||||
|
vk::StructureChain<vk::SamplerCreateInfo, vk::SamplerReductionModeCreateInfoEXT, vk::SamplerCustomBorderColorCreateInfoEXT> samplerInfo{
|
||||||
|
vk::SamplerCreateInfo{
|
||||||
|
.magFilter = ConvertSamplerFilter(samplerControl.magFilter),
|
||||||
|
.minFilter = ConvertSamplerFilter(samplerControl.minFilter),
|
||||||
|
.mipmapMode = ConvertSamplerMipFilter(samplerControl.mipFilter),
|
||||||
|
.addressModeU = convertAddressModeWithCheck(samplerControl.addressModeU),
|
||||||
|
.addressModeV = convertAddressModeWithCheck(samplerControl.addressModeV),
|
||||||
|
.addressModeW = convertAddressModeWithCheck(samplerControl.addressModeP),
|
||||||
|
.mipLodBias = samplerControl.MipLodBias(),
|
||||||
|
.anisotropyEnable = maxAnisotropy > 1.0f,
|
||||||
|
.maxAnisotropy = maxAnisotropy,
|
||||||
|
.compareEnable = samplerControl.depthCompareEnable,
|
||||||
|
.compareOp = ConvertSamplerCompareOp(samplerControl.depthCompareOp),
|
||||||
|
.minLod = samplerControl.MinLodClamp(),
|
||||||
|
.maxLod = samplerControl.MaxLodClamp(),
|
||||||
|
.unnormalizedCoordinates = false,
|
||||||
|
}, vk::SamplerReductionModeCreateInfoEXT{
|
||||||
|
.reductionMode = ConvertSamplerReductionFilter(samplerControl.reductionFilter),
|
||||||
|
}, vk::SamplerCustomBorderColorCreateInfoEXT{
|
||||||
|
.customBorderColor.float32 = {{samplerControl.borderColorR, samplerControl.borderColorG, samplerControl.borderColorB, samplerControl.borderColorA}},
|
||||||
|
.format = vk::Format::eUndefined,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!gpu.quirks.supportsSamplerReductionMode)
|
||||||
|
samplerInfo.unlink<vk::SamplerReductionModeCreateInfoEXT>();
|
||||||
|
|
||||||
|
vk::BorderColor &borderColor{samplerInfo.get<vk::SamplerCreateInfo>().borderColor};
|
||||||
|
if (gpu.quirks.supportsCustomBorderColor) {
|
||||||
|
borderColor = ConvertBorderColorWithCustom(samplerControl.borderColorR, samplerControl.borderColorG, samplerControl.borderColorB, samplerControl.borderColorA);
|
||||||
|
if (borderColor != vk::BorderColor::eFloatCustomEXT)
|
||||||
|
samplerInfo.unlink<vk::SamplerCustomBorderColorCreateInfoEXT>();
|
||||||
|
} else {
|
||||||
|
borderColor = ConvertBorderColorFixed(samplerControl.borderColorR, samplerControl.borderColorG, samplerControl.borderColorB, samplerControl.borderColorA);
|
||||||
|
samplerInfo.unlink<vk::SamplerCustomBorderColorCreateInfoEXT>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sampler = std::make_shared<Sampler>(gpu.vkDevice, samplerInfo.get<vk::SamplerCreateInfo>());
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void SetBindlessTextureConstantBufferIndex(u32 index) {
|
void SetBindlessTextureConstantBufferIndex(u32 index) {
|
||||||
bindlessTextureConstantBufferIndex = index;
|
bindlessTextureConstantBufferIndex = index;
|
||||||
|
136
app/src/main/cpp/skyline/gpu/interconnect/types/tsc.h
Normal file
136
app/src/main/cpp/skyline/gpu/interconnect/types/tsc.h
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
// Copyright © 2018-2020 fincs (https://github.com/devkitPro/deko3d)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <common/base.h>
|
||||||
|
|
||||||
|
namespace skyline::gpu::interconnect {
|
||||||
|
/**
|
||||||
|
* @brief The Texture Sampler Control is a descriptor used to configure the texture sampler in Maxwell GPUs
|
||||||
|
* @url https://github.com/envytools/envytools/blob/master/rnndb/graph/g80_texture.xml#L367
|
||||||
|
* @url https://github.com/devkitPro/deko3d/blob/00c12d1f4809014f1cc22719dd2e3476735eec64/source/maxwell/texture_sampler_control_block.h
|
||||||
|
*/
|
||||||
|
struct TextureSamplerControl {
|
||||||
|
enum class AddressMode : u32 {
|
||||||
|
Repeat = 0,
|
||||||
|
MirroredRepeat = 1,
|
||||||
|
ClampToEdge = 2,
|
||||||
|
ClampToBorder = 3,
|
||||||
|
Clamp = 4,
|
||||||
|
MirrorClampToEdge = 5,
|
||||||
|
MirrorClampToBorder = 6,
|
||||||
|
MirrorClamp = 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class CompareOp : u32 {
|
||||||
|
Never = 0,
|
||||||
|
Less = 1,
|
||||||
|
Equal = 2,
|
||||||
|
LessOrEqual = 3,
|
||||||
|
Greater = 4,
|
||||||
|
NotEqual = 5,
|
||||||
|
GreaterOrEqual = 6,
|
||||||
|
Always = 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Filter : u32 {
|
||||||
|
Nearest = 1,
|
||||||
|
Linear = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MipFilter : u32 {
|
||||||
|
None = 1,
|
||||||
|
Nearest = 2,
|
||||||
|
Linear = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SamplerReduction : u32 {
|
||||||
|
WeightedAverage = 0,
|
||||||
|
Min = 1,
|
||||||
|
Max = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 0x00
|
||||||
|
AddressMode addressModeU : 3;
|
||||||
|
AddressMode addressModeV : 3;
|
||||||
|
AddressMode addressModeP : 3;
|
||||||
|
u32 depthCompareEnable : 1;
|
||||||
|
CompareOp depthCompareOp : 3;
|
||||||
|
u32 srgbConversion : 1;
|
||||||
|
u32 fontFilterWidth : 3;
|
||||||
|
u32 fontFilterHeight : 3;
|
||||||
|
u32 maxAnisotropy : 3;
|
||||||
|
u32 _pad0_ : 9;
|
||||||
|
|
||||||
|
// 0x04
|
||||||
|
Filter magFilter : 2;
|
||||||
|
u32 _pad1_ : 2;
|
||||||
|
Filter minFilter : 2;
|
||||||
|
MipFilter mipFilter : 2;
|
||||||
|
u32 cubemapAnisotropy : 1;
|
||||||
|
u32 cubemapInterfaceFiltering : 1;
|
||||||
|
SamplerReduction reductionFilter : 2;
|
||||||
|
signed int mipLodBias : 13;
|
||||||
|
u32 floatCoordNormalization : 1;
|
||||||
|
u32 trilinearOptimization : 5;
|
||||||
|
u32 _pad2_ : 1;
|
||||||
|
|
||||||
|
// 0x08
|
||||||
|
u32 minLodClamp : 12;
|
||||||
|
u32 maxLodClamp : 12;
|
||||||
|
u32 srgbBorderColorR : 8;
|
||||||
|
|
||||||
|
// 0x0C
|
||||||
|
u32 _pad3_ : 12;
|
||||||
|
u32 srgbBorderColorG : 8;
|
||||||
|
u32 srgbBorderColorB : 8;
|
||||||
|
u32 _pad4_ : 4;
|
||||||
|
|
||||||
|
// 0x10
|
||||||
|
float borderColorR;
|
||||||
|
|
||||||
|
// 0x14
|
||||||
|
float borderColorG;
|
||||||
|
|
||||||
|
// 0x18
|
||||||
|
float borderColorB;
|
||||||
|
|
||||||
|
// 0x1C
|
||||||
|
float borderColorA;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Convert a fixed point integer to a floating point integer
|
||||||
|
*/
|
||||||
|
template<typename T, size_t FractionalBits = 8>
|
||||||
|
float ConvertFixedToFloat(T fixed) {
|
||||||
|
return static_cast<float>(fixed) / static_cast<float>(1 << FractionalBits);
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool operator==(const TextureSamplerControl&) const = default;
|
||||||
|
|
||||||
|
float MaxAnisotropy() {
|
||||||
|
constexpr size_t AnisotropyCount{8}; //!< The amount of unique anisotropy values that can be represented (2^3 — 3-bit value)
|
||||||
|
constexpr std::array<float, AnisotropyCount> anisotropyLut{
|
||||||
|
1.0f, 3.14f, 5.28f, 7.42f, 9.57f, 11.71f, 13.85f, 16.0f
|
||||||
|
}; //!< A linear mapping of value range (0..7) to anisotropy range (1..16) calculated using `(index * 15 / 7) + 1`
|
||||||
|
return anisotropyLut[maxAnisotropy];
|
||||||
|
}
|
||||||
|
|
||||||
|
float MipLodBias() {
|
||||||
|
return ConvertFixedToFloat(mipLodBias);
|
||||||
|
}
|
||||||
|
|
||||||
|
float MinLodClamp() {
|
||||||
|
return ConvertFixedToFloat(minLodClamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
float MaxLodClamp() {
|
||||||
|
return ConvertFixedToFloat(maxLodClamp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(TextureSamplerControl) == 0x20);
|
||||||
|
}
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
namespace skyline::gpu {
|
namespace skyline::gpu {
|
||||||
QuirkManager::QuirkManager(const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions, const DeviceProperties2 &deviceProperties2) {
|
QuirkManager::QuirkManager(const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions, const DeviceProperties2 &deviceProperties2) {
|
||||||
bool hasShaderAtomicInt64{}, hasShaderFloat16Int8Ext{};
|
bool hasCustomBorderColorExtension{}, hasShaderAtomicInt64{}, hasShaderFloat16Int8Ext{};
|
||||||
|
|
||||||
for (auto &extension : deviceExtensions) {
|
for (auto &extension : deviceExtensions) {
|
||||||
#define EXT_SET(name, property) \
|
#define EXT_SET(name, property) \
|
||||||
@ -28,6 +28,9 @@ namespace skyline::gpu {
|
|||||||
auto extensionVersion{extension.specVersion};
|
auto extensionVersion{extension.specVersion};
|
||||||
switch (util::Hash(extensionName)) {
|
switch (util::Hash(extensionName)) {
|
||||||
EXT_SET("VK_EXT_index_type_uint8", supportsUint8Indices);
|
EXT_SET("VK_EXT_index_type_uint8", supportsUint8Indices);
|
||||||
|
EXT_SET("VK_EXT_sampler_mirror_clamp_to_edge", supportsSamplerMirrorClampToEdge);
|
||||||
|
EXT_SET("VK_EXT_sampler_filter_minmax", supportsSamplerReductionMode);
|
||||||
|
EXT_SET("VK_EXT_custom_border_color", hasCustomBorderColorExtension);
|
||||||
EXT_SET("VK_EXT_provoking_vertex", supportsLastProvokingVertex);
|
EXT_SET("VK_EXT_provoking_vertex", supportsLastProvokingVertex);
|
||||||
EXT_SET("VK_EXT_vertex_attribute_divisor", supportsVertexAttributeDivisor);
|
EXT_SET("VK_EXT_vertex_attribute_divisor", supportsVertexAttributeDivisor);
|
||||||
EXT_SET("VK_EXT_shader_viewport_index_layer", supportsShaderViewportIndexLayer);
|
EXT_SET("VK_EXT_shader_viewport_index_layer", supportsShaderViewportIndexLayer);
|
||||||
@ -53,6 +56,16 @@ namespace skyline::gpu {
|
|||||||
FEAT_SET(vk::PhysicalDeviceFeatures2, features.shaderInt64, supportsInt64)
|
FEAT_SET(vk::PhysicalDeviceFeatures2, features.shaderInt64, supportsInt64)
|
||||||
FEAT_SET(vk::PhysicalDeviceFeatures2, features.shaderStorageImageReadWithoutFormat, supportsImageReadWithoutFormat)
|
FEAT_SET(vk::PhysicalDeviceFeatures2, features.shaderStorageImageReadWithoutFormat, supportsImageReadWithoutFormat)
|
||||||
|
|
||||||
|
if (hasCustomBorderColorExtension) {
|
||||||
|
bool hasCustomBorderColorFeature{};
|
||||||
|
FEAT_SET(vk::PhysicalDeviceCustomBorderColorFeaturesEXT, customBorderColors, hasCustomBorderColorFeature)
|
||||||
|
if (hasCustomBorderColorFeature)
|
||||||
|
// We only want to mark custom border colors as supported if it can be done without supplying a format
|
||||||
|
FEAT_SET(vk::PhysicalDeviceCustomBorderColorFeaturesEXT, customBorderColorWithoutFormat, supportsCustomBorderColor)
|
||||||
|
} else {
|
||||||
|
enabledFeatures2.unlink<vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT>();
|
||||||
|
}
|
||||||
|
|
||||||
if (supportsVertexAttributeDivisor) {
|
if (supportsVertexAttributeDivisor) {
|
||||||
FEAT_SET(vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vertexAttributeInstanceRateDivisor, supportsVertexAttributeDivisor)
|
FEAT_SET(vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vertexAttributeInstanceRateDivisor, supportsVertexAttributeDivisor)
|
||||||
FEAT_SET(vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vertexAttributeInstanceRateZeroDivisor, supportsVertexAttributeZeroDivisor)
|
FEAT_SET(vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vertexAttributeInstanceRateZeroDivisor, supportsVertexAttributeZeroDivisor)
|
||||||
@ -85,6 +98,9 @@ namespace skyline::gpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string QuirkManager::Summary() {
|
std::string QuirkManager::Summary() {
|
||||||
return fmt::format("\n* Supports U8 Indices: {}\n* Supports Last Provoking Vertex: {}\n* Supports Logical Operations: {}\n* Supports Vertex Attribute Divisor: {}\n* Supports Vertex Attribute Zero Divisor: {}\n* Supports Multiple Viewports: {}\n* Supports Shader Viewport Index: {}\n* Supports SPIR-V 1.4: {}\n* Supports 16-bit FP: {}\n* Supports 8-bit Integers: {}\n* Supports 16-bit Integers: {}\n* Supports 64-bit Integers: {}\n* Supports Atomic 64-bit Integers: {}\n* Supports Floating Point Behavior Control: {}\n* Supports Image Read Without Format: {}\n* Supports Subgroup Vote: {}\n* Subgroup Size: {}", supportsUint8Indices, supportsLastProvokingVertex, supportsLogicOp, supportsVertexAttributeDivisor, supportsVertexAttributeZeroDivisor, supportsMultipleViewports, supportsShaderViewportIndexLayer, supportsSpirv14, supportsFloat16, supportsInt8, supportsInt16, supportsInt64, supportsAtomicInt64, supportsFloatControls, supportsImageReadWithoutFormat, supportsSubgroupVote, subgroupSize);
|
return fmt::format(
|
||||||
|
"\n* Supports U8 Indices: {}\n* Supports Sampler Mirror Clamp To Edge: {}\n* Supports Sampler Reduction Mode: {}\n* Supports Custom Border Color (Without Format): {}\n* Supports Last Provoking Vertex: {}\n* Supports Logical Operations: {}\n* Supports Vertex Attribute Divisor: {}\n* Supports Vertex Attribute Zero Divisor: {}\n* Supports Multiple Viewports: {}\n* Supports Shader Viewport Index: {}\n* Supports SPIR-V 1.4: {}\n* Supports 16-bit FP: {}\n* Supports 8-bit Integers: {}\n* Supports 16-bit Integers: {}\n* Supports 64-bit Integers: {}\n* Supports Atomic 64-bit Integers: {}\n* Supports Floating Point Behavior Control: {}\n* Supports Image Read Without Format: {}\n* Supports Subgroup Vote: {}\n* Subgroup Size: {}",
|
||||||
|
supportsUint8Indices, supportsSamplerMirrorClampToEdge, supportsSamplerReductionMode, supportsCustomBorderColor, supportsLastProvokingVertex, supportsLogicOp, supportsVertexAttributeDivisor, supportsVertexAttributeZeroDivisor, supportsMultipleViewports, supportsShaderViewportIndexLayer, supportsSpirv14, supportsFloat16, supportsInt8, supportsInt16, supportsInt64, supportsAtomicInt64, supportsFloatControls, supportsImageReadWithoutFormat, supportsSubgroupVote, subgroupSize
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,10 @@ namespace skyline::gpu {
|
|||||||
*/
|
*/
|
||||||
class QuirkManager {
|
class QuirkManager {
|
||||||
public:
|
public:
|
||||||
bool supportsUint8Indices{}; //!< If the device supports using uint8 indices in index buffers
|
bool supportsUint8Indices{}; //!< If the device supports using uint8 indices in index buffers (with VK_EXT_index_type_uint8)
|
||||||
|
bool supportsSamplerMirrorClampToEdge{}; //!< If the device supports a mirrored clamp to edge as a sampler address mode (with VK_KHR_sampler_mirror_clamp_to_edge)
|
||||||
|
bool supportsSamplerReductionMode{}; //!< If the device supports explicitly specifying a reduction mode for sampling (with VK_EXT_sampler_filter_minmax)
|
||||||
|
bool supportsCustomBorderColor{}; //!< If the device supports a custom border color without format (VK_EXT_custom_border_color)
|
||||||
bool supportsLastProvokingVertex{}; //!< If the device supports setting the last vertex as the provoking vertex (with VK_EXT_provoking_vertex)
|
bool supportsLastProvokingVertex{}; //!< If the device supports setting the last vertex as the provoking vertex (with VK_EXT_provoking_vertex)
|
||||||
bool supportsLogicOp{}; //!< If the device supports framebuffer logical operations during blending
|
bool supportsLogicOp{}; //!< If the device supports framebuffer logical operations during blending
|
||||||
bool supportsVertexAttributeDivisor{}; //!< If the device supports a divisor for instance-rate vertex attributes (with VK_EXT_vertex_attribute_divisor)
|
bool supportsVertexAttributeDivisor{}; //!< If the device supports a divisor for instance-rate vertex attributes (with VK_EXT_vertex_attribute_divisor)
|
||||||
@ -35,7 +38,7 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
using DeviceProperties2 = vk::StructureChain<vk::PhysicalDeviceProperties2, vk::PhysicalDeviceFloatControlsProperties, vk::PhysicalDeviceSubgroupProperties>;
|
using DeviceProperties2 = vk::StructureChain<vk::PhysicalDeviceProperties2, vk::PhysicalDeviceFloatControlsProperties, vk::PhysicalDeviceSubgroupProperties>;
|
||||||
|
|
||||||
using DeviceFeatures2 = vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vk::PhysicalDeviceShaderFloat16Int8Features, vk::PhysicalDeviceShaderAtomicInt64Features>;
|
using DeviceFeatures2 = vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceCustomBorderColorFeaturesEXT, vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vk::PhysicalDeviceShaderFloat16Int8Features, vk::PhysicalDeviceShaderAtomicInt64Features>;
|
||||||
|
|
||||||
QuirkManager(const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions, const DeviceProperties2 &deviceProperties2);
|
QuirkManager(const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions, const DeviceProperties2 &deviceProperties2);
|
||||||
|
|
||||||
|
@ -467,6 +467,16 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
context.SetBindlessTextureConstantBufferIndex(bindlessTextureConstantBufferIndex);
|
context.SetBindlessTextureConstantBufferIndex(bindlessTextureConstantBufferIndex);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
MAXWELL3D_STRUCT_STRUCT_CASE(samplerPool, address, high, {
|
||||||
|
context.SetSamplerPoolIovaHigh(high);
|
||||||
|
})
|
||||||
|
MAXWELL3D_STRUCT_STRUCT_CASE(samplerPool, address, low, {
|
||||||
|
context.SetSamplerPoolIovaLow(low);
|
||||||
|
})
|
||||||
|
MAXWELL3D_STRUCT_CASE(samplerPool, maximumIndex, {
|
||||||
|
context.SetSamplerPoolMaximumIndex(maximumIndex);
|
||||||
|
})
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user