diff options
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 2 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 49 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 47 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.h | 6 |
7 files changed, 124 insertions, 24 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 180be4ff4..a15ca9e43 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -413,7 +413,7 @@ public: | |||
| 413 | struct { | 413 | struct { |
| 414 | u32 address_high; | 414 | u32 address_high; |
| 415 | u32 address_low; | 415 | u32 address_low; |
| 416 | u32 format; | 416 | Tegra::DepthFormat format; |
| 417 | u32 block_dimensions; | 417 | u32 block_dimensions; |
| 418 | u32 layer_stride; | 418 | u32 layer_stride; |
| 419 | 419 | ||
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index d0a4ac267..cc5ca656e 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -24,6 +24,15 @@ enum class RenderTargetFormat : u32 { | |||
| 24 | R11G11B10_FLOAT = 0xE0, | 24 | R11G11B10_FLOAT = 0xE0, |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | enum class DepthFormat : u32 { | ||
| 28 | Z32_FLOAT = 0xA, | ||
| 29 | Z16_UNORM = 0x13, | ||
| 30 | S8_Z24_UNORM = 0x14, | ||
| 31 | Z24_X8_UNORM = 0x15, | ||
| 32 | Z24_S8_UNORM = 0x16, | ||
| 33 | Z24_C8_UNORM = 0x18, | ||
| 34 | }; | ||
| 35 | |||
| 27 | /// Returns the number of bytes per pixel of each rendertarget format. | 36 | /// Returns the number of bytes per pixel of each rendertarget format. |
| 28 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format); | 37 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format); |
| 29 | 38 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 62ee45a36..b80f4336d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -307,7 +307,9 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 307 | // TODO(bunnei): Implement these | 307 | // TODO(bunnei): Implement these |
| 308 | const bool has_stencil = false; | 308 | const bool has_stencil = false; |
| 309 | const bool using_color_fb = true; | 309 | const bool using_color_fb = true; |
| 310 | const bool using_depth_fb = false; | 310 | |
| 311 | const bool using_depth_fb = regs.zeta.Address() != 0; | ||
| 312 | |||
| 311 | const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; | 313 | const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; |
| 312 | 314 | ||
| 313 | const bool write_color_fb = | 315 | const bool write_color_fb = |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index ae48378f3..35ad4f161 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -84,22 +84,18 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form | |||
| 84 | true}, // DXT45 | 84 | true}, // DXT45 |
| 85 | {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, true}, // DXN1 | 85 | {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, true}, // DXN1 |
| 86 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4 | 86 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4 |
| 87 | |||
| 88 | // DepthStencil formats | ||
| 89 | {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm, | ||
| 90 | false}, // Z24S8 | ||
| 87 | }}; | 91 | }}; |
| 88 | 92 | ||
| 89 | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { | 93 | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { |
| 90 | const SurfaceType type = SurfaceParams::GetFormatType(pixel_format); | 94 | ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size()); |
| 91 | if (type == SurfaceType::ColorTexture) { | 95 | auto& format = tex_format_tuples[static_cast<unsigned int>(pixel_format)]; |
| 92 | ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size()); | 96 | ASSERT(component_type == format.component_type); |
| 93 | auto& format = tex_format_tuples[static_cast<unsigned int>(pixel_format)]; | ||
| 94 | ASSERT(component_type == format.component_type); | ||
| 95 | return format; | ||
| 96 | } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) { | ||
| 97 | // TODO(Subv): Implement depth formats | ||
| 98 | ASSERT_MSG(false, "Unimplemented"); | ||
| 99 | } | ||
| 100 | 97 | ||
| 101 | UNREACHABLE(); | 98 | return format; |
| 102 | return {}; | ||
| 103 | } | 99 | } |
| 104 | 100 | ||
| 105 | VAddr SurfaceParams::GetCpuAddr() const { | 101 | VAddr SurfaceParams::GetCpuAddr() const { |
| @@ -149,11 +145,17 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra:: | |||
| 149 | const auto& gpu = Core::System::GetInstance().GPU(); | 145 | const auto& gpu = Core::System::GetInstance().GPU(); |
| 150 | 146 | ||
| 151 | if (morton_to_gl) { | 147 | if (morton_to_gl) { |
| 152 | auto data = Tegra::Texture::UnswizzleTexture( | 148 | if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) { |
| 153 | *gpu.memory_manager->GpuToCpuAddress(addr), | 149 | auto data = Tegra::Texture::UnswizzleTexture( |
| 154 | SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); | 150 | *gpu.memory_manager->GpuToCpuAddress(addr), |
| 155 | 151 | SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); | |
| 156 | std::memcpy(gl_buffer, data.data(), data.size()); | 152 | std::memcpy(gl_buffer, data.data(), data.size()); |
| 153 | } else { | ||
| 154 | auto data = Tegra::Texture::UnswizzleDepthTexture( | ||
| 155 | *gpu.memory_manager->GpuToCpuAddress(addr), | ||
| 156 | SurfaceParams::DepthFormatFromPixelFormat(format), stride, height, block_height); | ||
| 157 | std::memcpy(gl_buffer, data.data(), data.size()); | ||
| 158 | } | ||
| 157 | } else { | 159 | } else { |
| 158 | // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should | 160 | // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should |
| 159 | // check the configuration for this and perform more generic un/swizzle | 161 | // check the configuration for this and perform more generic un/swizzle |
| @@ -174,7 +176,7 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), | |||
| 174 | MortonCopy<true, PixelFormat::R11FG11FB10F>, MortonCopy<true, PixelFormat::RGBA32UI>, | 176 | MortonCopy<true, PixelFormat::R11FG11FB10F>, MortonCopy<true, PixelFormat::RGBA32UI>, |
| 175 | MortonCopy<true, PixelFormat::DXT1>, MortonCopy<true, PixelFormat::DXT23>, | 177 | MortonCopy<true, PixelFormat::DXT1>, MortonCopy<true, PixelFormat::DXT23>, |
| 176 | MortonCopy<true, PixelFormat::DXT45>, MortonCopy<true, PixelFormat::DXN1>, | 178 | MortonCopy<true, PixelFormat::DXT45>, MortonCopy<true, PixelFormat::DXN1>, |
| 177 | MortonCopy<true, PixelFormat::ASTC_2D_4X4>, | 179 | MortonCopy<true, PixelFormat::ASTC_2D_4X4>, MortonCopy<true, PixelFormat::Z24S8>, |
| 178 | }; | 180 | }; |
| 179 | 181 | ||
| 180 | static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), | 182 | static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), |
| @@ -194,6 +196,7 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), | |||
| 194 | nullptr, | 196 | nullptr, |
| 195 | nullptr, | 197 | nullptr, |
| 196 | MortonCopy<false, PixelFormat::ABGR8>, | 198 | MortonCopy<false, PixelFormat::ABGR8>, |
| 199 | MortonCopy<false, PixelFormat::Z24S8>, | ||
| 197 | }; | 200 | }; |
| 198 | 201 | ||
| 199 | // Allocate an uninitialized texture of appropriate size and format for the surface | 202 | // Allocate an uninitialized texture of appropriate size and format for the surface |
| @@ -397,9 +400,15 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( | |||
| 397 | 400 | ||
| 398 | // get color and depth surfaces | 401 | // get color and depth surfaces |
| 399 | const SurfaceParams color_params{SurfaceParams::CreateForFramebuffer(regs.rt[0])}; | 402 | const SurfaceParams color_params{SurfaceParams::CreateForFramebuffer(regs.rt[0])}; |
| 400 | const SurfaceParams depth_params{color_params}; | 403 | SurfaceParams depth_params{color_params}; |
| 401 | 404 | ||
| 402 | ASSERT_MSG(!using_depth_fb, "depth buffer is unimplemented"); | 405 | if (using_depth_fb) { |
| 406 | depth_params.addr = regs.zeta.Address(); | ||
| 407 | depth_params.pixel_format = SurfaceParams::PixelFormatFromDepthFormat(regs.zeta.format); | ||
| 408 | depth_params.component_type = SurfaceParams::ComponentTypeFromDepthFormat(regs.zeta.format); | ||
| 409 | depth_params.type = SurfaceParams::GetFormatType(depth_params.pixel_format); | ||
| 410 | depth_params.size_in_bytes = depth_params.SizeInBytes(); | ||
| 411 | } | ||
| 403 | 412 | ||
| 404 | MathUtil::Rectangle<u32> color_rect{}; | 413 | MathUtil::Rectangle<u32> color_rect{}; |
| 405 | Surface color_surface; | 414 | Surface color_surface; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 99be250b4..eea432b0b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -37,7 +37,14 @@ struct SurfaceParams { | |||
| 37 | DXN1 = 11, // This is also known as BC4 | 37 | DXN1 = 11, // This is also known as BC4 |
| 38 | ASTC_2D_4X4 = 12, | 38 | ASTC_2D_4X4 = 12, |
| 39 | 39 | ||
| 40 | Max, | 40 | MaxColorFormat, |
| 41 | |||
| 42 | // DepthStencil formats | ||
| 43 | Z24S8 = 13, | ||
| 44 | |||
| 45 | MaxDepthStencilFormat, | ||
| 46 | |||
| 47 | Max = MaxDepthStencilFormat, | ||
| 41 | Invalid = 255, | 48 | Invalid = 255, |
| 42 | }; | 49 | }; |
| 43 | 50 | ||
| @@ -84,6 +91,7 @@ struct SurfaceParams { | |||
| 84 | 4, // DXT45 | 91 | 4, // DXT45 |
| 85 | 4, // DXN1 | 92 | 4, // DXN1 |
| 86 | 4, // ASTC_2D_4X4 | 93 | 4, // ASTC_2D_4X4 |
| 94 | 1, // Z24S8 | ||
| 87 | }}; | 95 | }}; |
| 88 | 96 | ||
| 89 | ASSERT(static_cast<size_t>(format) < compression_factor_table.size()); | 97 | ASSERT(static_cast<size_t>(format) < compression_factor_table.size()); |
| @@ -108,6 +116,7 @@ struct SurfaceParams { | |||
| 108 | 128, // DXT45 | 116 | 128, // DXT45 |
| 109 | 64, // DXN1 | 117 | 64, // DXN1 |
| 110 | 32, // ASTC_2D_4X4 | 118 | 32, // ASTC_2D_4X4 |
| 119 | 32, // Z24S8 | ||
| 111 | }}; | 120 | }}; |
| 112 | 121 | ||
| 113 | ASSERT(static_cast<size_t>(format) < bpp_table.size()); | 122 | ASSERT(static_cast<size_t>(format) < bpp_table.size()); |
| @@ -117,6 +126,16 @@ struct SurfaceParams { | |||
| 117 | return GetFormatBpp(pixel_format); | 126 | return GetFormatBpp(pixel_format); |
| 118 | } | 127 | } |
| 119 | 128 | ||
| 129 | static PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) { | ||
| 130 | switch (format) { | ||
| 131 | case Tegra::DepthFormat::Z24_S8_UNORM: | ||
| 132 | return PixelFormat::Z24S8; | ||
| 133 | default: | ||
| 134 | NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | ||
| 135 | UNREACHABLE(); | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 120 | static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { | 139 | static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { |
| 121 | switch (format) { | 140 | switch (format) { |
| 122 | case Tegra::RenderTargetFormat::RGBA8_UNORM: | 141 | case Tegra::RenderTargetFormat::RGBA8_UNORM: |
| @@ -205,6 +224,15 @@ struct SurfaceParams { | |||
| 205 | } | 224 | } |
| 206 | } | 225 | } |
| 207 | 226 | ||
| 227 | static Tegra::DepthFormat DepthFormatFromPixelFormat(PixelFormat format) { | ||
| 228 | switch (format) { | ||
| 229 | case PixelFormat::Z24S8: | ||
| 230 | return Tegra::DepthFormat::Z24_S8_UNORM; | ||
| 231 | default: | ||
| 232 | UNREACHABLE(); | ||
| 233 | } | ||
| 234 | } | ||
| 235 | |||
| 208 | static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) { | 236 | static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) { |
| 209 | // TODO(Subv): Implement more component types | 237 | // TODO(Subv): Implement more component types |
| 210 | switch (type) { | 238 | switch (type) { |
| @@ -244,11 +272,26 @@ struct SurfaceParams { | |||
| 244 | } | 272 | } |
| 245 | } | 273 | } |
| 246 | 274 | ||
| 275 | static ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format) { | ||
| 276 | switch (format) { | ||
| 277 | case Tegra::DepthFormat::Z24_S8_UNORM: | ||
| 278 | return ComponentType::UNorm; | ||
| 279 | default: | ||
| 280 | NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | ||
| 281 | UNREACHABLE(); | ||
| 282 | } | ||
| 283 | } | ||
| 284 | |||
| 247 | static SurfaceType GetFormatType(PixelFormat pixel_format) { | 285 | static SurfaceType GetFormatType(PixelFormat pixel_format) { |
| 248 | if (static_cast<size_t>(pixel_format) < MaxPixelFormat) { | 286 | if (static_cast<size_t>(pixel_format) < static_cast<size_t>(PixelFormat::MaxColorFormat)) { |
| 249 | return SurfaceType::ColorTexture; | 287 | return SurfaceType::ColorTexture; |
| 250 | } | 288 | } |
| 251 | 289 | ||
| 290 | if (static_cast<size_t>(pixel_format) < | ||
| 291 | static_cast<size_t>(PixelFormat::MaxDepthStencilFormat)) { | ||
| 292 | return SurfaceType::DepthStencil; | ||
| 293 | } | ||
| 294 | |||
| 252 | // TODO(Subv): Implement the other formats | 295 | // TODO(Subv): Implement the other formats |
| 253 | ASSERT(false); | 296 | ASSERT(false); |
| 254 | 297 | ||
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index eaf15da32..680f22ddb 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <cstring> | 5 | #include <cstring> |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "core/memory.h" | 7 | #include "core/memory.h" |
| 8 | #include "video_core/gpu.h" | ||
| 8 | #include "video_core/textures/decoders.h" | 9 | #include "video_core/textures/decoders.h" |
| 9 | #include "video_core/textures/texture.h" | 10 | #include "video_core/textures/texture.h" |
| 10 | 11 | ||
| @@ -73,6 +74,16 @@ u32 BytesPerPixel(TextureFormat format) { | |||
| 73 | } | 74 | } |
| 74 | } | 75 | } |
| 75 | 76 | ||
| 77 | static u32 DepthBytesPerPixel(DepthFormat format) { | ||
| 78 | switch (format) { | ||
| 79 | case DepthFormat::Z24_S8_UNORM: | ||
| 80 | return 4; | ||
| 81 | default: | ||
| 82 | UNIMPLEMENTED_MSG("Format not implemented"); | ||
| 83 | break; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 76 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, | 87 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, |
| 77 | u32 block_height) { | 88 | u32 block_height) { |
| 78 | u8* data = Memory::GetPointer(address); | 89 | u8* data = Memory::GetPointer(address); |
| @@ -110,6 +121,26 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, | |||
| 110 | return unswizzled_data; | 121 | return unswizzled_data; |
| 111 | } | 122 | } |
| 112 | 123 | ||
| 124 | std::vector<u8> UnswizzleDepthTexture(VAddr address, DepthFormat format, u32 width, u32 height, | ||
| 125 | u32 block_height) { | ||
| 126 | u8* data = Memory::GetPointer(address); | ||
| 127 | u32 bytes_per_pixel = DepthBytesPerPixel(format); | ||
| 128 | |||
| 129 | std::vector<u8> unswizzled_data(width * height * bytes_per_pixel); | ||
| 130 | |||
| 131 | switch (format) { | ||
| 132 | case DepthFormat::Z24_S8_UNORM: | ||
| 133 | CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, | ||
| 134 | unswizzled_data.data(), true, block_height); | ||
| 135 | break; | ||
| 136 | default: | ||
| 137 | UNIMPLEMENTED_MSG("Format not implemented"); | ||
| 138 | break; | ||
| 139 | } | ||
| 140 | |||
| 141 | return unswizzled_data; | ||
| 142 | } | ||
| 143 | |||
| 113 | std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width, | 144 | std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width, |
| 114 | u32 height) { | 145 | u32 height) { |
| 115 | std::vector<u8> rgba_data; | 146 | std::vector<u8> rgba_data; |
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index 2562c4b06..2b088c077 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h | |||
| @@ -17,6 +17,12 @@ namespace Texture { | |||
| 17 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, | 17 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, |
| 18 | u32 block_height = TICEntry::DefaultBlockHeight); | 18 | u32 block_height = TICEntry::DefaultBlockHeight); |
| 19 | 19 | ||
| 20 | /** | ||
| 21 | * Unswizzles a swizzled depth texture without changing its format. | ||
| 22 | */ | ||
| 23 | std::vector<u8> UnswizzleDepthTexture(VAddr address, DepthFormat format, u32 width, u32 height, | ||
| 24 | u32 block_height = TICEntry::DefaultBlockHeight); | ||
| 25 | |||
| 20 | /// Copies texture data from a buffer and performs swizzling/unswizzling as necessary. | 26 | /// Copies texture data from a buffer and performs swizzling/unswizzling as necessary. |
| 21 | void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, | 27 | void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, |
| 22 | u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height); | 28 | u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height); |