summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/memory_manager.cpp53
-rw-r--r--src/video_core/memory_manager.h6
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h14
-rw-r--r--src/video_core/textures/decoders.cpp3
-rw-r--r--src/video_core/textures/texture.h1
-rw-r--r--src/yuzu/debugger/graphics/graphics_surface.cpp2
7 files changed, 47 insertions, 40 deletions
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index 2789a4ca1..2e1edee03 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/alignment.h"
#include "common/assert.h"
#include "video_core/memory_manager.h"
@@ -11,7 +12,8 @@ PAddr MemoryManager::AllocateSpace(u64 size, u64 align) {
boost::optional<PAddr> paddr = FindFreeBlock(size, align);
ASSERT(paddr);
- for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) {
+ for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
+ ASSERT(PageSlot(*paddr + offset) == static_cast<u64>(PageStatus::Unmapped));
PageSlot(*paddr + offset) = static_cast<u64>(PageStatus::Allocated);
}
@@ -19,13 +21,8 @@ PAddr MemoryManager::AllocateSpace(u64 size, u64 align) {
}
PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) {
- for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) {
- if (IsPageMapped(paddr + offset)) {
- return AllocateSpace(size, align);
- }
- }
-
- for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) {
+ for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
+ ASSERT(PageSlot(paddr + offset) == static_cast<u64>(PageStatus::Unmapped));
PageSlot(paddr + offset) = static_cast<u64>(PageStatus::Allocated);
}
@@ -33,12 +30,11 @@ PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) {
}
PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) {
- vaddr &= ~Memory::PAGE_MASK;
-
- boost::optional<PAddr> paddr = FindFreeBlock(size);
+ boost::optional<PAddr> paddr = FindFreeBlock(size, PAGE_SIZE);
ASSERT(paddr);
- for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) {
+ for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
+ ASSERT(PageSlot(*paddr + offset) == static_cast<u64>(PageStatus::Unmapped));
PageSlot(*paddr + offset) = vaddr + offset;
}
@@ -46,16 +42,10 @@ PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) {
}
PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) {
- vaddr &= ~Memory::PAGE_MASK;
- paddr &= ~Memory::PAGE_MASK;
+ ASSERT((paddr & PAGE_MASK) == 0);
- for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) {
- if (PageSlot(paddr + offset) != static_cast<u64>(PageStatus::Allocated)) {
- return MapBufferEx(vaddr, size);
- }
- }
-
- for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) {
+ for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
+ ASSERT(PageSlot(paddr + offset) == static_cast<u64>(PageStatus::Allocated));
PageSlot(paddr + offset) = vaddr + offset;
}
@@ -63,23 +53,20 @@ PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) {
}
boost::optional<PAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
- PAddr paddr{};
- u64 free_space{};
- align = (align + Memory::PAGE_MASK) & ~Memory::PAGE_MASK;
+ PAddr paddr = 0;
+ u64 free_space = 0;
+ align = (align + PAGE_MASK) & ~PAGE_MASK;
while (paddr + free_space < MAX_ADDRESS) {
if (!IsPageMapped(paddr + free_space)) {
- free_space += Memory::PAGE_SIZE;
+ free_space += PAGE_SIZE;
if (free_space >= size) {
return paddr;
}
} else {
- paddr += free_space + Memory::PAGE_SIZE;
+ paddr += free_space + PAGE_SIZE;
free_space = 0;
- const u64 remainder{paddr % align};
- if (!remainder) {
- paddr = (paddr - remainder) + align;
- }
+ paddr = Common::AlignUp(paddr, align);
}
}
@@ -89,7 +76,7 @@ boost::optional<PAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
VAddr MemoryManager::PhysicalToVirtualAddress(PAddr paddr) {
VAddr base_addr = PageSlot(paddr);
ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped));
- return base_addr + (paddr & Memory::PAGE_MASK);
+ return base_addr + (paddr & PAGE_MASK);
}
bool MemoryManager::IsPageMapped(PAddr paddr) {
@@ -97,14 +84,14 @@ bool MemoryManager::IsPageMapped(PAddr paddr) {
}
VAddr& MemoryManager::PageSlot(PAddr paddr) {
- auto& block = page_table[(paddr >> (Memory::PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK];
+ auto& block = page_table[(paddr >> (PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK];
if (!block) {
block = std::make_unique<PageBlock>();
for (unsigned index = 0; index < PAGE_BLOCK_SIZE; index++) {
(*block)[index] = static_cast<u64>(PageStatus::Unmapped);
}
}
- return (*block)[(paddr >> Memory::PAGE_BITS) & PAGE_BLOCK_MASK];
+ return (*block)[(paddr >> PAGE_BITS) & PAGE_BLOCK_MASK];
}
} // namespace Tegra
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index 47da7acd6..b73e283f8 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -24,6 +24,10 @@ public:
PAddr MapBufferEx(VAddr vaddr, PAddr paddr, u64 size);
VAddr PhysicalToVirtualAddress(PAddr paddr);
+ static constexpr u64 PAGE_BITS = 16;
+ static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS;
+ static constexpr u64 PAGE_MASK = PAGE_SIZE - 1;
+
private:
boost::optional<PAddr> FindFreeBlock(u64 size, u64 align = 1);
bool IsPageMapped(PAddr paddr);
@@ -35,7 +39,7 @@ private:
};
static constexpr u64 MAX_ADDRESS{0x10000000000ULL};
- static constexpr u64 PAGE_TABLE_BITS{14};
+ static constexpr u64 PAGE_TABLE_BITS{10};
static constexpr u64 PAGE_TABLE_SIZE{1 << PAGE_TABLE_BITS};
static constexpr u64 PAGE_TABLE_MASK{PAGE_TABLE_SIZE - 1};
static constexpr u64 PAGE_BLOCK_BITS{14};
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index ced2b8247..7410471cc 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -49,6 +49,7 @@ struct FormatTuple {
static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false, 1}, // ABGR8
{GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false, 1}, // B5G6R5
+ {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false, 1}, // A2B10G10R10
{GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT1
{GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT23
{GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT45
@@ -104,9 +105,9 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, VAddr b
static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr),
SurfaceParams::MaxPixelFormat>
morton_to_gl_fns = {
- MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>,
- MortonCopy<true, PixelFormat::DXT1>, MortonCopy<true, PixelFormat::DXT23>,
- MortonCopy<true, PixelFormat::DXT45>,
+ MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>,
+ MortonCopy<true, PixelFormat::A2B10G10R10>, MortonCopy<true, PixelFormat::DXT1>,
+ MortonCopy<true, PixelFormat::DXT23>, MortonCopy<true, PixelFormat::DXT45>,
};
static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr),
@@ -114,6 +115,7 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr),
gl_to_morton_fns = {
MortonCopy<false, PixelFormat::ABGR8>,
MortonCopy<false, PixelFormat::B5G6R5>,
+ MortonCopy<false, PixelFormat::A2B10G10R10>,
// TODO(Subv): Swizzling the DXT1/DXT23/DXT45 formats is not yet supported
nullptr,
nullptr,
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 6861efe16..bf0fabb29 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -54,9 +54,10 @@ struct SurfaceParams {
enum class PixelFormat {
ABGR8 = 0,
B5G6R5 = 1,
- DXT1 = 2,
- DXT23 = 3,
- DXT45 = 4,
+ A2B10G10R10 = 2,
+ DXT1 = 3,
+ DXT23 = 4,
+ DXT45 = 5,
Max,
Invalid = 255,
@@ -88,6 +89,7 @@ struct SurfaceParams {
constexpr std::array<unsigned int, MaxPixelFormat> bpp_table = {
32, // ABGR8
16, // B5G6R5
+ 32, // A2B10G10R10
64, // DXT1
128, // DXT23
128, // DXT45
@@ -104,6 +106,8 @@ struct SurfaceParams {
switch (format) {
case Tegra::RenderTargetFormat::RGBA8_UNORM:
return PixelFormat::ABGR8;
+ case Tegra::RenderTargetFormat::RGB10_A2_UNORM:
+ return PixelFormat::A2B10G10R10;
default:
NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
UNREACHABLE();
@@ -127,6 +131,8 @@ struct SurfaceParams {
return PixelFormat::ABGR8;
case Tegra::Texture::TextureFormat::B5G6R5:
return PixelFormat::B5G6R5;
+ case Tegra::Texture::TextureFormat::A2B10G10R10:
+ return PixelFormat::A2B10G10R10;
case Tegra::Texture::TextureFormat::DXT1:
return PixelFormat::DXT1;
case Tegra::Texture::TextureFormat::DXT23:
@@ -146,6 +152,8 @@ struct SurfaceParams {
return Tegra::Texture::TextureFormat::A8R8G8B8;
case PixelFormat::B5G6R5:
return Tegra::Texture::TextureFormat::B5G6R5;
+ case PixelFormat::A2B10G10R10:
+ return Tegra::Texture::TextureFormat::A2B10G10R10;
case PixelFormat::DXT1:
return Tegra::Texture::TextureFormat::DXT1;
case PixelFormat::DXT23:
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 4df687786..e0509f0ce 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -53,6 +53,7 @@ u32 BytesPerPixel(TextureFormat format) {
// In this case a 'pixel' actually refers to a 4x4 tile.
return 16;
case TextureFormat::A8R8G8B8:
+ case TextureFormat::A2B10G10R10:
return 4;
case TextureFormat::B5G6R5:
return 2;
@@ -78,6 +79,7 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width,
unswizzled_data.data(), true, block_height);
break;
case TextureFormat::A8R8G8B8:
+ case TextureFormat::A2B10G10R10:
case TextureFormat::B5G6R5:
CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
unswizzled_data.data(), true, block_height);
@@ -100,6 +102,7 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat
case TextureFormat::DXT23:
case TextureFormat::DXT45:
case TextureFormat::A8R8G8B8:
+ case TextureFormat::A2B10G10R10:
case TextureFormat::B5G6R5:
// TODO(Subv): For the time being just forward the same data without any decoding.
rgba_data = texture_data;
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h
index 86e45aa88..dc004d361 100644
--- a/src/video_core/textures/texture.h
+++ b/src/video_core/textures/texture.h
@@ -15,6 +15,7 @@ namespace Texture {
enum class TextureFormat : u32 {
A8R8G8B8 = 0x8,
+ A2B10G10R10 = 0x9,
B5G6R5 = 0x15,
DXT1 = 0x24,
DXT23 = 0x25,
diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp
index 1e4844b57..5fada74be 100644
--- a/src/yuzu/debugger/graphics/graphics_surface.cpp
+++ b/src/yuzu/debugger/graphics/graphics_surface.cpp
@@ -25,6 +25,8 @@ static Tegra::Texture::TextureFormat ConvertToTextureFormat(
switch (render_target_format) {
case Tegra::RenderTargetFormat::RGBA8_UNORM:
return Tegra::Texture::TextureFormat::A8R8G8B8;
+ case Tegra::RenderTargetFormat::RGB10_A2_UNORM:
+ return Tegra::Texture::TextureFormat::A2B10G10R10;
default:
UNIMPLEMENTED_MSG("Unimplemented RT format");
}