Compare commits

..

14 Commits

Author SHA1 Message Date
Lioncash
8eb97706b8 qt/game_list: Resolve truncation warning within GameListItemPath's constructor
Silences a warning about truncating from size_t to u32
2018-08-10 18:19:44 -04:00
Lioncash
aaf671a309 gt/game_list: Use std::array in GameListItemPath's data() function
We don't need to use a heap-allocated std::vector here, given we
explicitly know the bounds.
2018-08-10 18:19:40 -04:00
Lioncash
be53097577 qt/game_list: Remove redundant base class constructor from initializer list
This is called automatically anyways.
2018-08-10 18:17:39 -04:00
bunnei
0a003efde4 Merge pull request #1007 from MerryMage/dynarmic
dynarmic: Update to 0118ee0
2018-08-10 15:57:50 -04:00
bunnei
2e8620c877 Merge pull request #1011 from bunnei/misc-vtx-fmt
Implements VertexAttributes Size_32_32_32 and Size_8_8.
2018-08-10 15:57:28 -04:00
bunnei
6b0bc48a42 maxwell_to_gl: Implement VertexAttribute::Size::Size_8_8.
- Used by Super Mario Odyssey.
2018-08-10 12:47:00 -04:00
bunnei
a5b65df9cf maxwell_to_gl: Implement VertexAttribute::Size::Size_32_32_32.
- Used by Super Mario Odyssey.
2018-08-10 12:46:49 -04:00
bunnei
57626fda7b Merge pull request #1004 from lioncash/unused
gl_rasterizer_cache: Remove unused viewport parameter of GetFramebufferSurfaces()
2018-08-10 12:13:32 -04:00
bunnei
6313d54cef Merge pull request #1008 from yuzu-emu/revert-697-disable-depth-cull
Revert "gl_state: Temporarily disable culling and depth test."
2018-08-10 12:13:09 -04:00
bunnei
7e6a73963e Merge pull request #1002 from bunnei/refactor-tex-fmt
textures: Refactor out for Texture/Depth FormatFromPixelFormat.
2018-08-10 11:06:23 -04:00
bunnei
2156cb3cbe Revert "gl_state: Temporarily disable culling and depth test." 2018-08-10 10:39:46 -04:00
MerryMage
ef41983c84 dynarmic: Update to 0118ee0
0118ee0 emit_x64_vector: packusdw is SSE4.1
2018-08-10 11:15:04 +01:00
Lioncash
0e1510ac29 gl_rasterizer_cache: Remove unused viewport parameter of GetFramebufferSurfaces() 2018-08-09 20:55:41 -04:00
bunnei
3a67876252 textures: Refactor out for Texture/Depth FormatFromPixelFormat. 2018-08-09 20:36:03 -04:00
10 changed files with 69 additions and 207 deletions

View File

@@ -198,13 +198,27 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st
#ifdef _WIN32
std::string UTF16ToUTF8(const std::u16string& input) {
#if _MSC_VER >= 1900
// Workaround for missing char16_t/char32_t instantiations in MSVC2015
std::wstring_convert<std::codecvt_utf8_utf16<__int16>, __int16> convert;
std::basic_string<__int16> tmp_buffer(input.cbegin(), input.cend());
return convert.to_bytes(tmp_buffer);
#else
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
return convert.to_bytes(input);
#endif
}
std::u16string UTF8ToUTF16(const std::string& input) {
#if _MSC_VER >= 1900
// Workaround for missing char16_t/char32_t instantiations in MSVC2015
std::wstring_convert<std::codecvt_utf8_utf16<__int16>, __int16> convert;
auto tmp_buffer = convert.from_bytes(input);
return std::u16string(tmp_buffer.cbegin(), tmp_buffer.cend());
#else
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
return convert.from_bytes(input);
#endif
}
static std::wstring CPToUTF16(u32 code_page, const std::string& input) {

View File

@@ -332,8 +332,6 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c
// TODO(bunnei): Implement this
const bool has_stencil = false;
const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
const bool write_color_fb =
state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE ||
state.color_mask.blue_enabled == GL_TRUE || state.color_mask.alpha_enabled == GL_TRUE;
@@ -346,9 +344,10 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c
Surface depth_surface;
MathUtil::Rectangle<u32> surfaces_rect;
std::tie(color_surface, depth_surface, surfaces_rect) =
res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect);
res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb);
MathUtil::Rectangle<u32> draw_rect{
const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
const MathUtil::Rectangle<u32> draw_rect{
static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.left,
surfaces_rect.left, surfaces_rect.right)), // Left
static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.top,
@@ -812,9 +811,7 @@ void RasterizerOpenGL::SyncClipCoef() {
void RasterizerOpenGL::SyncCullMode() {
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
// TODO(bunnei): Enable the below once more things work - until then, this may hide regressions
// state.cull.enabled = regs.cull.enabled != 0;
state.cull.enabled = false;
state.cull.enabled = regs.cull.enabled != 0;
if (state.cull.enabled) {
state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face);

View File

@@ -183,6 +183,21 @@ MathUtil::Rectangle<u32> SurfaceParams::GetRect() const {
return {0, actual_height, width, 0};
}
/// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN
static bool IsFormatBCn(PixelFormat format) {
switch (format) {
case PixelFormat::DXT1:
case PixelFormat::DXT23:
case PixelFormat::DXT45:
case PixelFormat::DXN1:
case PixelFormat::DXN2SNORM:
case PixelFormat::DXN2UNORM:
case PixelFormat::BC7U:
return true;
}
return false;
}
template <bool morton_to_gl, PixelFormat format>
void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_buffer,
Tegra::GPUVAddr addr) {
@@ -191,16 +206,12 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_bu
const auto& gpu = Core::System::GetInstance().GPU();
if (morton_to_gl) {
std::vector<u8> data;
if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) {
data = Tegra::Texture::UnswizzleTexture(
*gpu.memory_manager->GpuToCpuAddress(addr),
SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height);
} else {
data = Tegra::Texture::UnswizzleDepthTexture(
*gpu.memory_manager->GpuToCpuAddress(addr),
SurfaceParams::DepthFormatFromPixelFormat(format), stride, height, block_height);
}
// With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual
// pixel values.
const u32 tile_size{IsFormatBCn(format) ? 4U : 1U};
const std::vector<u8> data =
Tegra::Texture::UnswizzleTexture(*gpu.memory_manager->GpuToCpuAddress(addr), tile_size,
bytes_per_pixel, stride, height, block_height);
const size_t size_to_copy{std::min(gl_buffer.size(), data.size())};
gl_buffer.assign(data.begin(), data.begin() + size_to_copy);
} else {
@@ -611,8 +622,8 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
return GetSurface(SurfaceParams::CreateForTexture(config));
}
SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) {
SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(bool using_color_fb,
bool using_depth_fb) {
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
// TODO(bunnei): This is hard corded to use just the first render buffer

View File

@@ -348,92 +348,6 @@ struct SurfaceParams {
}
}
static Tegra::Texture::TextureFormat TextureFormatFromPixelFormat(PixelFormat format) {
// TODO(Subv): Properly implement this
switch (format) {
case PixelFormat::ABGR8:
case PixelFormat::SRGBA8:
return Tegra::Texture::TextureFormat::A8R8G8B8;
case PixelFormat::B5G6R5:
return Tegra::Texture::TextureFormat::B5G6R5;
case PixelFormat::A2B10G10R10:
return Tegra::Texture::TextureFormat::A2B10G10R10;
case PixelFormat::A1B5G5R5:
return Tegra::Texture::TextureFormat::A1B5G5R5;
case PixelFormat::R8:
return Tegra::Texture::TextureFormat::R8;
case PixelFormat::G8R8:
return Tegra::Texture::TextureFormat::G8R8;
case PixelFormat::RGBA16F:
return Tegra::Texture::TextureFormat::R16_G16_B16_A16;
case PixelFormat::R11FG11FB10F:
return Tegra::Texture::TextureFormat::BF10GF11RF11;
case PixelFormat::RGBA32UI:
return Tegra::Texture::TextureFormat::R32_G32_B32_A32;
case PixelFormat::DXT1:
return Tegra::Texture::TextureFormat::DXT1;
case PixelFormat::DXT23:
return Tegra::Texture::TextureFormat::DXT23;
case PixelFormat::DXT45:
return Tegra::Texture::TextureFormat::DXT45;
case PixelFormat::DXN1:
return Tegra::Texture::TextureFormat::DXN1;
case PixelFormat::DXN2UNORM:
case PixelFormat::DXN2SNORM:
return Tegra::Texture::TextureFormat::DXN2;
case PixelFormat::BC7U:
return Tegra::Texture::TextureFormat::BC7U;
case PixelFormat::ASTC_2D_4X4:
return Tegra::Texture::TextureFormat::ASTC_2D_4X4;
case PixelFormat::BGRA8:
// TODO(bunnei): This is fine for unswizzling (since we just need the right component
// sizes), but could be a bug if we used this function in different ways.
return Tegra::Texture::TextureFormat::A8R8G8B8;
case PixelFormat::RGBA32F:
return Tegra::Texture::TextureFormat::R32_G32_B32_A32;
case PixelFormat::RGB32F:
return Tegra::Texture::TextureFormat::R32_G32_B32;
case PixelFormat::RG32F:
return Tegra::Texture::TextureFormat::R32_G32;
case PixelFormat::R32F:
return Tegra::Texture::TextureFormat::R32;
case PixelFormat::R16F:
case PixelFormat::R16UNORM:
return Tegra::Texture::TextureFormat::R16;
case PixelFormat::Z32F:
return Tegra::Texture::TextureFormat::ZF32;
case PixelFormat::Z24S8:
return Tegra::Texture::TextureFormat::Z24S8;
case PixelFormat::RG16F:
case PixelFormat::RG16:
case PixelFormat::RG16UI:
case PixelFormat::RG16I:
case PixelFormat::RG16S:
return Tegra::Texture::TextureFormat::R16_G16;
default:
LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
UNREACHABLE();
}
}
static Tegra::DepthFormat DepthFormatFromPixelFormat(PixelFormat format) {
switch (format) {
case PixelFormat::S8Z24:
return Tegra::DepthFormat::S8_Z24_UNORM;
case PixelFormat::Z24S8:
return Tegra::DepthFormat::Z24_S8_UNORM;
case PixelFormat::Z32F:
return Tegra::DepthFormat::Z32_FLOAT;
case PixelFormat::Z16:
return Tegra::DepthFormat::Z16_UNORM;
case PixelFormat::Z32FS8:
return Tegra::DepthFormat::Z32_S8_X24_FLOAT;
default:
LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
UNREACHABLE();
}
}
static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) {
// TODO(Subv): Implement more component types
switch (type) {
@@ -634,8 +548,7 @@ public:
Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config);
/// Get the color and depth surfaces based on the framebuffer configuration
SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb,
const MathUtil::Rectangle<s32>& viewport);
SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb);
/// Flushes the surface to Switch memory
void FlushSurface(const Surface& surface);

View File

@@ -45,6 +45,9 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) {
case Maxwell::VertexAttribute::Type::SignedNorm: {
switch (attrib.size) {
case Maxwell::VertexAttribute::Size::Size_32_32_32:
return GL_INT;
case Maxwell::VertexAttribute::Size::Size_8_8:
case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
return GL_BYTE;
case Maxwell::VertexAttribute::Size::Size_16_16:

View File

@@ -86,88 +86,11 @@ u32 BytesPerPixel(TextureFormat format) {
}
}
static u32 DepthBytesPerPixel(DepthFormat format) {
switch (format) {
case DepthFormat::Z16_UNORM:
return 2;
case DepthFormat::S8_Z24_UNORM:
case DepthFormat::Z24_S8_UNORM:
case DepthFormat::Z32_FLOAT:
return 4;
case DepthFormat::Z32_S8_X24_FLOAT:
return 8;
default:
UNIMPLEMENTED_MSG("Format not implemented");
break;
}
}
std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height,
u32 block_height) {
u8* data = Memory::GetPointer(address);
u32 bytes_per_pixel = BytesPerPixel(format);
std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width,
u32 height, u32 block_height) {
std::vector<u8> unswizzled_data(width * height * bytes_per_pixel);
switch (format) {
case TextureFormat::DXT1:
case TextureFormat::DXT23:
case TextureFormat::DXT45:
case TextureFormat::DXN1:
case TextureFormat::DXN2:
case TextureFormat::BC7U:
// In the DXT and DXN formats, each 4x4 tile is swizzled instead of just individual pixel
// values.
CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data,
unswizzled_data.data(), true, block_height);
break;
case TextureFormat::A8R8G8B8:
case TextureFormat::A2B10G10R10:
case TextureFormat::A1B5G5R5:
case TextureFormat::B5G6R5:
case TextureFormat::R8:
case TextureFormat::G8R8:
case TextureFormat::R16_G16_B16_A16:
case TextureFormat::R32_G32_B32_A32:
case TextureFormat::R32_G32:
case TextureFormat::R32:
case TextureFormat::R16:
case TextureFormat::R16_G16:
case TextureFormat::BF10GF11RF11:
case TextureFormat::ASTC_2D_4X4:
case TextureFormat::R32_G32_B32:
CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
unswizzled_data.data(), true, block_height);
break;
default:
UNIMPLEMENTED_MSG("Format not implemented");
break;
}
return unswizzled_data;
}
std::vector<u8> UnswizzleDepthTexture(VAddr address, DepthFormat format, u32 width, u32 height,
u32 block_height) {
u8* data = Memory::GetPointer(address);
u32 bytes_per_pixel = DepthBytesPerPixel(format);
std::vector<u8> unswizzled_data(width * height * bytes_per_pixel);
switch (format) {
case DepthFormat::Z16_UNORM:
case DepthFormat::S8_Z24_UNORM:
case DepthFormat::Z24_S8_UNORM:
case DepthFormat::Z32_FLOAT:
case DepthFormat::Z32_S8_X24_FLOAT:
CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
unswizzled_data.data(), true, block_height);
break;
default:
UNIMPLEMENTED_MSG("Format not implemented");
break;
}
CopySwizzledData(width / tile_size, height / tile_size, bytes_per_pixel, bytes_per_pixel,
Memory::GetPointer(address), unswizzled_data.data(), true, block_height);
return unswizzled_data;
}

View File

@@ -13,8 +13,8 @@ namespace Tegra::Texture {
/**
* Unswizzles a swizzled texture without changing its format.
*/
std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height,
u32 block_height = TICEntry::DefaultBlockHeight);
std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width,
u32 height, u32 block_height = TICEntry::DefaultBlockHeight);
/**
* Unswizzles a swizzled depth texture without changing its format.

View File

@@ -383,8 +383,10 @@ void GraphicsSurfaceWidget::OnUpdate() {
QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32);
boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address);
auto unswizzled_data =
Tegra::Texture::UnswizzleTexture(*address, surface_format, surface_width, surface_height);
// TODO(bunnei): Will not work with BCn formats that swizzle 4x4 tiles.
// Needs to be fixed if we plan to use this feature more, otherwise we may remove it.
auto unswizzled_data = Tegra::Texture::UnswizzleTexture(
*address, 1, Tegra::Texture::BytesPerPixel(surface_format), surface_width, surface_height);
auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format,
surface_width, surface_height);

View File

@@ -4,6 +4,7 @@
#pragma once
#include <array>
#include <atomic>
#include <utility>
#include <QImage>
@@ -39,7 +40,6 @@ public:
* If this class receives valid SMDH data, it will also display game icons and titles.
*/
class GameListItemPath : public GameListItem {
public:
static const int FullPathRole = Qt::UserRole + 1;
static const int TitleRole = Qt::UserRole + 2;
@@ -48,18 +48,18 @@ public:
GameListItemPath() = default;
GameListItemPath(const QString& game_path, const std::vector<u8>& picture_data,
const QString& game_name, const QString& game_type, u64 program_id)
: GameListItem() {
const QString& game_name, const QString& game_type, u64 program_id) {
setData(game_path, FullPathRole);
setData(game_name, TitleRole);
setData(qulonglong(program_id), ProgramIdRole);
setData(game_type, FileTypeRole);
QPixmap picture;
u32 size = UISettings::values.icon_size;
if (!picture.loadFromData(picture_data.data(), picture_data.size()))
picture = GetDefaultIcon(size);
const u32 size = UISettings::values.icon_size;
QPixmap picture;
if (!picture.loadFromData(picture_data.data(), static_cast<u32>(picture_data.size()))) {
picture = GetDefaultIcon(size);
}
picture = picture.scaled(size, size);
setData(picture, Qt::DecorationRole);
@@ -70,17 +70,16 @@ public:
std::string filename;
Common::SplitPath(data(FullPathRole).toString().toStdString(), nullptr, &filename,
nullptr);
QString title = data(TitleRole).toString();
std::vector<QString> row_data{
const std::array<QString, 4> row_data{{
QString::fromStdString(filename),
data(FileTypeRole).toString(),
QString::fromStdString(fmt::format("0x{:016X}", data(ProgramIdRole).toULongLong())),
data(TitleRole).toString(),
};
}};
auto row1 = row_data.at(UISettings::values.row_1_text_id);
auto row2 = row_data.at(UISettings::values.row_2_text_id);
const auto& row1 = row_data.at(UISettings::values.row_1_text_id);
const auto& row2 = row_data.at(UISettings::values.row_2_text_id);
if (row1.isEmpty() || row1 == row2)
return row2;
@@ -88,9 +87,9 @@ public:
return row1;
return row1 + "\n " + row2;
} else {
return GameListItem::data(role);
}
return GameListItem::data(role);
}
};