diff options
Diffstat (limited to '')
-rw-r--r-- | src/video_core/gpu.h | 1 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 53 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 5 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/maxwell_to_gl.h | 1 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 3 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 5 | ||||
-rw-r--r-- | src/video_core/surface.cpp | 7 | ||||
-rw-r--r-- | src/video_core/surface.h | 14 | ||||
-rw-r--r-- | src/video_core/texture_cache/formatter.h | 2 | ||||
-rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 10 |
10 files changed, 82 insertions, 19 deletions
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 ecb215a7d..14e6522f2 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -149,6 +149,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: @@ -318,13 +320,12 @@ void AttachTexture(GLuint fbo, GLenum attachment, const ImageView* image_view) { } } -OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_format) { +OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_format, + GLsizei gl_num_levels) { const GLenum target = ImageTarget(info); const GLsizei width = info.size.width; const GLsizei height = info.size.height; const GLsizei depth = info.size.depth; - const int max_host_mip_levels = std::bit_width(info.size.width); - const GLsizei num_levels = std::min(info.resources.levels, max_host_mip_levels); const GLsizei num_layers = info.resources.layers; const GLsizei num_samples = info.num_samples; @@ -336,10 +337,10 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form } switch (target) { case GL_TEXTURE_1D_ARRAY: - glTextureStorage2D(handle, num_levels, gl_internal_format, width, num_layers); + glTextureStorage2D(handle, gl_num_levels, gl_internal_format, width, num_layers); break; case GL_TEXTURE_2D_ARRAY: - glTextureStorage3D(handle, num_levels, gl_internal_format, width, height, num_layers); + glTextureStorage3D(handle, gl_num_levels, gl_internal_format, width, height, num_layers); break; case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: { // TODO: Where should 'fixedsamplelocations' come from? @@ -349,10 +350,10 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form break; } case GL_TEXTURE_RECTANGLE: - glTextureStorage2D(handle, num_levels, gl_internal_format, width, height); + glTextureStorage2D(handle, gl_num_levels, gl_internal_format, width, height); break; case GL_TEXTURE_3D: - glTextureStorage3D(handle, num_levels, gl_internal_format, width, height, depth); + glTextureStorage3D(handle, gl_num_levels, gl_internal_format, width, height, depth); break; case GL_TEXTURE_BUFFER: UNREACHABLE(); @@ -694,7 +695,9 @@ Image::Image(TextureCacheRuntime& runtime_, const VideoCommon::ImageInfo& info_, gl_format = tuple.format; gl_type = tuple.type; } - texture = MakeImage(info, gl_internal_format); + const int max_host_mip_levels = std::bit_width(info.size.width); + gl_num_levels = std::min(info.resources.levels, max_host_mip_levels); + texture = MakeImage(info, gl_internal_format, gl_num_levels); current_texture = texture.handle; if (runtime->device.HasDebuggingToolAttached()) { const std::string name = VideoCommon::Name(*this); @@ -722,6 +725,9 @@ void Image::UploadMemory(const ImageBufferMap& map, u32 current_image_height = std::numeric_limits<u32>::max(); for (const VideoCommon::BufferImageCopy& copy : copies) { + if (copy.image_subresource.base_level >= gl_num_levels) { + continue; + } if (current_row_length != copy.buffer_row_length) { current_row_length = copy.buffer_row_length; glPixelStorei(GL_UNPACK_ROW_LENGTH, current_row_length); @@ -751,6 +757,9 @@ void Image::DownloadMemory(ImageBufferMap& map, u32 current_image_height = std::numeric_limits<u32>::max(); for (const VideoCommon::BufferImageCopy& copy : copies) { + if (copy.image_subresource.base_level >= gl_num_levels) { + continue; + } if (current_row_length != copy.buffer_row_length) { current_row_length = copy.buffer_row_length; glPixelStorei(GL_PACK_ROW_LENGTH, current_row_length); @@ -790,7 +799,7 @@ GLuint Image::StorageHandle() noexcept { } store_view.Create(); glTextureView(store_view.handle, ImageTarget(info), current_texture, GL_RGBA8, 0, - info.resources.levels, 0, info.resources.layers); + gl_num_levels, 0, info.resources.layers); return store_view.handle; default: return current_texture; @@ -905,6 +914,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: @@ -918,8 +929,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; @@ -931,8 +944,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; @@ -954,7 +969,7 @@ void Image::Scale(bool up_scale) { auto dst_info = info; dst_info.size.width = scaled_width; dst_info.size.height = scaled_height; - upscaled_backup = MakeImage(dst_info, gl_internal_format); + upscaled_backup = MakeImage(dst_info, gl_internal_format, gl_num_levels); } const u32 src_width = up_scale ? original_width : scaled_width; const u32 src_height = up_scale ? original_height : scaled_height; @@ -1262,10 +1277,20 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM } if (const ImageView* const image_view = depth_buffer; image_view) { - if (GetFormatType(image_view->format) == SurfaceType::DepthStencil) { + 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; - } else { + 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 ad5157d66..37d5e6a6b 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -168,8 +168,8 @@ private: std::array<GLuint, Shader::NUM_TEXTURE_TYPES> null_image_views{}; - std::array<OGLFramebuffer, 3> rescale_draw_fbos; - std::array<OGLFramebuffer, 3> rescale_read_fbos; + std::array<OGLFramebuffer, 4> rescale_draw_fbos; + std::array<OGLFramebuffer, 4> rescale_read_fbos; const Settings::ResolutionScalingInfo& resolution; }; @@ -225,6 +225,7 @@ private: GLenum gl_internal_format = GL_NONE; GLenum gl_format = GL_NONE; GLenum gl_type = GL_NONE; + GLsizei gl_num_levels{}; TextureCacheRuntime* runtime{}; GLuint current_texture{}; }; 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<FormatTuple, VideoCore::Surface::MaxPixelFormat> 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 f194110e5..3964424af 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -103,6 +103,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& 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; @@ -174,6 +175,8 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& 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: @@ -196,6 +199,8 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& 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: @@ -214,6 +216,11 @@ SurfaceType GetFormatType(PixelFormat pixel_format) { } if (static_cast<std::size_t>(pixel_format) < + static_cast<std::size_t>(PixelFormat::MaxStencilFormat)) { + return SurfaceType::Stencil; + } + + if (static_cast<std::size_t>(pixel_format) < static_cast<std::size_t>(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<std::size_t>(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<u32, MaxPixelFormat> 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<u32, MaxPixelFormat> 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<u32, MaxPixelFormat> 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<VideoCore::Surface::PixelFormat> : fmt::formatter<fmt::str return "D32_FLOAT"; case PixelFormat::D16_UNORM: return "D16_UNORM"; + case PixelFormat::S8_UINT: + return "S8_UINT"; case PixelFormat::D24_UNORM_S8_UINT: return "D24_UNORM_S8_UINT"; case PixelFormat::S8_UINT_D24_UNORM: diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 95106f88f..70c52aaac 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -21,6 +21,13 @@ namespace Vulkan { namespace { namespace Alternatives { +constexpr std::array STENCIL8_UINT{ + VK_FORMAT_D16_UNORM_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT, + VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_UNDEFINED, +}; + constexpr std::array DEPTH24_UNORM_STENCIL8_UINT{ VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, @@ -74,6 +81,8 @@ void SetNext(void**& next, T& data) { constexpr const VkFormat* GetFormatAlternatives(VkFormat format) { switch (format) { + case VK_FORMAT_S8_UINT: + return Alternatives::STENCIL8_UINT.data(); case VK_FORMAT_D24_UNORM_S8_UINT: return Alternatives::DEPTH24_UNORM_STENCIL8_UINT.data(); case VK_FORMAT_D16_UNORM_S8_UINT: @@ -145,6 +154,7 @@ std::unordered_map<VkFormat, VkFormatProperties> 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, |