summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2019-12-14 22:30:12 -0500
committerGravatar GitHub2019-12-14 22:30:12 -0500
commit3d511536114c28d19cf700077ca98b77743311e0 (patch)
treedc2c3d3a7881269f651e9963dc7db851922756d5 /src
parentMerge pull request #3224 from bunnei/boost-ext-update (diff)
parentmaxwell_to_vk: Improve image format table and add more formats (diff)
downloadyuzu-3d511536114c28d19cf700077ca98b77743311e0.tar.gz
yuzu-3d511536114c28d19cf700077ca98b77743311e0.tar.xz
yuzu-3d511536114c28d19cf700077ca98b77743311e0.zip
Merge pull request #3222 from ReinUsesLisp/maxwell-to-vk
maxwell_to_vk: Use VK_EXT_index_type_uint8 and misc changes
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.cpp329
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.h18
-rw-r--r--src/video_core/renderer_vulkan/vk_sampler_cache.cpp7
3 files changed, 243 insertions, 111 deletions
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
index 7f0eb6b74..000e3616d 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
@@ -44,7 +44,8 @@ vk::SamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filt
44 return {}; 44 return {};
45} 45}
46 46
47vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode) { 47vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode,
48 Tegra::Texture::TextureFilter filter) {
48 switch (wrap_mode) { 49 switch (wrap_mode) {
49 case Tegra::Texture::WrapMode::Wrap: 50 case Tegra::Texture::WrapMode::Wrap:
50 return vk::SamplerAddressMode::eRepeat; 51 return vk::SamplerAddressMode::eRepeat;
@@ -55,10 +56,15 @@ vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode) {
55 case Tegra::Texture::WrapMode::Border: 56 case Tegra::Texture::WrapMode::Border:
56 return vk::SamplerAddressMode::eClampToBorder; 57 return vk::SamplerAddressMode::eClampToBorder;
57 case Tegra::Texture::WrapMode::Clamp: 58 case Tegra::Texture::WrapMode::Clamp:
58 // TODO(Rodrigo): GL_CLAMP was removed as of OpenGL 3.1, to implement GL_CLAMP, we can use 59 // TODO(Rodrigo): Emulate GL_CLAMP properly
59 // eClampToBorder to get the border color of the texture, and then sample the edge to 60 switch (filter) {
60 // manually mix them. However the shader part of this is not yet implemented. 61 case Tegra::Texture::TextureFilter::Nearest:
61 return vk::SamplerAddressMode::eClampToBorder; 62 return vk::SamplerAddressMode::eClampToEdge;
63 case Tegra::Texture::TextureFilter::Linear:
64 return vk::SamplerAddressMode::eClampToBorder;
65 }
66 UNREACHABLE();
67 return vk::SamplerAddressMode::eClampToEdge;
62 case Tegra::Texture::WrapMode::MirrorOnceClampToEdge: 68 case Tegra::Texture::WrapMode::MirrorOnceClampToEdge:
63 return vk::SamplerAddressMode::eMirrorClampToEdge; 69 return vk::SamplerAddressMode::eMirrorClampToEdge;
64 case Tegra::Texture::WrapMode::MirrorOnceBorder: 70 case Tegra::Texture::WrapMode::MirrorOnceBorder:
@@ -96,106 +102,140 @@ vk::CompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compar
96 102
97} // namespace Sampler 103} // namespace Sampler
98 104
105namespace {
106
107enum : u32 { Attachable = 1, Storage = 2 };
108
99struct FormatTuple { 109struct FormatTuple {
100 vk::Format format; ///< Vulkan format 110 vk::Format format; ///< Vulkan format
101 bool attachable; ///< True when this format can be used as an attachment 111 int usage; ///< Describes image format usage
102}; 112} constexpr tex_format_tuples[] = {
103 113 {vk::Format::eA8B8G8R8UnormPack32, Attachable | Storage}, // ABGR8U
104static constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format_tuples = {{ 114 {vk::Format::eA8B8G8R8SnormPack32, Attachable | Storage}, // ABGR8S
105 {vk::Format::eA8B8G8R8UnormPack32, true}, // ABGR8U 115 {vk::Format::eA8B8G8R8UintPack32, Attachable | Storage}, // ABGR8UI
106 {vk::Format::eUndefined, false}, // ABGR8S 116 {vk::Format::eB5G6R5UnormPack16, {}}, // B5G6R5U
107 {vk::Format::eUndefined, false}, // ABGR8UI 117 {vk::Format::eA2B10G10R10UnormPack32, Attachable | Storage}, // A2B10G10R10U
108 {vk::Format::eB5G6R5UnormPack16, false}, // B5G6R5U 118 {vk::Format::eA1R5G5B5UnormPack16, Attachable | Storage}, // A1B5G5R5U (flipped with swizzle)
109 {vk::Format::eA2B10G10R10UnormPack32, true}, // A2B10G10R10U 119 {vk::Format::eR8Unorm, Attachable | Storage}, // R8U
110 {vk::Format::eUndefined, false}, // A1B5G5R5U 120 {vk::Format::eR8Uint, Attachable | Storage}, // R8UI
111 {vk::Format::eR8Unorm, true}, // R8U 121 {vk::Format::eR16G16B16A16Sfloat, Attachable | Storage}, // RGBA16F
112 {vk::Format::eUndefined, false}, // R8UI 122 {vk::Format::eR16G16B16A16Unorm, Attachable | Storage}, // RGBA16U
113 {vk::Format::eUndefined, false}, // RGBA16F 123 {vk::Format::eR16G16B16A16Uint, Attachable | Storage}, // RGBA16UI
114 {vk::Format::eUndefined, false}, // RGBA16U 124 {vk::Format::eB10G11R11UfloatPack32, Attachable | Storage}, // R11FG11FB10F
115 {vk::Format::eUndefined, false}, // RGBA16UI 125 {vk::Format::eR32G32B32A32Uint, Attachable | Storage}, // RGBA32UI
116 {vk::Format::eUndefined, false}, // R11FG11FB10F 126 {vk::Format::eBc1RgbaUnormBlock, {}}, // DXT1
117 {vk::Format::eUndefined, false}, // RGBA32UI 127 {vk::Format::eBc2UnormBlock, {}}, // DXT23
118 {vk::Format::eBc1RgbaUnormBlock, false}, // DXT1 128 {vk::Format::eBc3UnormBlock, {}}, // DXT45
119 {vk::Format::eBc2UnormBlock, false}, // DXT23 129 {vk::Format::eBc4UnormBlock, {}}, // DXN1
120 {vk::Format::eBc3UnormBlock, false}, // DXT45 130 {vk::Format::eBc5UnormBlock, {}}, // DXN2UNORM
121 {vk::Format::eBc4UnormBlock, false}, // DXN1 131 {vk::Format::eBc5SnormBlock, {}}, // DXN2SNORM
122 {vk::Format::eUndefined, false}, // DXN2UNORM 132 {vk::Format::eBc7UnormBlock, {}}, // BC7U
123 {vk::Format::eUndefined, false}, // DXN2SNORM 133 {vk::Format::eBc6HUfloatBlock, {}}, // BC6H_UF16
124 {vk::Format::eUndefined, false}, // BC7U 134 {vk::Format::eBc6HSfloatBlock, {}}, // BC6H_SF16
125 {vk::Format::eUndefined, false}, // BC6H_UF16 135 {vk::Format::eAstc4x4UnormBlock, {}}, // ASTC_2D_4X4
126 {vk::Format::eUndefined, false}, // BC6H_SF16 136 {vk::Format::eB8G8R8A8Unorm, {}}, // BGRA8
127 {vk::Format::eUndefined, false}, // ASTC_2D_4X4 137 {vk::Format::eR32G32B32A32Sfloat, Attachable | Storage}, // RGBA32F
128 {vk::Format::eUndefined, false}, // BGRA8 138 {vk::Format::eR32G32Sfloat, Attachable | Storage}, // RG32F
129 {vk::Format::eUndefined, false}, // RGBA32F 139 {vk::Format::eR32Sfloat, Attachable | Storage}, // R32F
130 {vk::Format::eUndefined, false}, // RG32F 140 {vk::Format::eR16Sfloat, Attachable | Storage}, // R16F
131 {vk::Format::eUndefined, false}, // R32F 141 {vk::Format::eR16Unorm, Attachable | Storage}, // R16U
132 {vk::Format::eUndefined, false}, // R16F 142 {vk::Format::eUndefined, {}}, // R16S
133 {vk::Format::eUndefined, false}, // R16U 143 {vk::Format::eUndefined, {}}, // R16UI
134 {vk::Format::eUndefined, false}, // R16S 144 {vk::Format::eUndefined, {}}, // R16I
135 {vk::Format::eUndefined, false}, // R16UI 145 {vk::Format::eR16G16Unorm, Attachable | Storage}, // RG16
136 {vk::Format::eUndefined, false}, // R16I 146 {vk::Format::eR16G16Sfloat, Attachable | Storage}, // RG16F
137 {vk::Format::eUndefined, false}, // RG16 147 {vk::Format::eUndefined, {}}, // RG16UI
138 {vk::Format::eUndefined, false}, // RG16F 148 {vk::Format::eUndefined, {}}, // RG16I
139 {vk::Format::eUndefined, false}, // RG16UI 149 {vk::Format::eR16G16Snorm, Attachable | Storage}, // RG16S
140 {vk::Format::eUndefined, false}, // RG16I 150 {vk::Format::eUndefined, {}}, // RGB32F
141 {vk::Format::eUndefined, false}, // RG16S 151 {vk::Format::eR8G8B8A8Srgb, Attachable}, // RGBA8_SRGB
142 {vk::Format::eUndefined, false}, // RGB32F 152 {vk::Format::eR8G8Unorm, Attachable | Storage}, // RG8U
143 {vk::Format::eA8B8G8R8SrgbPack32, true}, // RGBA8_SRGB 153 {vk::Format::eR8G8Snorm, Attachable | Storage}, // RG8S
144 {vk::Format::eUndefined, false}, // RG8U 154 {vk::Format::eR32G32Uint, Attachable | Storage}, // RG32UI
145 {vk::Format::eUndefined, false}, // RG8S 155 {vk::Format::eUndefined, {}}, // RGBX16F
146 {vk::Format::eUndefined, false}, // RG32UI 156 {vk::Format::eR32Uint, Attachable | Storage}, // R32UI
147 {vk::Format::eUndefined, false}, // RGBX16F 157 {vk::Format::eAstc8x8UnormBlock, {}}, // ASTC_2D_8X8
148 {vk::Format::eUndefined, false}, // R32UI 158 {vk::Format::eUndefined, {}}, // ASTC_2D_8X5
149 {vk::Format::eUndefined, false}, // ASTC_2D_8X8 159 {vk::Format::eUndefined, {}}, // ASTC_2D_5X4
150 {vk::Format::eUndefined, false}, // ASTC_2D_8X5 160 {vk::Format::eUndefined, {}}, // BGRA8_SRGB
151 {vk::Format::eUndefined, false}, // ASTC_2D_5X4 161 {vk::Format::eBc1RgbaSrgbBlock, {}}, // DXT1_SRGB
152 162 {vk::Format::eUndefined, {}}, // DXT23_SRGB
153 // Compressed sRGB formats 163 {vk::Format::eBc3SrgbBlock, {}}, // DXT45_SRGB
154 {vk::Format::eUndefined, false}, // BGRA8_SRGB 164 {vk::Format::eBc7SrgbBlock, {}}, // BC7U_SRGB
155 {vk::Format::eUndefined, false}, // DXT1_SRGB 165 {vk::Format::eR4G4B4A4UnormPack16, Attachable}, // R4G4B4A4U
156 {vk::Format::eUndefined, false}, // DXT23_SRGB 166 {vk::Format::eAstc4x4SrgbBlock, {}}, // ASTC_2D_4X4_SRGB
157 {vk::Format::eUndefined, false}, // DXT45_SRGB 167 {vk::Format::eAstc8x8SrgbBlock, {}}, // ASTC_2D_8X8_SRGB
158 {vk::Format::eUndefined, false}, // BC7U_SRGB 168 {vk::Format::eAstc8x5SrgbBlock, {}}, // ASTC_2D_8X5_SRGB
159 {vk::Format::eUndefined, false}, // ASTC_2D_4X4_SRGB 169 {vk::Format::eAstc5x4SrgbBlock, {}}, // ASTC_2D_5X4_SRGB
160 {vk::Format::eUndefined, false}, // ASTC_2D_8X8_SRGB 170 {vk::Format::eAstc5x5UnormBlock, {}}, // ASTC_2D_5X5
161 {vk::Format::eUndefined, false}, // ASTC_2D_8X5_SRGB 171 {vk::Format::eAstc5x5SrgbBlock, {}}, // ASTC_2D_5X5_SRGB
162 {vk::Format::eUndefined, false}, // ASTC_2D_5X4_SRGB 172 {vk::Format::eAstc10x8UnormBlock, {}}, // ASTC_2D_10X8
163 {vk::Format::eUndefined, false}, // ASTC_2D_5X5 173 {vk::Format::eAstc10x8SrgbBlock, {}}, // ASTC_2D_10X8_SRGB
164 {vk::Format::eUndefined, false}, // ASTC_2D_5X5_SRGB 174 {vk::Format::eAstc6x6UnormBlock, {}}, // ASTC_2D_6X6
165 {vk::Format::eUndefined, false}, // ASTC_2D_10X8 175 {vk::Format::eAstc6x6SrgbBlock, {}}, // ASTC_2D_6X6_SRGB
166 {vk::Format::eUndefined, false}, // ASTC_2D_10X8_SRGB 176 {vk::Format::eAstc10x10UnormBlock, {}}, // ASTC_2D_10X10
177 {vk::Format::eAstc10x10SrgbBlock, {}}, // ASTC_2D_10X10_SRGB
178 {vk::Format::eAstc12x12UnormBlock, {}}, // ASTC_2D_12X12
179 {vk::Format::eAstc12x12SrgbBlock, {}}, // ASTC_2D_12X12_SRGB
180 {vk::Format::eAstc8x6UnormBlock, {}}, // ASTC_2D_8X6
181 {vk::Format::eAstc8x6SrgbBlock, {}}, // ASTC_2D_8X6_SRGB
182 {vk::Format::eAstc6x5UnormBlock, {}}, // ASTC_2D_6X5
183 {vk::Format::eAstc6x5SrgbBlock, {}}, // ASTC_2D_6X5_SRGB
184 {vk::Format::eE5B9G9R9UfloatPack32, {}}, // E5B9G9R9F
167 185
168 // Depth formats 186 // Depth formats
169 {vk::Format::eD32Sfloat, true}, // Z32F 187 {vk::Format::eD32Sfloat, Attachable}, // Z32F
170 {vk::Format::eD16Unorm, true}, // Z16 188 {vk::Format::eD16Unorm, Attachable}, // Z16
171 189
172 // DepthStencil formats 190 // DepthStencil formats
173 {vk::Format::eD24UnormS8Uint, true}, // Z24S8 191 {vk::Format::eD24UnormS8Uint, Attachable}, // Z24S8
174 {vk::Format::eD24UnormS8Uint, true}, // S8Z24 (emulated) 192 {vk::Format::eD24UnormS8Uint, Attachable}, // S8Z24 (emulated)
175 {vk::Format::eUndefined, false}, // Z32FS8 193 {vk::Format::eD32SfloatS8Uint, Attachable}, // Z32FS8
176}}; 194};
195static_assert(std::size(tex_format_tuples) == VideoCore::Surface::MaxPixelFormat);
177 196
178static constexpr bool IsZetaFormat(PixelFormat pixel_format) { 197constexpr bool IsZetaFormat(PixelFormat pixel_format) {
179 return pixel_format >= PixelFormat::MaxColorFormat && 198 return pixel_format >= PixelFormat::MaxColorFormat &&
180 pixel_format < PixelFormat::MaxDepthStencilFormat; 199 pixel_format < PixelFormat::MaxDepthStencilFormat;
181} 200}
182 201
183std::pair<vk::Format, bool> SurfaceFormat(const VKDevice& device, FormatType format_type, 202} // Anonymous namespace
184 PixelFormat pixel_format) { 203
185 ASSERT(static_cast<std::size_t>(pixel_format) < tex_format_tuples.size()); 204FormatInfo SurfaceFormat(const VKDevice& device, FormatType format_type, PixelFormat pixel_format) {
205 ASSERT(static_cast<std::size_t>(pixel_format) < std::size(tex_format_tuples));
186 206
187 const auto tuple = tex_format_tuples[static_cast<u32>(pixel_format)]; 207 auto tuple = tex_format_tuples[static_cast<std::size_t>(pixel_format)];
188 UNIMPLEMENTED_IF_MSG(tuple.format == vk::Format::eUndefined, 208 if (tuple.format == vk::Format::eUndefined) {
189 "Unimplemented texture format with pixel format={}", 209 UNIMPLEMENTED_MSG("Unimplemented texture format with pixel format={}",
190 static_cast<u32>(pixel_format)); 210 static_cast<u32>(pixel_format));
211 return {vk::Format::eA8B8G8R8UnormPack32, true, true};
212 }
213
214 // Use ABGR8 on hardware that doesn't support ASTC natively
215 if (!device.IsOptimalAstcSupported() && VideoCore::Surface::IsPixelFormatASTC(pixel_format)) {
216 tuple.format = VideoCore::Surface::IsPixelFormatSRGB(pixel_format)
217 ? vk::Format::eA8B8G8R8SrgbPack32
218 : vk::Format::eA8B8G8R8UnormPack32;
219 }
220 const bool attachable = tuple.usage & Attachable;
221 const bool storage = tuple.usage & Storage;
191 222
192 auto usage = vk::FormatFeatureFlagBits::eSampledImage | 223 vk::FormatFeatureFlags usage;
193 vk::FormatFeatureFlagBits::eTransferDst | vk::FormatFeatureFlagBits::eTransferSrc; 224 if (format_type == FormatType::Buffer) {
194 if (tuple.attachable) { 225 usage = vk::FormatFeatureFlagBits::eStorageTexelBuffer |
195 usage |= IsZetaFormat(pixel_format) ? vk::FormatFeatureFlagBits::eDepthStencilAttachment 226 vk::FormatFeatureFlagBits::eUniformTexelBuffer;
196 : vk::FormatFeatureFlagBits::eColorAttachment; 227 } else {
228 usage = vk::FormatFeatureFlagBits::eSampledImage | vk::FormatFeatureFlagBits::eTransferDst |
229 vk::FormatFeatureFlagBits::eTransferSrc;
230 if (attachable) {
231 usage |= IsZetaFormat(pixel_format) ? vk::FormatFeatureFlagBits::eDepthStencilAttachment
232 : vk::FormatFeatureFlagBits::eColorAttachment;
233 }
234 if (storage) {
235 usage |= vk::FormatFeatureFlagBits::eStorageImage;
236 }
197 } 237 }
198 return {device.GetSupportedFormat(tuple.format, usage, format_type), tuple.attachable}; 238 return {device.GetSupportedFormat(tuple.format, usage, format_type), attachable, storage};
199} 239}
200 240
201vk::ShaderStageFlagBits ShaderStage(Tegra::Engines::ShaderType stage) { 241vk::ShaderStageFlagBits ShaderStage(Tegra::Engines::ShaderType stage) {
@@ -215,7 +255,8 @@ vk::ShaderStageFlagBits ShaderStage(Tegra::Engines::ShaderType stage) {
215 return {}; 255 return {};
216} 256}
217 257
218vk::PrimitiveTopology PrimitiveTopology(Maxwell::PrimitiveTopology topology) { 258vk::PrimitiveTopology PrimitiveTopology([[maybe_unused]] const VKDevice& device,
259 Maxwell::PrimitiveTopology topology) {
219 switch (topology) { 260 switch (topology) {
220 case Maxwell::PrimitiveTopology::Points: 261 case Maxwell::PrimitiveTopology::Points:
221 return vk::PrimitiveTopology::ePointList; 262 return vk::PrimitiveTopology::ePointList;
@@ -227,6 +268,13 @@ vk::PrimitiveTopology PrimitiveTopology(Maxwell::PrimitiveTopology topology) {
227 return vk::PrimitiveTopology::eTriangleList; 268 return vk::PrimitiveTopology::eTriangleList;
228 case Maxwell::PrimitiveTopology::TriangleStrip: 269 case Maxwell::PrimitiveTopology::TriangleStrip:
229 return vk::PrimitiveTopology::eTriangleStrip; 270 return vk::PrimitiveTopology::eTriangleStrip;
271 case Maxwell::PrimitiveTopology::TriangleFan:
272 return vk::PrimitiveTopology::eTriangleFan;
273 case Maxwell::PrimitiveTopology::Quads:
274 // TODO(Rodrigo): Use VK_PRIMITIVE_TOPOLOGY_QUAD_LIST_EXT whenever it releases
275 return vk::PrimitiveTopology::eTriangleList;
276 case Maxwell::PrimitiveTopology::Patches:
277 return vk::PrimitiveTopology::ePatchList;
230 default: 278 default:
231 UNIMPLEMENTED_MSG("Unimplemented topology={}", static_cast<u32>(topology)); 279 UNIMPLEMENTED_MSG("Unimplemented topology={}", static_cast<u32>(topology));
232 return {}; 280 return {};
@@ -236,37 +284,111 @@ vk::PrimitiveTopology PrimitiveTopology(Maxwell::PrimitiveTopology topology) {
236vk::Format VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size) { 284vk::Format VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size) {
237 switch (type) { 285 switch (type) {
238 case Maxwell::VertexAttribute::Type::SignedNorm: 286 case Maxwell::VertexAttribute::Type::SignedNorm:
287 switch (size) {
288 case Maxwell::VertexAttribute::Size::Size_8:
289 return vk::Format::eR8Snorm;
290 case Maxwell::VertexAttribute::Size::Size_8_8:
291 return vk::Format::eR8G8Snorm;
292 case Maxwell::VertexAttribute::Size::Size_8_8_8:
293 return vk::Format::eR8G8B8Snorm;
294 case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
295 return vk::Format::eR8G8B8A8Snorm;
296 case Maxwell::VertexAttribute::Size::Size_16:
297 return vk::Format::eR16Snorm;
298 case Maxwell::VertexAttribute::Size::Size_16_16:
299 return vk::Format::eR16G16Snorm;
300 case Maxwell::VertexAttribute::Size::Size_16_16_16:
301 return vk::Format::eR16G16B16Snorm;
302 case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
303 return vk::Format::eR16G16B16A16Snorm;
304 case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
305 return vk::Format::eA2B10G10R10SnormPack32;
306 default:
307 break;
308 }
239 break; 309 break;
240 case Maxwell::VertexAttribute::Type::UnsignedNorm: 310 case Maxwell::VertexAttribute::Type::UnsignedNorm:
241 switch (size) { 311 switch (size) {
312 case Maxwell::VertexAttribute::Size::Size_8:
313 return vk::Format::eR8Unorm;
314 case Maxwell::VertexAttribute::Size::Size_8_8:
315 return vk::Format::eR8G8Unorm;
316 case Maxwell::VertexAttribute::Size::Size_8_8_8:
317 return vk::Format::eR8G8B8Unorm;
242 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 318 case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
243 return vk::Format::eR8G8B8A8Unorm; 319 return vk::Format::eR8G8B8A8Unorm;
320 case Maxwell::VertexAttribute::Size::Size_16:
321 return vk::Format::eR16Unorm;
322 case Maxwell::VertexAttribute::Size::Size_16_16:
323 return vk::Format::eR16G16Unorm;
324 case Maxwell::VertexAttribute::Size::Size_16_16_16:
325 return vk::Format::eR16G16B16Unorm;
326 case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
327 return vk::Format::eR16G16B16A16Unorm;
244 default: 328 default:
245 break; 329 break;
246 } 330 }
247 break; 331 break;
248 case Maxwell::VertexAttribute::Type::SignedInt: 332 case Maxwell::VertexAttribute::Type::SignedInt:
249 break; 333 switch (size) {
334 case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
335 return vk::Format::eR16G16B16A16Sint;
336 case Maxwell::VertexAttribute::Size::Size_8:
337 return vk::Format::eR8Sint;
338 case Maxwell::VertexAttribute::Size::Size_8_8:
339 return vk::Format::eR8G8Sint;
340 case Maxwell::VertexAttribute::Size::Size_8_8_8:
341 return vk::Format::eR8G8B8Sint;
342 case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
343 return vk::Format::eR8G8B8A8Sint;
344 case Maxwell::VertexAttribute::Size::Size_32:
345 return vk::Format::eR32Sint;
346 default:
347 break;
348 }
250 case Maxwell::VertexAttribute::Type::UnsignedInt: 349 case Maxwell::VertexAttribute::Type::UnsignedInt:
251 switch (size) { 350 switch (size) {
351 case Maxwell::VertexAttribute::Size::Size_8:
352 return vk::Format::eR8Uint;
353 case Maxwell::VertexAttribute::Size::Size_8_8:
354 return vk::Format::eR8G8Uint;
355 case Maxwell::VertexAttribute::Size::Size_8_8_8:
356 return vk::Format::eR8G8B8Uint;
357 case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
358 return vk::Format::eR8G8B8A8Uint;
252 case Maxwell::VertexAttribute::Size::Size_32: 359 case Maxwell::VertexAttribute::Size::Size_32:
253 return vk::Format::eR32Uint; 360 return vk::Format::eR32Uint;
254 default: 361 default:
255 break; 362 break;
256 } 363 }
257 case Maxwell::VertexAttribute::Type::UnsignedScaled: 364 case Maxwell::VertexAttribute::Type::UnsignedScaled:
365 switch (size) {
366 case Maxwell::VertexAttribute::Size::Size_8_8:
367 return vk::Format::eR8G8Uscaled;
368 default:
369 break;
370 }
371 break;
258 case Maxwell::VertexAttribute::Type::SignedScaled: 372 case Maxwell::VertexAttribute::Type::SignedScaled:
259 break; 373 break;
260 case Maxwell::VertexAttribute::Type::Float: 374 case Maxwell::VertexAttribute::Type::Float:
261 switch (size) { 375 switch (size) {
262 case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
263 return vk::Format::eR32G32B32A32Sfloat;
264 case Maxwell::VertexAttribute::Size::Size_32_32_32:
265 return vk::Format::eR32G32B32Sfloat;
266 case Maxwell::VertexAttribute::Size::Size_32_32:
267 return vk::Format::eR32G32Sfloat;
268 case Maxwell::VertexAttribute::Size::Size_32: 376 case Maxwell::VertexAttribute::Size::Size_32:
269 return vk::Format::eR32Sfloat; 377 return vk::Format::eR32Sfloat;
378 case Maxwell::VertexAttribute::Size::Size_32_32:
379 return vk::Format::eR32G32Sfloat;
380 case Maxwell::VertexAttribute::Size::Size_32_32_32:
381 return vk::Format::eR32G32B32Sfloat;
382 case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
383 return vk::Format::eR32G32B32A32Sfloat;
384 case Maxwell::VertexAttribute::Size::Size_16:
385 return vk::Format::eR16Sfloat;
386 case Maxwell::VertexAttribute::Size::Size_16_16:
387 return vk::Format::eR16G16Sfloat;
388 case Maxwell::VertexAttribute::Size::Size_16_16_16:
389 return vk::Format::eR16G16B16Sfloat;
390 case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
391 return vk::Format::eR16G16B16A16Sfloat;
270 default: 392 default:
271 break; 393 break;
272 } 394 }
@@ -308,11 +430,14 @@ vk::CompareOp ComparisonOp(Maxwell::ComparisonOp comparison) {
308 return {}; 430 return {};
309} 431}
310 432
311vk::IndexType IndexFormat(Maxwell::IndexFormat index_format) { 433vk::IndexType IndexFormat(const VKDevice& device, Maxwell::IndexFormat index_format) {
312 switch (index_format) { 434 switch (index_format) {
313 case Maxwell::IndexFormat::UnsignedByte: 435 case Maxwell::IndexFormat::UnsignedByte:
314 UNIMPLEMENTED_MSG("Vulkan does not support native u8 index format"); 436 if (!device.IsExtIndexTypeUint8Supported()) {
315 return vk::IndexType::eUint16; 437 UNIMPLEMENTED_MSG("Native uint8 indices are not supported on this device");
438 return vk::IndexType::eUint16;
439 }
440 return vk::IndexType::eUint8EXT;
316 case Maxwell::IndexFormat::UnsignedShort: 441 case Maxwell::IndexFormat::UnsignedShort:
317 return vk::IndexType::eUint16; 442 return vk::IndexType::eUint16;
318 case Maxwell::IndexFormat::UnsignedInt: 443 case Maxwell::IndexFormat::UnsignedInt:
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h
index 904a32e01..1534b738b 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.h
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h
@@ -4,7 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <utility>
8#include "common/common_types.h" 7#include "common/common_types.h"
9#include "video_core/engines/maxwell_3d.h" 8#include "video_core/engines/maxwell_3d.h"
10#include "video_core/renderer_vulkan/declarations.h" 9#include "video_core/renderer_vulkan/declarations.h"
@@ -23,24 +22,31 @@ vk::Filter Filter(Tegra::Texture::TextureFilter filter);
23 22
24vk::SamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter); 23vk::SamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter);
25 24
26vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode); 25vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode,
26 Tegra::Texture::TextureFilter filter);
27 27
28vk::CompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compare_func); 28vk::CompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compare_func);
29 29
30} // namespace Sampler 30} // namespace Sampler
31 31
32std::pair<vk::Format, bool> SurfaceFormat(const VKDevice& device, FormatType format_type, 32struct FormatInfo {
33 PixelFormat pixel_format); 33 vk::Format format;
34 bool attachable;
35 bool storage;
36};
37
38FormatInfo SurfaceFormat(const VKDevice& device, FormatType format_type, PixelFormat pixel_format);
34 39
35vk::ShaderStageFlagBits ShaderStage(Tegra::Engines::ShaderType stage); 40vk::ShaderStageFlagBits ShaderStage(Tegra::Engines::ShaderType stage);
36 41
37vk::PrimitiveTopology PrimitiveTopology(Maxwell::PrimitiveTopology topology); 42vk::PrimitiveTopology PrimitiveTopology(const VKDevice& device,
43 Maxwell::PrimitiveTopology topology);
38 44
39vk::Format VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size); 45vk::Format VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size);
40 46
41vk::CompareOp ComparisonOp(Maxwell::ComparisonOp comparison); 47vk::CompareOp ComparisonOp(Maxwell::ComparisonOp comparison);
42 48
43vk::IndexType IndexFormat(Maxwell::IndexFormat index_format); 49vk::IndexType IndexFormat(const VKDevice& device, Maxwell::IndexFormat index_format);
44 50
45vk::StencilOp StencilOp(Maxwell::StencilOp stencil_op); 51vk::StencilOp StencilOp(Maxwell::StencilOp stencil_op);
46 52
diff --git a/src/video_core/renderer_vulkan/vk_sampler_cache.cpp b/src/video_core/renderer_vulkan/vk_sampler_cache.cpp
index 801826d3d..1ce583f75 100644
--- a/src/video_core/renderer_vulkan/vk_sampler_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_sampler_cache.cpp
@@ -46,9 +46,10 @@ UniqueSampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc)
46 {}, MaxwellToVK::Sampler::Filter(tsc.mag_filter), 46 {}, MaxwellToVK::Sampler::Filter(tsc.mag_filter),
47 MaxwellToVK::Sampler::Filter(tsc.min_filter), 47 MaxwellToVK::Sampler::Filter(tsc.min_filter),
48 MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter), 48 MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter),
49 MaxwellToVK::Sampler::WrapMode(tsc.wrap_u), MaxwellToVK::Sampler::WrapMode(tsc.wrap_v), 49 MaxwellToVK::Sampler::WrapMode(tsc.wrap_u, tsc.mag_filter),
50 MaxwellToVK::Sampler::WrapMode(tsc.wrap_p), tsc.GetLodBias(), has_anisotropy, 50 MaxwellToVK::Sampler::WrapMode(tsc.wrap_v, tsc.mag_filter),
51 max_anisotropy, tsc.depth_compare_enabled, 51 MaxwellToVK::Sampler::WrapMode(tsc.wrap_p, tsc.mag_filter), tsc.GetLodBias(),
52 has_anisotropy, max_anisotropy, tsc.depth_compare_enabled,
52 MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func), tsc.GetMinLod(), 53 MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func), tsc.GetMinLod(),
53 tsc.GetMaxLod(), vk_border_color.value_or(vk::BorderColor::eFloatTransparentBlack), 54 tsc.GetMaxLod(), vk_border_color.value_or(vk::BorderColor::eFloatTransparentBlack),
54 unnormalized_coords); 55 unnormalized_coords);