diff options
Diffstat (limited to 'src/video_core')
-rw-r--r-- | src/video_core/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/video_core/dma_pusher.cpp | 2 | ||||
-rw-r--r-- | src/video_core/gpu.h | 2 | ||||
-rw-r--r-- | src/video_core/gpu_asynch.h | 2 | ||||
-rw-r--r-- | src/video_core/gpu_synch.h | 2 | ||||
-rw-r--r-- | src/video_core/gpu_thread.h | 7 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 483 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/maxwell_to_vk.h | 58 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_device.cpp | 13 |
9 files changed, 559 insertions, 12 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 57f31cd58..dac992d44 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -112,6 +112,8 @@ add_library(video_core STATIC if (ENABLE_VULKAN) target_sources(video_core PRIVATE renderer_vulkan/declarations.h + renderer_vulkan/maxwell_to_vk.cpp + renderer_vulkan/maxwell_to_vk.h renderer_vulkan/vk_buffer_cache.cpp renderer_vulkan/vk_buffer_cache.h renderer_vulkan/vk_device.cpp diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 669541b4b..bff1a37ff 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp @@ -39,7 +39,7 @@ bool DmaPusher::Step() { } const CommandList& command_list{dma_pushbuffer.front()}; - const CommandListHeader& command_list_header{command_list[dma_pushbuffer_subindex++]}; + const CommandListHeader command_list_header{command_list[dma_pushbuffer_subindex++]}; GPUVAddr dma_get = command_list_header.addr; GPUVAddr dma_put = dma_get + command_list_header.size * sizeof(u32); bool non_main = command_list_header.is_non_main; diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 14a421cc1..56a203275 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -123,7 +123,7 @@ class GPU { public: explicit GPU(Core::System& system, VideoCore::RendererBase& renderer); - ~GPU(); + virtual ~GPU(); struct MethodCall { u32 method{}; diff --git a/src/video_core/gpu_asynch.h b/src/video_core/gpu_asynch.h index 58046f3e9..e6a807aba 100644 --- a/src/video_core/gpu_asynch.h +++ b/src/video_core/gpu_asynch.h @@ -21,7 +21,7 @@ class ThreadManager; class GPUAsynch : public Tegra::GPU { public: explicit GPUAsynch(Core::System& system, VideoCore::RendererBase& renderer); - ~GPUAsynch(); + ~GPUAsynch() override; void PushGPUEntries(Tegra::CommandList&& entries) override; void SwapBuffers( diff --git a/src/video_core/gpu_synch.h b/src/video_core/gpu_synch.h index 658f683e2..7d5a241ff 100644 --- a/src/video_core/gpu_synch.h +++ b/src/video_core/gpu_synch.h @@ -16,7 +16,7 @@ namespace VideoCommon { class GPUSynch : public Tegra::GPU { public: explicit GPUSynch(Core::System& system, VideoCore::RendererBase& renderer); - ~GPUSynch(); + ~GPUSynch() override; void PushGPUEntries(Tegra::CommandList&& entries) override; void SwapBuffers( diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h index 2ad8214cc..edb148b14 100644 --- a/src/video_core/gpu_thread.h +++ b/src/video_core/gpu_thread.h @@ -113,9 +113,6 @@ public: /// Notify rasterizer that any caches of the specified region should be flushed and invalidated void FlushAndInvalidateRegion(VAddr addr, u64 size); - /// Waits the caller until the GPU thread is idle, used for synchronization - void WaitForIdle(); - private: /// Pushes a command to be executed by the GPU thread void PushCommand(CommandData&& command_data, bool wait_for_idle, bool allow_on_cpu); @@ -127,10 +124,10 @@ private: private: SynchState state; - std::thread thread; - std::thread::id thread_id; VideoCore::RendererBase& renderer; Tegra::DmaPusher& dma_pusher; + std::thread thread; + std::thread::id thread_id; }; } // namespace VideoCommon::GPUThread diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp new file mode 100644 index 000000000..34bf26ff2 --- /dev/null +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -0,0 +1,483 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/assert.h" +#include "common/common_types.h" +#include "common/logging/log.h" +#include "video_core/engines/maxwell_3d.h" +#include "video_core/renderer_vulkan/declarations.h" +#include "video_core/renderer_vulkan/maxwell_to_vk.h" +#include "video_core/renderer_vulkan/vk_device.h" +#include "video_core/surface.h" + +namespace Vulkan::MaxwellToVK { + +namespace Sampler { + +vk::Filter Filter(Tegra::Texture::TextureFilter filter) { + switch (filter) { + case Tegra::Texture::TextureFilter::Linear: + return vk::Filter::eLinear; + case Tegra::Texture::TextureFilter::Nearest: + return vk::Filter::eNearest; + } + UNIMPLEMENTED_MSG("Unimplemented sampler filter={}", static_cast<u32>(filter)); + return {}; +} + +vk::SamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter) { + switch (mipmap_filter) { + case Tegra::Texture::TextureMipmapFilter::None: + // TODO(Rodrigo): None seems to be mapped to OpenGL's mag and min filters without mipmapping + // (e.g. GL_NEAREST and GL_LINEAR). Vulkan doesn't have such a thing, find out if we have to + // use an image view with a single mipmap level to emulate this. + return vk::SamplerMipmapMode::eLinear; + case Tegra::Texture::TextureMipmapFilter::Linear: + return vk::SamplerMipmapMode::eLinear; + case Tegra::Texture::TextureMipmapFilter::Nearest: + return vk::SamplerMipmapMode::eNearest; + } + UNIMPLEMENTED_MSG("Unimplemented sampler mipmap mode={}", static_cast<u32>(mipmap_filter)); + return {}; +} + +vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode) { + switch (wrap_mode) { + case Tegra::Texture::WrapMode::Wrap: + return vk::SamplerAddressMode::eRepeat; + case Tegra::Texture::WrapMode::Mirror: + return vk::SamplerAddressMode::eMirroredRepeat; + case Tegra::Texture::WrapMode::ClampToEdge: + return vk::SamplerAddressMode::eClampToEdge; + case Tegra::Texture::WrapMode::Border: + return vk::SamplerAddressMode::eClampToBorder; + case Tegra::Texture::WrapMode::ClampOGL: + // TODO(Rodrigo): GL_CLAMP was removed as of OpenGL 3.1, to implement GL_CLAMP, we can use + // eClampToBorder to get the border color of the texture, and then sample the edge to + // manually mix them. However the shader part of this is not yet implemented. + return vk::SamplerAddressMode::eClampToBorder; + case Tegra::Texture::WrapMode::MirrorOnceClampToEdge: + return vk::SamplerAddressMode::eMirrorClampToEdge; + case Tegra::Texture::WrapMode::MirrorOnceBorder: + UNIMPLEMENTED(); + return vk::SamplerAddressMode::eMirrorClampToEdge; + } + UNIMPLEMENTED_MSG("Unimplemented wrap mode={}", static_cast<u32>(wrap_mode)); + return {}; +} + +vk::CompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compare_func) { + switch (depth_compare_func) { + case Tegra::Texture::DepthCompareFunc::Never: + return vk::CompareOp::eNever; + case Tegra::Texture::DepthCompareFunc::Less: + return vk::CompareOp::eLess; + case Tegra::Texture::DepthCompareFunc::LessEqual: + return vk::CompareOp::eLessOrEqual; + case Tegra::Texture::DepthCompareFunc::Equal: + return vk::CompareOp::eEqual; + case Tegra::Texture::DepthCompareFunc::NotEqual: + return vk::CompareOp::eNotEqual; + case Tegra::Texture::DepthCompareFunc::Greater: + return vk::CompareOp::eGreater; + case Tegra::Texture::DepthCompareFunc::GreaterEqual: + return vk::CompareOp::eGreaterOrEqual; + case Tegra::Texture::DepthCompareFunc::Always: + return vk::CompareOp::eAlways; + } + UNIMPLEMENTED_MSG("Unimplemented sampler depth compare function={}", + static_cast<u32>(depth_compare_func)); + return {}; +} + +} // namespace Sampler + +struct FormatTuple { + vk::Format format; ///< Vulkan format + ComponentType component_type; ///< Abstracted component type + bool attachable; ///< True when this format can be used as an attachment +}; + +static constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format_tuples = {{ + {vk::Format::eA8B8G8R8UnormPack32, ComponentType::UNorm, true}, // ABGR8U + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ABGR8S + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ABGR8UI + {vk::Format::eB5G6R5UnormPack16, ComponentType::UNorm, false}, // B5G6R5U + {vk::Format::eA2B10G10R10UnormPack32, ComponentType::UNorm, true}, // A2B10G10R10U + {vk::Format::eUndefined, ComponentType::Invalid, false}, // A1B5G5R5U + {vk::Format::eR8Unorm, ComponentType::UNorm, true}, // R8U + {vk::Format::eUndefined, ComponentType::Invalid, false}, // R8UI + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGBA16F + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGBA16U + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGBA16UI + {vk::Format::eUndefined, ComponentType::Invalid, false}, // R11FG11FB10F + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGBA32UI + {vk::Format::eBc1RgbaUnormBlock, ComponentType::UNorm, false}, // DXT1 + {vk::Format::eBc2UnormBlock, ComponentType::UNorm, false}, // DXT23 + {vk::Format::eBc3UnormBlock, ComponentType::UNorm, false}, // DXT45 + {vk::Format::eBc4UnormBlock, ComponentType::UNorm, false}, // DXN1 + {vk::Format::eUndefined, ComponentType::Invalid, false}, // DXN2UNORM + {vk::Format::eUndefined, ComponentType::Invalid, false}, // DXN2SNORM + {vk::Format::eUndefined, ComponentType::Invalid, false}, // BC7U + {vk::Format::eUndefined, ComponentType::Invalid, false}, // BC6H_UF16 + {vk::Format::eUndefined, ComponentType::Invalid, false}, // BC6H_SF16 + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_4X4 + {vk::Format::eUndefined, ComponentType::Invalid, false}, // BGRA8 + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGBA32F + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG32F + {vk::Format::eUndefined, ComponentType::Invalid, false}, // R32F + {vk::Format::eUndefined, ComponentType::Invalid, false}, // R16F + {vk::Format::eUndefined, ComponentType::Invalid, false}, // R16U + {vk::Format::eUndefined, ComponentType::Invalid, false}, // R16S + {vk::Format::eUndefined, ComponentType::Invalid, false}, // R16UI + {vk::Format::eUndefined, ComponentType::Invalid, false}, // R16I + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG16 + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG16F + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG16UI + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG16I + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG16S + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RGB32F + {vk::Format::eA8B8G8R8SrgbPack32, ComponentType::UNorm, true}, // RGBA8_SRGB + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG8U + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG8S + {vk::Format::eUndefined, ComponentType::Invalid, false}, // RG32UI + {vk::Format::eUndefined, ComponentType::Invalid, false}, // R32UI + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_8X8 + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_8X5 + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_5X4 + + // Compressed sRGB formats + {vk::Format::eUndefined, ComponentType::Invalid, false}, // BGRA8_SRGB + {vk::Format::eUndefined, ComponentType::Invalid, false}, // DXT1_SRGB + {vk::Format::eUndefined, ComponentType::Invalid, false}, // DXT23_SRGB + {vk::Format::eUndefined, ComponentType::Invalid, false}, // DXT45_SRGB + {vk::Format::eUndefined, ComponentType::Invalid, false}, // BC7U_SRGB + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_4X4_SRGB + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_8X8_SRGB + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_8X5_SRGB + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_5X4_SRGB + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_5X5 + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_5X5_SRGB + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_10X8 + {vk::Format::eUndefined, ComponentType::Invalid, false}, // ASTC_2D_10X8_SRGB + + // Depth formats + {vk::Format::eD32Sfloat, ComponentType::Float, true}, // Z32F + {vk::Format::eD16Unorm, ComponentType::UNorm, true}, // Z16 + + // DepthStencil formats + {vk::Format::eD24UnormS8Uint, ComponentType::UNorm, true}, // Z24S8 + {vk::Format::eD24UnormS8Uint, ComponentType::UNorm, true}, // S8Z24 (emulated) + {vk::Format::eUndefined, ComponentType::Invalid, false}, // Z32FS8 +}}; + +static constexpr bool IsZetaFormat(PixelFormat pixel_format) { + return pixel_format >= PixelFormat::MaxColorFormat && + pixel_format < PixelFormat::MaxDepthStencilFormat; +} + +std::pair<vk::Format, bool> SurfaceFormat(const VKDevice& device, FormatType format_type, + PixelFormat pixel_format, ComponentType component_type) { + ASSERT(static_cast<std::size_t>(pixel_format) < tex_format_tuples.size()); + + const auto tuple = tex_format_tuples[static_cast<u32>(pixel_format)]; + UNIMPLEMENTED_IF_MSG(tuple.format == vk::Format::eUndefined, + "Unimplemented texture format with pixel format={} and component type={}", + static_cast<u32>(pixel_format), static_cast<u32>(component_type)); + ASSERT_MSG(component_type == tuple.component_type, "Component type mismatch"); + + auto usage = vk::FormatFeatureFlagBits::eSampledImage | + vk::FormatFeatureFlagBits::eTransferDst | vk::FormatFeatureFlagBits::eTransferSrc; + if (tuple.attachable) { + usage |= IsZetaFormat(pixel_format) ? vk::FormatFeatureFlagBits::eDepthStencilAttachment + : vk::FormatFeatureFlagBits::eColorAttachment; + } + return {device.GetSupportedFormat(tuple.format, usage, format_type), tuple.attachable}; +} + +vk::ShaderStageFlagBits ShaderStage(Maxwell::ShaderStage stage) { + switch (stage) { + case Maxwell::ShaderStage::Vertex: + return vk::ShaderStageFlagBits::eVertex; + case Maxwell::ShaderStage::TesselationControl: + return vk::ShaderStageFlagBits::eTessellationControl; + case Maxwell::ShaderStage::TesselationEval: + return vk::ShaderStageFlagBits::eTessellationEvaluation; + case Maxwell::ShaderStage::Geometry: + return vk::ShaderStageFlagBits::eGeometry; + case Maxwell::ShaderStage::Fragment: + return vk::ShaderStageFlagBits::eFragment; + } + UNIMPLEMENTED_MSG("Unimplemented shader stage={}", static_cast<u32>(stage)); + return {}; +} + +vk::PrimitiveTopology PrimitiveTopology(Maxwell::PrimitiveTopology topology) { + switch (topology) { + case Maxwell::PrimitiveTopology::Points: + return vk::PrimitiveTopology::ePointList; + case Maxwell::PrimitiveTopology::Lines: + return vk::PrimitiveTopology::eLineList; + case Maxwell::PrimitiveTopology::LineStrip: + return vk::PrimitiveTopology::eLineStrip; + case Maxwell::PrimitiveTopology::Triangles: + return vk::PrimitiveTopology::eTriangleList; + case Maxwell::PrimitiveTopology::TriangleStrip: + return vk::PrimitiveTopology::eTriangleStrip; + } + UNIMPLEMENTED_MSG("Unimplemented topology={}", static_cast<u32>(topology)); + return {}; +} + +vk::Format VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size) { + switch (type) { + case Maxwell::VertexAttribute::Type::SignedNorm: + break; + case Maxwell::VertexAttribute::Type::UnsignedNorm: + switch (size) { + case Maxwell::VertexAttribute::Size::Size_8_8_8_8: + return vk::Format::eR8G8B8A8Unorm; + default: + break; + } + break; + case Maxwell::VertexAttribute::Type::SignedInt: + break; + case Maxwell::VertexAttribute::Type::UnsignedInt: + switch (size) { + case Maxwell::VertexAttribute::Size::Size_32: + return vk::Format::eR32Uint; + default: + break; + } + case Maxwell::VertexAttribute::Type::UnsignedScaled: + case Maxwell::VertexAttribute::Type::SignedScaled: + break; + case Maxwell::VertexAttribute::Type::Float: + switch (size) { + case Maxwell::VertexAttribute::Size::Size_32_32_32_32: + return vk::Format::eR32G32B32A32Sfloat; + case Maxwell::VertexAttribute::Size::Size_32_32_32: + return vk::Format::eR32G32B32Sfloat; + case Maxwell::VertexAttribute::Size::Size_32_32: + return vk::Format::eR32G32Sfloat; + case Maxwell::VertexAttribute::Size::Size_32: + return vk::Format::eR32Sfloat; + default: + break; + } + break; + } + UNIMPLEMENTED_MSG("Unimplemented vertex format of type={} and size={}", static_cast<u32>(type), + static_cast<u32>(size)); + return {}; +} + +vk::CompareOp ComparisonOp(Maxwell::ComparisonOp comparison) { + switch (comparison) { + case Maxwell::ComparisonOp::Never: + case Maxwell::ComparisonOp::NeverOld: + return vk::CompareOp::eNever; + case Maxwell::ComparisonOp::Less: + case Maxwell::ComparisonOp::LessOld: + return vk::CompareOp::eLess; + case Maxwell::ComparisonOp::Equal: + case Maxwell::ComparisonOp::EqualOld: + return vk::CompareOp::eEqual; + case Maxwell::ComparisonOp::LessEqual: + case Maxwell::ComparisonOp::LessEqualOld: + return vk::CompareOp::eLessOrEqual; + case Maxwell::ComparisonOp::Greater: + case Maxwell::ComparisonOp::GreaterOld: + return vk::CompareOp::eGreater; + case Maxwell::ComparisonOp::NotEqual: + case Maxwell::ComparisonOp::NotEqualOld: + return vk::CompareOp::eNotEqual; + case Maxwell::ComparisonOp::GreaterEqual: + case Maxwell::ComparisonOp::GreaterEqualOld: + return vk::CompareOp::eGreaterOrEqual; + case Maxwell::ComparisonOp::Always: + case Maxwell::ComparisonOp::AlwaysOld: + return vk::CompareOp::eAlways; + } + UNIMPLEMENTED_MSG("Unimplemented comparison op={}", static_cast<u32>(comparison)); + return {}; +} + +vk::IndexType IndexFormat(Maxwell::IndexFormat index_format) { + switch (index_format) { + case Maxwell::IndexFormat::UnsignedByte: + UNIMPLEMENTED_MSG("Vulkan does not support native u8 index format"); + return vk::IndexType::eUint16; + case Maxwell::IndexFormat::UnsignedShort: + return vk::IndexType::eUint16; + case Maxwell::IndexFormat::UnsignedInt: + return vk::IndexType::eUint32; + } + UNIMPLEMENTED_MSG("Unimplemented index_format={}", static_cast<u32>(index_format)); + return {}; +} + +vk::StencilOp StencilOp(Maxwell::StencilOp stencil_op) { + switch (stencil_op) { + case Maxwell::StencilOp::Keep: + case Maxwell::StencilOp::KeepOGL: + return vk::StencilOp::eKeep; + case Maxwell::StencilOp::Zero: + case Maxwell::StencilOp::ZeroOGL: + return vk::StencilOp::eZero; + case Maxwell::StencilOp::Replace: + case Maxwell::StencilOp::ReplaceOGL: + return vk::StencilOp::eReplace; + case Maxwell::StencilOp::Incr: + case Maxwell::StencilOp::IncrOGL: + return vk::StencilOp::eIncrementAndClamp; + case Maxwell::StencilOp::Decr: + case Maxwell::StencilOp::DecrOGL: + return vk::StencilOp::eDecrementAndClamp; + case Maxwell::StencilOp::Invert: + case Maxwell::StencilOp::InvertOGL: + return vk::StencilOp::eInvert; + case Maxwell::StencilOp::IncrWrap: + case Maxwell::StencilOp::IncrWrapOGL: + return vk::StencilOp::eIncrementAndWrap; + case Maxwell::StencilOp::DecrWrap: + case Maxwell::StencilOp::DecrWrapOGL: + return vk::StencilOp::eDecrementAndWrap; + } + UNIMPLEMENTED_MSG("Unimplemented stencil op={}", static_cast<u32>(stencil_op)); + return {}; +} + +vk::BlendOp BlendEquation(Maxwell::Blend::Equation equation) { + switch (equation) { + case Maxwell::Blend::Equation::Add: + case Maxwell::Blend::Equation::AddGL: + return vk::BlendOp::eAdd; + case Maxwell::Blend::Equation::Subtract: + case Maxwell::Blend::Equation::SubtractGL: + return vk::BlendOp::eSubtract; + case Maxwell::Blend::Equation::ReverseSubtract: + case Maxwell::Blend::Equation::ReverseSubtractGL: + return vk::BlendOp::eReverseSubtract; + case Maxwell::Blend::Equation::Min: + case Maxwell::Blend::Equation::MinGL: + return vk::BlendOp::eMin; + case Maxwell::Blend::Equation::Max: + case Maxwell::Blend::Equation::MaxGL: + return vk::BlendOp::eMax; + } + UNIMPLEMENTED_MSG("Unimplemented blend equation={}", static_cast<u32>(equation)); + return {}; +} + +vk::BlendFactor BlendFactor(Maxwell::Blend::Factor factor) { + switch (factor) { + case Maxwell::Blend::Factor::Zero: + case Maxwell::Blend::Factor::ZeroGL: + return vk::BlendFactor::eZero; + case Maxwell::Blend::Factor::One: + case Maxwell::Blend::Factor::OneGL: + return vk::BlendFactor::eOne; + case Maxwell::Blend::Factor::SourceColor: + case Maxwell::Blend::Factor::SourceColorGL: + return vk::BlendFactor::eSrcColor; + case Maxwell::Blend::Factor::OneMinusSourceColor: + case Maxwell::Blend::Factor::OneMinusSourceColorGL: + return vk::BlendFactor::eOneMinusSrcColor; + case Maxwell::Blend::Factor::SourceAlpha: + case Maxwell::Blend::Factor::SourceAlphaGL: + return vk::BlendFactor::eSrcAlpha; + case Maxwell::Blend::Factor::OneMinusSourceAlpha: + case Maxwell::Blend::Factor::OneMinusSourceAlphaGL: + return vk::BlendFactor::eOneMinusSrcAlpha; + case Maxwell::Blend::Factor::DestAlpha: + case Maxwell::Blend::Factor::DestAlphaGL: + return vk::BlendFactor::eDstAlpha; + case Maxwell::Blend::Factor::OneMinusDestAlpha: + case Maxwell::Blend::Factor::OneMinusDestAlphaGL: + return vk::BlendFactor::eOneMinusDstAlpha; + case Maxwell::Blend::Factor::DestColor: + case Maxwell::Blend::Factor::DestColorGL: + return vk::BlendFactor::eDstColor; + case Maxwell::Blend::Factor::OneMinusDestColor: + case Maxwell::Blend::Factor::OneMinusDestColorGL: + return vk::BlendFactor::eOneMinusDstColor; + case Maxwell::Blend::Factor::SourceAlphaSaturate: + case Maxwell::Blend::Factor::SourceAlphaSaturateGL: + return vk::BlendFactor::eSrcAlphaSaturate; + case Maxwell::Blend::Factor::Source1Color: + case Maxwell::Blend::Factor::Source1ColorGL: + return vk::BlendFactor::eSrc1Color; + case Maxwell::Blend::Factor::OneMinusSource1Color: + case Maxwell::Blend::Factor::OneMinusSource1ColorGL: + return vk::BlendFactor::eOneMinusSrc1Color; + case Maxwell::Blend::Factor::Source1Alpha: + case Maxwell::Blend::Factor::Source1AlphaGL: + return vk::BlendFactor::eSrc1Alpha; + case Maxwell::Blend::Factor::OneMinusSource1Alpha: + case Maxwell::Blend::Factor::OneMinusSource1AlphaGL: + return vk::BlendFactor::eOneMinusSrc1Alpha; + case Maxwell::Blend::Factor::ConstantColor: + case Maxwell::Blend::Factor::ConstantColorGL: + return vk::BlendFactor::eConstantColor; + case Maxwell::Blend::Factor::OneMinusConstantColor: + case Maxwell::Blend::Factor::OneMinusConstantColorGL: + return vk::BlendFactor::eOneMinusConstantColor; + case Maxwell::Blend::Factor::ConstantAlpha: + case Maxwell::Blend::Factor::ConstantAlphaGL: + return vk::BlendFactor::eConstantAlpha; + case Maxwell::Blend::Factor::OneMinusConstantAlpha: + case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: + return vk::BlendFactor::eOneMinusConstantAlpha; + } + UNIMPLEMENTED_MSG("Unimplemented blend factor={}", static_cast<u32>(factor)); + return {}; +} + +vk::FrontFace FrontFace(Maxwell::Cull::FrontFace front_face) { + switch (front_face) { + case Maxwell::Cull::FrontFace::ClockWise: + return vk::FrontFace::eClockwise; + case Maxwell::Cull::FrontFace::CounterClockWise: + return vk::FrontFace::eCounterClockwise; + } + UNIMPLEMENTED_MSG("Unimplemented front face={}", static_cast<u32>(front_face)); + return {}; +} + +vk::CullModeFlags CullFace(Maxwell::Cull::CullFace cull_face) { + switch (cull_face) { + case Maxwell::Cull::CullFace::Front: + return vk::CullModeFlagBits::eFront; + case Maxwell::Cull::CullFace::Back: + return vk::CullModeFlagBits::eBack; + case Maxwell::Cull::CullFace::FrontAndBack: + return vk::CullModeFlagBits::eFrontAndBack; + } + UNIMPLEMENTED_MSG("Unimplemented cull face={}", static_cast<u32>(cull_face)); + return {}; +} + +vk::ComponentSwizzle SwizzleSource(Tegra::Texture::SwizzleSource swizzle) { + switch (swizzle) { + case Tegra::Texture::SwizzleSource::Zero: + return vk::ComponentSwizzle::eZero; + case Tegra::Texture::SwizzleSource::R: + return vk::ComponentSwizzle::eR; + case Tegra::Texture::SwizzleSource::G: + return vk::ComponentSwizzle::eG; + case Tegra::Texture::SwizzleSource::B: + return vk::ComponentSwizzle::eB; + case Tegra::Texture::SwizzleSource::A: + return vk::ComponentSwizzle::eA; + case Tegra::Texture::SwizzleSource::OneInt: + case Tegra::Texture::SwizzleSource::OneFloat: + return vk::ComponentSwizzle::eOne; + } + UNIMPLEMENTED_MSG("Unimplemented swizzle source={}", static_cast<u32>(swizzle)); + return {}; +} + +} // namespace Vulkan::MaxwellToVK diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h new file mode 100644 index 000000000..4cadc0721 --- /dev/null +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h @@ -0,0 +1,58 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <utility> +#include "common/common_types.h" +#include "video_core/engines/maxwell_3d.h" +#include "video_core/renderer_vulkan/declarations.h" +#include "video_core/renderer_vulkan/vk_device.h" +#include "video_core/surface.h" +#include "video_core/textures/texture.h" + +namespace Vulkan::MaxwellToVK { + +using Maxwell = Tegra::Engines::Maxwell3D::Regs; +using PixelFormat = VideoCore::Surface::PixelFormat; +using ComponentType = VideoCore::Surface::ComponentType; + +namespace Sampler { + +vk::Filter Filter(Tegra::Texture::TextureFilter filter); + +vk::SamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter); + +vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode); + +vk::CompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compare_func); + +} // namespace Sampler + +std::pair<vk::Format, bool> SurfaceFormat(const VKDevice& device, FormatType format_type, + PixelFormat pixel_format, ComponentType component_type); + +vk::ShaderStageFlagBits ShaderStage(Maxwell::ShaderStage stage); + +vk::PrimitiveTopology PrimitiveTopology(Maxwell::PrimitiveTopology topology); + +vk::Format VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size); + +vk::CompareOp ComparisonOp(Maxwell::ComparisonOp comparison); + +vk::IndexType IndexFormat(Maxwell::IndexFormat index_format); + +vk::StencilOp StencilOp(Maxwell::StencilOp stencil_op); + +vk::BlendOp BlendEquation(Maxwell::Blend::Equation equation); + +vk::BlendFactor BlendFactor(Maxwell::Blend::Factor factor); + +vk::FrontFace FrontFace(Maxwell::Cull::FrontFace front_face); + +vk::CullModeFlags CullFace(Maxwell::Cull::CullFace cull_face); + +vk::ComponentSwizzle SwizzleSource(Tegra::Texture::SwizzleSource swizzle); + +} // namespace Vulkan::MaxwellToVK diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp index 78a4e5f0e..00242ecbe 100644 --- a/src/video_core/renderer_vulkan/vk_device.cpp +++ b/src/video_core/renderer_vulkan/vk_device.cpp @@ -122,8 +122,7 @@ bool VKDevice::IsFormatSupported(vk::Format wanted_format, vk::FormatFeatureFlag FormatType format_type) const { const auto it = format_properties.find(wanted_format); if (it == format_properties.end()) { - LOG_CRITICAL(Render_Vulkan, "Unimplemented format query={}", - static_cast<u32>(wanted_format)); + LOG_CRITICAL(Render_Vulkan, "Unimplemented format query={}", vk::to_string(wanted_format)); UNREACHABLE(); return true; } @@ -219,11 +218,19 @@ std::map<vk::Format, vk::FormatProperties> VKDevice::GetFormatProperties( format_properties.emplace(format, physical.getFormatProperties(format, dldi)); }; AddFormatQuery(vk::Format::eA8B8G8R8UnormPack32); - AddFormatQuery(vk::Format::eR5G6B5UnormPack16); + AddFormatQuery(vk::Format::eB5G6R5UnormPack16); + AddFormatQuery(vk::Format::eA2B10G10R10UnormPack32); + AddFormatQuery(vk::Format::eR8G8B8A8Srgb); + AddFormatQuery(vk::Format::eR8Unorm); AddFormatQuery(vk::Format::eD32Sfloat); + AddFormatQuery(vk::Format::eD16Unorm); AddFormatQuery(vk::Format::eD16UnormS8Uint); AddFormatQuery(vk::Format::eD24UnormS8Uint); AddFormatQuery(vk::Format::eD32SfloatS8Uint); + AddFormatQuery(vk::Format::eBc1RgbaUnormBlock); + AddFormatQuery(vk::Format::eBc2UnormBlock); + AddFormatQuery(vk::Format::eBc3UnormBlock); + AddFormatQuery(vk::Format::eBc4UnormBlock); return format_properties; } |