diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 05e5c94f3..c89a5d693 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -83,6 +83,7 @@ enum class DepthFormat : u32 { S8_UINT_Z24_UNORM = 0x14, D24X8_UNORM = 0x15, D24S8_UNORM = 0x16, + S8_UINT = 0x17, D24C8_UNORM = 0x18, D32_FLOAT_S8X24_UINT = 0x19, }; diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 6956535e5..9e7850428 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -148,6 +148,8 @@ GLenum AttachmentType(PixelFormat format) { switch (const SurfaceType type = VideoCore::Surface::GetFormatType(format); type) { case SurfaceType::Depth: return GL_DEPTH_ATTACHMENT; + case SurfaceType::Stencil: + return GL_STENCIL_ATTACHMENT; case SurfaceType::DepthStencil: return GL_DEPTH_STENCIL_ATTACHMENT; default: @@ -907,6 +909,8 @@ void Image::Scale(bool up_scale) { return GL_COLOR_ATTACHMENT0; case SurfaceType::Depth: return GL_DEPTH_ATTACHMENT; + case SurfaceType::Stencil: + return GL_STENCIL_ATTACHMENT; case SurfaceType::DepthStencil: return GL_DEPTH_STENCIL_ATTACHMENT; default: @@ -920,8 +924,10 @@ void Image::Scale(bool up_scale) { return GL_COLOR_BUFFER_BIT; case SurfaceType::Depth: return GL_DEPTH_BUFFER_BIT; + case SurfaceType::Stencil: + return GL_STENCIL_BUFFER_BIT; case SurfaceType::DepthStencil: - return GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; + return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; default: UNREACHABLE(); return GL_COLOR_BUFFER_BIT; @@ -933,8 +939,10 @@ void Image::Scale(bool up_scale) { return 0; case SurfaceType::Depth: return 1; - case SurfaceType::DepthStencil: + case SurfaceType::Stencil: return 2; + case SurfaceType::DepthStencil: + return 3; default: UNREACHABLE(); return 0; @@ -1264,10 +1272,20 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::spanformat) == SurfaceType::DepthStencil) { - buffer_bits |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; - } else { + switch (GetFormatType(image_view->format)) { + case SurfaceType::Depth: buffer_bits |= GL_DEPTH_BUFFER_BIT; + break; + case SurfaceType::Stencil: + buffer_bits |= GL_STENCIL_BUFFER_BIT; + break; + case SurfaceType::DepthStencil: + buffer_bits |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; + break; + default: + UNREACHABLE(); + buffer_bits |= GL_DEPTH_BUFFER_BIT; + break; } const GLenum attachment = AttachmentType(image_view->format); AttachTexture(handle, attachment, image_view); diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 578f8d523..40acc8fad 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -164,8 +164,8 @@ private: std::array null_image_views{}; - std::array rescale_draw_fbos; - std::array rescale_read_fbos; + std::array rescale_draw_fbos; + std::array rescale_read_fbos; const Settings::ResolutionScalingInfo& resolution; }; diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index 39158aa3e..daba42ed9 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h @@ -108,6 +108,7 @@ constexpr std::array FORMAT_TAB {GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, // E5B9G9R9_FLOAT {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // D32_FLOAT {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16_UNORM + {GL_STENCIL_INDEX8, GL_STENCIL, GL_UNSIGNED_BYTE}, // S8_UINT {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24_UNORM_S8_UINT {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // S8_UINT_D24_UNORM {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 68a23b602..31adada56 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -208,6 +208,9 @@ struct FormatTuple { {VK_FORMAT_D32_SFLOAT, Attachable}, // D32_FLOAT {VK_FORMAT_D16_UNORM, Attachable}, // D16_UNORM + // Stencil formats + {VK_FORMAT_S8_UINT, Attachable}, // S8_UINT + // DepthStencil formats {VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // D24_UNORM_S8_UINT {VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // S8_UINT_D24_UNORM (emulated) diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 407fd2a15..9bc846b94 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -102,6 +102,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array& color) { usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; break; case VideoCore::Surface::SurfaceType::Depth: + case VideoCore::Surface::SurfaceType::Stencil: case VideoCore::Surface::SurfaceType::DepthStencil: usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; break; @@ -173,6 +174,8 @@ constexpr VkBorderColor ConvertBorderColor(const std::array& color) { return VK_IMAGE_ASPECT_COLOR_BIT; case VideoCore::Surface::SurfaceType::Depth: return VK_IMAGE_ASPECT_DEPTH_BIT; + case VideoCore::Surface::SurfaceType::Stencil: + return VK_IMAGE_ASPECT_STENCIL_BIT; case VideoCore::Surface::SurfaceType::DepthStencil: return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; default: @@ -195,6 +198,8 @@ constexpr VkBorderColor ConvertBorderColor(const std::array& color) { case PixelFormat::D16_UNORM: case PixelFormat::D32_FLOAT: return VK_IMAGE_ASPECT_DEPTH_BIT; + case PixelFormat::S8_UINT: + return VK_IMAGE_ASPECT_STENCIL_BIT; default: return VK_IMAGE_ASPECT_COLOR_BIT; } diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 58d262446..a36015c8c 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -82,6 +82,8 @@ PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) { return PixelFormat::D32_FLOAT; case Tegra::DepthFormat::D16_UNORM: return PixelFormat::D16_UNORM; + case Tegra::DepthFormat::S8_UINT: + return PixelFormat::S8_UINT; case Tegra::DepthFormat::D32_FLOAT_S8X24_UINT: return PixelFormat::D32_FLOAT_S8_UINT; default: @@ -213,6 +215,11 @@ SurfaceType GetFormatType(PixelFormat pixel_format) { return SurfaceType::Depth; } + if (static_cast(pixel_format) < + static_cast(PixelFormat::MaxStencilFormat)) { + return SurfaceType::Stencil; + } + if (static_cast(pixel_format) < static_cast(PixelFormat::MaxDepthStencilFormat)) { return SurfaceType::DepthStencil; diff --git a/src/video_core/surface.h b/src/video_core/surface.h index 2ce7c7d33..33e8d24ab 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -110,8 +110,12 @@ enum class PixelFormat { MaxDepthFormat, + // Stencil formats + S8_UINT = MaxDepthFormat, + MaxStencilFormat, + // DepthStencil formats - D24_UNORM_S8_UINT = MaxDepthFormat, + D24_UNORM_S8_UINT = MaxStencilFormat, S8_UINT_D24_UNORM, D32_FLOAT_S8_UINT, @@ -125,8 +129,9 @@ constexpr std::size_t MaxPixelFormat = static_cast(PixelFormat::Max enum class SurfaceType { ColorTexture = 0, Depth = 1, - DepthStencil = 2, - Invalid = 3, + Stencil = 2, + DepthStencil = 3, + Invalid = 4, }; enum class SurfaceTarget { @@ -229,6 +234,7 @@ constexpr std::array BLOCK_WIDTH_TABLE = {{ 1, // E5B9G9R9_FLOAT 1, // D32_FLOAT 1, // D16_UNORM + 1, // S8_UINT 1, // D24_UNORM_S8_UINT 1, // S8_UINT_D24_UNORM 1, // D32_FLOAT_S8_UINT @@ -328,6 +334,7 @@ constexpr std::array BLOCK_HEIGHT_TABLE = {{ 1, // E5B9G9R9_FLOAT 1, // D32_FLOAT 1, // D16_UNORM + 1, // S8_UINT 1, // D24_UNORM_S8_UINT 1, // S8_UINT_D24_UNORM 1, // D32_FLOAT_S8_UINT @@ -427,6 +434,7 @@ constexpr std::array BITS_PER_BLOCK_TABLE = {{ 32, // E5B9G9R9_FLOAT 32, // D32_FLOAT 16, // D16_UNORM + 8, // S8_UINT 32, // D24_UNORM_S8_UINT 32, // S8_UINT_D24_UNORM 64, // D32_FLOAT_S8_UINT diff --git a/src/video_core/texture_cache/formatter.h b/src/video_core/texture_cache/formatter.h index c6cf0583f..b2c81057b 100644 --- a/src/video_core/texture_cache/formatter.h +++ b/src/video_core/texture_cache/formatter.h @@ -194,6 +194,8 @@ struct fmt::formatter : fmt::formatter GetFormatProperties(vk::Physica VK_FORMAT_R4G4B4A4_UNORM_PACK16, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM, + VK_FORMAT_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT,