Merge pull request #17097 from hrydgard/d3d9-dds

Texture Replacement: Support compressed textures in D3D9 as well
This commit is contained in:
Henrik Rydgård 2023-03-12 18:44:24 +01:00 committed by GitHub
commit 9eb0e49765
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 259 additions and 114 deletions

View File

@ -113,7 +113,7 @@ static const D3DSTENCILOP stencilOpToD3D9[] = {
D3DSTENCILOP_DECR,
};
D3DFORMAT FormatToD3DFMT(DataFormat fmt) {
static D3DFORMAT FormatToD3DFMT(DataFormat fmt) {
switch (fmt) {
case DataFormat::R16_UNORM: return D3DFMT_L16; // closest match, should be a fine substitution if we ignore channels except R.
case DataFormat::R8G8B8A8_UNORM: return D3DFMT_A8R8G8B8;
@ -1592,6 +1592,7 @@ uint32_t D3D9Context::GetDataFormatSupport(DataFormat fmt) const {
case DataFormat::BC1_RGBA_UNORM_BLOCK:
case DataFormat::BC2_UNORM_BLOCK:
case DataFormat::BC3_UNORM_BLOCK:
// DXT1, DXT3, DXT5.
return FMT_TEXTURE;
default:
return 0;

View File

@ -105,6 +105,18 @@ bool Thin3DFormatToGLFormatAndType(DataFormat fmt, GLuint &internalFormat, GLuin
type = GL_FLOAT;
alignment = 16;
break;
case DataFormat::BC4_UNORM_BLOCK:
internalFormat = GL_COMPRESSED_RED_RGTC1;
format = GL_R;
type = GL_FLOAT;
alignment = 16;
break;
case DataFormat::BC5_UNORM_BLOCK:
internalFormat = GL_COMPRESSED_RG_RGTC2;
format = GL_RG;
type = GL_FLOAT;
alignment = 16;
break;
case DataFormat::BC7_UNORM_BLOCK:
internalFormat = GL_COMPRESSED_RGBA_BPTC_UNORM;
format = GL_RGBA;

View File

@ -182,7 +182,9 @@ bool CheckGLExtensions() {
gl_extensions.gpuVendor = GPU_VENDOR_IMGTEC;
} else if (vendor == "Qualcomm") {
gl_extensions.gpuVendor = GPU_VENDOR_QUALCOMM;
sscanf(renderer, "Adreno (TM) %d", &gl_extensions.modelNumber);
if (1 != sscanf(renderer, "Adreno (TM) %d", &gl_extensions.modelNumber)) {
gl_extensions.modelNumber = 300; // or what should we default to?
}
} else if (vendor == "Broadcom") {
gl_extensions.gpuVendor = GPU_VENDOR_BROADCOM;
// Just for reference: Galaxy Y has renderer == "VideoCore IV HW"
@ -378,6 +380,12 @@ bool CheckGLExtensions() {
gl_extensions.ARB_explicit_attrib_location = g_set_gl_extensions.count("GL_ARB_explicit_attrib_location") != 0;
gl_extensions.ARB_texture_non_power_of_two = g_set_gl_extensions.count("GL_ARB_texture_non_power_of_two") != 0;
gl_extensions.ARB_shader_stencil_export = g_set_gl_extensions.count("GL_ARB_shader_stencil_export") != 0;
gl_extensions.ARB_texture_compression_bptc = g_set_gl_extensions.count("GL_ARB_texture_compression_bptc") != 0;
gl_extensions.ARB_texture_compression_rgtc = g_set_gl_extensions.count("GL_ARB_texture_compression_rgtc") != 0;
gl_extensions.KHR_texture_compression_astc_ldr = g_set_gl_extensions.count("GL_KHR_texture_compression_astc_ldr") != 0;
gl_extensions.EXT_texture_compression_s3tc = g_set_gl_extensions.count("GL_EXT_texture_compression_s3tc") != 0;
gl_extensions.OES_texture_compression_astc = g_set_gl_extensions.count("GL_OES_texture_compression_astc") != 0;
if (gl_extensions.IsGLES) {
gl_extensions.EXT_blend_func_extended = g_set_gl_extensions.count("GL_EXT_blend_func_extended") != 0;
gl_extensions.OES_texture_npot = g_set_gl_extensions.count("GL_OES_texture_npot") != 0;
@ -575,6 +583,40 @@ bool CheckGLExtensions() {
gl_extensions.EXT_clip_cull_distance = false;
}
// Check the old query API. It doesn't seem to be very reliable (can miss stuff).
GLint numCompressedFormats = 0;
glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numCompressedFormats);
GLint *compressedFormats = new GLint[numCompressedFormats];
if (numCompressedFormats > 0) {
glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, compressedFormats);
for (int i = 0; i < numCompressedFormats; i++) {
switch (compressedFormats[i]) {
case GL_COMPRESSED_RGB8_ETC2: gl_extensions.supportsETC2 = true; break;
case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: gl_extensions.supportsASTC = true; break;
#if !PPSSPP_PLATFORM(IOS) && !PPSSPP_PLATFORM(MAC)
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: gl_extensions.supportsBC123 = true; break;
#endif
#if PPSSPP_PLATFORM(WINDOWS)
case GL_COMPRESSED_RGBA_BPTC_UNORM: gl_extensions.supportsBC7 = true; break;
#endif
}
}
}
// Enable additional formats based on extensions.
if (gl_extensions.EXT_texture_compression_s3tc) gl_extensions.supportsBC123 = true;
if (gl_extensions.ARB_texture_compression_bptc) gl_extensions.supportsBC7 = true;
if (gl_extensions.ARB_texture_compression_rgtc) gl_extensions.supportsBC45 = true;
if (gl_extensions.KHR_texture_compression_astc_ldr) gl_extensions.supportsASTC = true;
if (gl_extensions.OES_texture_compression_astc) gl_extensions.supportsASTC = true;
// Now, disable known-emulated texture formats.
if (gl_extensions.gpuVendor == GPU_VENDOR_NVIDIA && !gl_extensions.IsGLES) {
gl_extensions.supportsETC2 = false;
gl_extensions.supportsASTC = false;
}
delete[] compressedFormats;
ProcessGPUFeatures();
int error = glGetError();

View File

@ -52,6 +52,7 @@ struct GLExtensions {
bool OES_copy_image;
bool OES_texture_float;
bool OES_texture_3D;
bool OES_texture_compression_astc;
// ARB
bool ARB_framebuffer_object;
@ -73,8 +74,14 @@ struct GLExtensions {
bool ARB_texture_non_power_of_two;
bool ARB_stencil_texturing;
bool ARB_shader_stencil_export;
bool ARB_texture_compression_bptc;
bool ARB_texture_compression_rgtc;
// KHR
bool KHR_texture_compression_astc_ldr;
// EXT
bool EXT_texture_compression_s3tc;
bool EXT_swap_control_tear;
bool EXT_discard_framebuffer;
bool EXT_unpack_subimage; // always supported on desktop and ES3
@ -115,6 +122,12 @@ struct GLExtensions {
int maxVertexTextureUnits;
bool supportsETC2;
bool supportsBC123;
bool supportsBC45;
bool supportsBC7;
bool supportsASTC;
// greater-or-equal than
bool VersionGEThan(int major, int minor, int sub = 0);
int GLSLVersion();

View File

@ -1556,7 +1556,23 @@ uint32_t OpenGLContext::GetDataFormatSupport(DataFormat fmt) const {
case DataFormat::BC1_RGBA_UNORM_BLOCK:
case DataFormat::BC2_UNORM_BLOCK:
case DataFormat::BC3_UNORM_BLOCK:
return FMT_TEXTURE;
return gl_extensions.supportsBC123 ? FMT_TEXTURE : 0;
case DataFormat::BC4_UNORM_BLOCK:
case DataFormat::BC5_UNORM_BLOCK:
return gl_extensions.supportsBC45 ? FMT_TEXTURE : 0;
case DataFormat::BC7_UNORM_BLOCK:
return gl_extensions.supportsBC7 ? FMT_TEXTURE : 0;
case DataFormat::ASTC_4x4_UNORM_BLOCK:
return gl_extensions.supportsASTC ? FMT_TEXTURE : 0;
case DataFormat::ETC2_R8G8B8_UNORM_BLOCK:
case DataFormat::ETC2_R8G8B8A1_UNORM_BLOCK:
case DataFormat::ETC2_R8G8B8A8_UNORM_BLOCK:
return gl_extensions.supportsETC2 ? FMT_TEXTURE : 0;
default:
return 0;
}

View File

@ -84,6 +84,36 @@ private:
LimitedWaitable *waitable_;
};
ReplacedTexture::~ReplacedTexture() {
if (threadWaitable_) {
SetState(ReplacementState::CANCEL_INIT);
std::unique_lock<std::mutex> lock(mutex_);
threadWaitable_->WaitAndRelease();
threadWaitable_ = nullptr;
}
for (auto &level : levels_) {
vfs_->ReleaseFile(level.fileRef);
level.fileRef = nullptr;
}
}
void ReplacedTexture::PurgeIfOlder(double t) {
if (threadWaitable_ && !threadWaitable_->WaitFor(0.0))
return;
if (lastUsed_ >= t)
return;
if (levelData_->lastUsed < t) {
// We have to lock since multiple textures might reference this same data.
std::lock_guard<std::mutex> guard(levelData_->lock);
levelData_->data.clear();
// This means we have to reload. If we never purge any, there's no need.
SetState(ReplacementState::POPULATED);
}
}
// This can only return true if ACTIVE or NOT_FOUND.
bool ReplacedTexture::IsReady(double budget) {
_assert_(vfs_ != nullptr);
@ -166,27 +196,18 @@ void ReplacedTexture::Prepare(VFSBackend *vfs) {
break;
}
const Path filename = desc_->basePath / desc_->filenames[i];
VFSFileReference *fileRef = vfs_->GetFile(desc_->filenames[i].c_str());
if (!fileRef) {
// If the file doesn't exist, let's just bail immediately here.
break;
}
// TODO: Here, if we find a file with multiple built-in mipmap levels,
// we'll have to change a bit how things work...
ReplacedTextureLevel level;
level.file = filename;
if (i == 0) {
fmt = Draw::DataFormat::R8G8B8A8_UNORM;
}
level.fileRef = fileRef;
Draw::DataFormat pixelFormat;
if (LoadLevelData(level, i, &pixelFormat)) {
if (LoadLevelData(fileRef, desc_->filenames[i], i, &pixelFormat)) {
if (i == 0) {
fmt = pixelFormat;
} else {
@ -195,7 +216,6 @@ void ReplacedTexture::Prepare(VFSBackend *vfs) {
break;
}
}
levels_.push_back(level);
} else {
// Otherwise, we're done loading mips (bad PNG or bad size, either way.)
break;
@ -223,7 +243,11 @@ inline uint32_t RoundUpTo4(uint32_t value) {
return (value + 3) & ~3;
}
bool ReplacedTexture::LoadLevelData(ReplacedTextureLevel &level, int mipLevel, Draw::DataFormat *pixelFormat) {
// Returns true if Prepare should keep calling this to load more levels.
bool ReplacedTexture::LoadLevelData(VFSFileReference *fileRef, const std::string &filename, int mipLevel, Draw::DataFormat *pixelFormat) {
ReplacedTextureLevel level;
level.fileRef = fileRef;
bool good = false;
if (levelData_->data.size() <= mipLevel) {
@ -262,14 +286,22 @@ bool ReplacedTexture::LoadLevelData(ReplacedTextureLevel &level, int mipLevel, D
switch (format) {
case 98: // DXGI_FORMAT_BC7_UNORM:
case 99: // DXGI_FORMAT_BC7_UNORM_SRGB:
if (!desc_->formatSupport.bc7) {
WARN_LOG(G3D, "BC1-3 formats not supported, skipping texture");
good = false;
}
ddsBytesToRead = RoundUpTo4(header.dwWidth) * RoundUpTo4(header.dwHeight); // 1 byte per pixel so this should be right.
*pixelFormat = Draw::DataFormat::BC7_UNORM_BLOCK;
break;
default:
ERROR_LOG(G3D, "DXGI pixel format %d not supported.", header10.dxgiFormat);
WARN_LOG(G3D, "DXGI pixel format %d not supported.", header10.dxgiFormat);
good = false;
}
} else {
if (!desc_->formatSupport.bc123) {
WARN_LOG(G3D, "BC1-3 formats not supported");
good = false;
}
ddsBytesToRead = header.dwPitchOrLinearSize;
format = header.ddspf.dwFourCC;
// OK, there are a number of possible formats we might have ended up with. We choose just a few
@ -297,6 +329,10 @@ bool ReplacedTexture::LoadLevelData(ReplacedTextureLevel &level, int mipLevel, D
level.w = header.dwWidth;
level.h = header.dwHeight;
numMips = header.dwMipMapCount;
if (numMips > 1) {
WARN_LOG(G3D, "DDS file contains more than one mip level. Ignoring for now.");
}
} else if (imageType == ReplacedImageType::ZIM) {
uint32_t ignore = 0;
struct ZimHeader {
@ -318,16 +354,12 @@ bool ReplacedTexture::LoadLevelData(ReplacedTextureLevel &level, int mipLevel, D
level.h = headerPeek.Height();
good = true;
} else {
ERROR_LOG(G3D, "Could not get PNG dimensions: %s (zip)", level.file.ToVisualString().c_str());
ERROR_LOG(G3D, "Could not get PNG dimensions: %s (zip)", filename.c_str());
good = false;
}
*pixelFormat = Draw::DataFormat::R8G8B8A8_UNORM;
} else {
ERROR_LOG(G3D, "Could not load texture replacement info: %s - unsupported format %s", level.file.ToVisualString().c_str(), magic.c_str());
}
if (numMips > 1) {
WARN_LOG(G3D, "File contains more than one mip level. Ignoring for now.");
ERROR_LOG(G3D, "Could not load texture replacement info: %s - unsupported format %s", filename.c_str(), magic.c_str());
}
// Already populated from cache. TODO: Move this above the first read, and take level.w/h from the cache.
@ -370,7 +402,7 @@ bool ReplacedTexture::LoadLevelData(ReplacedTextureLevel &level, int mipLevel, D
out.resize(ddsBytesToRead);
size_t read_bytes = vfs_->Read(openFile, &out[0], ddsBytesToRead);
if (read_bytes != ddsBytesToRead) {
WARN_LOG(G3D, "DDS: Expected %d bytes, got %d", ddsBytesToRead, read_bytes);
WARN_LOG(G3D, "DDS: Expected %d bytes, got %d", ddsBytesToRead, (int)read_bytes);
}
} else if (imageType == ReplacedImageType::ZIM) {
std::unique_ptr<uint8_t[]> zim(new uint8_t[fileSize]);
@ -382,7 +414,7 @@ bool ReplacedTexture::LoadLevelData(ReplacedTextureLevel &level, int mipLevel, D
}
if (vfs_->Read(openFile, &zim[0], fileSize) != fileSize) {
ERROR_LOG(G3D, "Could not load texture replacement: %s - failed to read ZIM", level.file.c_str());
ERROR_LOG(G3D, "Could not load texture replacement: %s - failed to read ZIM", filename.c_str());
SetState(ReplacementState::NOT_FOUND);
cleanup();
return false;
@ -392,7 +424,7 @@ bool ReplacedTexture::LoadLevelData(ReplacedTextureLevel &level, int mipLevel, D
uint8_t *image;
if (LoadZIMPtr(&zim[0], fileSize, &w, &h, &f, &image)) {
if (w > level.w || h > level.h) {
ERROR_LOG(G3D, "Texture replacement changed since header read: %s", level.file.c_str());
ERROR_LOG(G3D, "Texture replacement changed since header read: %s", filename.c_str());
SetState(ReplacementState::NOT_FOUND);
cleanup();
return false;
@ -421,13 +453,13 @@ bool ReplacedTexture::LoadLevelData(ReplacedTextureLevel &level, int mipLevel, D
pngdata.resize(fileSize);
pngdata.resize(vfs_->Read(openFile, &pngdata[0], fileSize));
if (!png_image_begin_read_from_memory(&png, &pngdata[0], pngdata.size())) {
ERROR_LOG(G3D, "Could not load texture replacement info: %s - %s (zip)", level.file.c_str(), png.message);
ERROR_LOG(G3D, "Could not load texture replacement info: %s - %s (zip)", filename.c_str(), png.message);
SetState(ReplacementState::NOT_FOUND);
cleanup();
return false;
}
if (png.width > (uint32_t)level.w || png.height > (uint32_t)level.h) {
ERROR_LOG(G3D, "Texture replacement changed since header read: %s", level.file.c_str());
ERROR_LOG(G3D, "Texture replacement changed since header read: %s", filename.c_str());
SetState(ReplacementState::NOT_FOUND);
cleanup();
return false;
@ -445,7 +477,7 @@ bool ReplacedTexture::LoadLevelData(ReplacedTextureLevel &level, int mipLevel, D
out.resize(level.w * level.h * 4);
if (!png_image_finish_read(&png, nullptr, &out[0], level.w * 4, nullptr)) {
ERROR_LOG(G3D, "Could not load texture replacement: %s - %s", level.file.c_str(), png.message);
ERROR_LOG(G3D, "Could not load texture replacement: %s - %s", filename.c_str(), png.message);
SetState(ReplacementState::NOT_FOUND);
cleanup();
out.resize(0);
@ -465,39 +497,12 @@ bool ReplacedTexture::LoadLevelData(ReplacedTextureLevel &level, int mipLevel, D
}
cleanup();
levels_.push_back(level);
return true;
}
void ReplacedTexture::PurgeIfOlder(double t) {
if (threadWaitable_ && !threadWaitable_->WaitFor(0.0))
return;
if (lastUsed_ >= t)
return;
if (levelData_->lastUsed < t) {
// We have to lock since multiple textures might reference this same data.
std::lock_guard<std::mutex> guard(levelData_->lock);
levelData_->data.clear();
// This means we have to reload. If we never purge any, there's no need.
SetState(ReplacementState::POPULATED);
}
}
ReplacedTexture::~ReplacedTexture() {
if (threadWaitable_) {
SetState(ReplacementState::CANCEL_INIT);
std::unique_lock<std::mutex> lock(mutex_);
threadWaitable_->WaitAndRelease();
threadWaitable_ = nullptr;
}
for (auto &level : levels_) {
vfs_->ReleaseFile(level.fileRef);
level.fileRef = nullptr;
}
}
bool ReplacedTexture::CopyLevelTo(int level, void *out, int rowPitch) {
_assert_msg_((size_t)level < levels_.size(), "Invalid miplevel");
_assert_msg_(out != nullptr && rowPitch > 0, "Invalid out/pitch");

View File

@ -54,7 +54,6 @@ static const int MAX_REPLACEMENT_MIP_LEVELS = 12; // 12 should be plenty, 8 is
struct ReplacedTextureLevel {
int w = 0;
int h = 0;
Path file;
// To be able to reload, we need to be able to reopen, unfortunate we can't use zip_file_t.
// TODO: This really belongs on the level in the cache, not in the individual ReplacedTextureLevel objects.
@ -72,6 +71,13 @@ enum class ReplacementState : uint32_t {
const char *StateString(ReplacementState state);
struct GPUFormatSupport {
bool bc123;
bool astc;
bool bc7;
bool etc2;
};
struct ReplacementDesc {
int newW;
int newH;
@ -85,6 +91,7 @@ struct ReplacementDesc {
std::vector<std::string> filenames;
std::string logId;
ReplacedLevelsCache *cache;
GPUFormatSupport formatSupport;
};
struct ReplacedLevelsCache {
@ -145,7 +152,7 @@ struct ReplacedTexture {
private:
void Prepare(VFSBackend *vfs);
bool LoadLevelData(ReplacedTextureLevel &info, int level, Draw::DataFormat *pixelFormat);
bool LoadLevelData(VFSFileReference *fileRef, const std::string &filename, int level, Draw::DataFormat *pixelFormat);
void PurgeIfOlder(double t);
std::vector<ReplacedTextureLevel> levels_;

View File

@ -55,7 +55,11 @@ static const int VERSION = 1;
static const double MAX_CACHE_SIZE = 4.0;
TextureReplacer::TextureReplacer(Draw::DrawContext *draw) {
// TODO: Check draw for supported texture formats.
// We don't want to keep the draw object around, so extract the info we need.
if (draw->GetDataFormatSupport(Draw::DataFormat::BC3_UNORM_BLOCK)) formatSupport_.bc123 = true;
if (draw->GetDataFormatSupport(Draw::DataFormat::ASTC_4x4_UNORM_BLOCK)) formatSupport_.astc = true;
if (draw->GetDataFormatSupport(Draw::DataFormat::BC7_UNORM_BLOCK)) formatSupport_.bc7 = true;
if (draw->GetDataFormatSupport(Draw::DataFormat::ETC2_R8G8B8_UNORM_BLOCK)) formatSupport_.etc2 = true;
}
TextureReplacer::~TextureReplacer() {
@ -487,6 +491,7 @@ void TextureReplacer::PopulateReplacement(ReplacedTexture *texture, u64 cachekey
desc->cachekey = cachekey;
desc->hash = hash;
desc->basePath = basePath_;
desc->formatSupport = formatSupport_;
LookupHashRange(cachekey >> 32, desc->newW, desc->newH);
if (ignoreAddress_) {

View File

@ -93,7 +93,7 @@ enum class ReplacerDecimateMode {
class TextureReplacer {
public:
// The draw context will be checked for supported texture formats.
// The draw context is checked for supported texture formats.
TextureReplacer(Draw::DrawContext *draw);
~TextureReplacer();
@ -152,6 +152,7 @@ protected:
VFSBackend *vfs_ = nullptr;
bool vfsIsZip_ = false;
GPUFormatSupport formatSupport_{};
typedef std::pair<int, int> WidthHeightPair;
std::unordered_map<u64, WidthHeightPair> hashranges_;

View File

@ -58,17 +58,11 @@ static const D3D11_INPUT_ELEMENT_DESC g_QuadVertexElements[] = {
static Draw::DataFormat FromD3D11Format(u32 fmt) {
switch (fmt) {
case DXGI_FORMAT_B4G4R4A4_UNORM:
return Draw::DataFormat::A4R4G4B4_UNORM_PACK16;
case DXGI_FORMAT_B5G5R5A1_UNORM:
return Draw::DataFormat::A1R5G5B5_UNORM_PACK16;
case DXGI_FORMAT_B5G6R5_UNORM:
return Draw::DataFormat::R5G6B5_UNORM_PACK16;
case DXGI_FORMAT_R8_UNORM:
return Draw::DataFormat::R8_UNORM;
case DXGI_FORMAT_B8G8R8A8_UNORM:
default:
return Draw::DataFormat::R8G8B8A8_UNORM;
case DXGI_FORMAT_B4G4R4A4_UNORM: return Draw::DataFormat::A4R4G4B4_UNORM_PACK16;
case DXGI_FORMAT_B5G5R5A1_UNORM: return Draw::DataFormat::A1R5G5B5_UNORM_PACK16;
case DXGI_FORMAT_B5G6R5_UNORM: return Draw::DataFormat::R5G6B5_UNORM_PACK16;
case DXGI_FORMAT_R8_UNORM: return Draw::DataFormat::R8_UNORM;
case DXGI_FORMAT_B8G8R8A8_UNORM: default: return Draw::DataFormat::R8G8B8A8_UNORM;
}
}
@ -281,14 +275,6 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
ID3D11Resource *texture = DxTex(entry);
_assert_(texture == nullptr);
int tw;
int th;
plan.GetMipSize(0, &tw, &th);
if (tw > 16384)
tw = 16384;
if (th > 16384)
th = 16384;
// The PSP only supports 8 mip levels, but we support 12 in the texture replacer (4k textures down to 1).
D3D11_SUBRESOURCE_DATA subresData[12]{};
@ -355,6 +341,14 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
LoadTextureLevel(*entry, data, stride, plan, srcLevel, texFmt, TexDecodeFlags{});
}
int tw;
int th;
plan.GetMipSize(0, &tw, &th);
if (tw > 16384)
tw = 16384;
if (th > 16384)
th = 16384;
if (plan.depth == 1) {
// We don't yet have mip generation, so clamp the number of levels to the ones we can load directly.
levels = std::min(plan.levelsToCreate, plan.levelsToLoad);

View File

@ -40,23 +40,21 @@
Draw::DataFormat FromD3D9Format(u32 fmt) {
switch (fmt) {
case D3DFMT_A4R4G4B4:
return Draw::DataFormat::B4G4R4A4_UNORM_PACK16;
case D3DFMT_A1R5G5B5:
return Draw::DataFormat::A1R5G5B5_UNORM_PACK16;
case D3DFMT_R5G6B5:
return Draw::DataFormat::R5G6B5_UNORM_PACK16;
case D3DFMT_A8:
return Draw::DataFormat::R8_UNORM;
case D3DFMT_A8R8G8B8:
default:
return Draw::DataFormat::R8G8B8A8_UNORM;
case D3DFMT_A4R4G4B4: return Draw::DataFormat::B4G4R4A4_UNORM_PACK16;
case D3DFMT_A1R5G5B5: return Draw::DataFormat::A1R5G5B5_UNORM_PACK16;
case D3DFMT_R5G6B5: return Draw::DataFormat::R5G6B5_UNORM_PACK16;
case D3DFMT_A8: return Draw::DataFormat::R8_UNORM;
case D3DFMT_A8R8G8B8: default: return Draw::DataFormat::R8G8B8A8_UNORM;
}
}
D3DFORMAT ToD3D9Format(Draw::DataFormat fmt) {
switch (fmt) {
case Draw::DataFormat::R8G8B8A8_UNORM: default: return D3DFMT_A8R8G8B8;
case Draw::DataFormat::BC1_RGBA_UNORM_BLOCK: return D3DFMT_DXT1;
case Draw::DataFormat::BC2_UNORM_BLOCK: return D3DFMT_DXT3;
case Draw::DataFormat::BC3_UNORM_BLOCK: return D3DFMT_DXT5;
case Draw::DataFormat::R8G8B8A8_UNORM: return D3DFMT_A8R8G8B8;
default: _dbg_assert_(false); return D3DFMT_A8R8G8B8;
}
}

View File

@ -76,9 +76,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.139"
version = "0.2.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
[[package]]
name = "proc-macro-error"
@ -106,9 +106,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.50"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
dependencies = [
"unicode-ident",
]
@ -154,9 +154,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.107"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
@ -174,9 +174,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.6"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
[[package]]
name = "unicode-segmentation"

View File

@ -5,4 +5,4 @@ name = "langtool"
version = "0.1.0"
[dependencies]
structopt = "0.3"
structopt = "0.3.26"

View File

@ -100,7 +100,7 @@ fn move_key(target_ini: &mut IniFile, old: &str, new: &str, key: &str) -> io::Re
fn remove_key(target_ini: &mut IniFile, section: &str, key: &str) -> io::Result<()> {
if let Some(old_section) = target_ini.get_section_mut(section) {
let _ = old_section.remove_line(key);
old_section.remove_line(key);
} else {
println!("No section {}", section);
}
@ -109,7 +109,7 @@ fn remove_key(target_ini: &mut IniFile, section: &str, key: &str) -> io::Result<
fn add_new_key(target_ini: &mut IniFile, section: &str, key: &str) -> io::Result<()> {
if let Some(section) = target_ini.get_section_mut(section) {
let _ = section.insert_line_if_missing(&format!("{} = {}", key, key));
section.insert_line_if_missing(&format!("{} = {}", key, key));
} else {
println!("No section {}", section);
}
@ -118,7 +118,7 @@ fn add_new_key(target_ini: &mut IniFile, section: &str, key: &str) -> io::Result
fn rename_key(target_ini: &mut IniFile, section: &str, old: &str, new: &str) -> io::Result<()> {
if let Some(section) = target_ini.get_section_mut(section) {
let _ = section.rename_key(old, new);
section.rename_key(old, new);
} else {
println!("No section {}", section);
}
@ -178,13 +178,13 @@ fn main() {
match opt.cmd {
Command::CopyMissingLines {} => {
copy_missing_lines(&reference_ini, &mut target_ini).unwrap();
copy_missing_lines(reference_ini, &mut target_ini).unwrap();
}
Command::CommentUnknownLines {} => {
deal_with_unknown_lines(&reference_ini, &mut target_ini, false).unwrap();
deal_with_unknown_lines(reference_ini, &mut target_ini, false).unwrap();
}
Command::RemoveUnknownLines {} => {
deal_with_unknown_lines(&reference_ini, &mut target_ini, true).unwrap();
deal_with_unknown_lines(reference_ini, &mut target_ini, true).unwrap();
}
Command::SortSection { ref section } => sort_section(&mut target_ini, section).unwrap(),
Command::RenameKey {

View File

@ -20,7 +20,7 @@ impl Section {
continue;
};
if prefix.eq_ignore_ascii_case(&key) {
if prefix.eq_ignore_ascii_case(key) {
remove_index = Some(index);
break;
}
@ -140,11 +140,9 @@ impl Section {
if prefix.starts_with("Font") || prefix.starts_with('#') {
return true;
}
if !other.lines.iter().any(|line| line.starts_with(prefix)) {
false
} else {
true
}
// keeps the line if this expression returns true.
other.lines.iter().any(|line| line.starts_with(prefix))
});
}
}

View File

@ -554,6 +554,16 @@ void SystemInfoScreen::CreateViews() {
}
}
deviceSpecs->Add(new InfoItem(si->T("Depth buffer format"), DataFormatToString(draw->GetDeviceCaps().preferredDepthBufferFormat)));
std::string texCompressionFormats;
// Simple non-detailed summary of supported tex compression formats.
if (draw->GetDataFormatSupport(Draw::DataFormat::ETC2_R8G8B8_UNORM_BLOCK)) texCompressionFormats += "ETC2 ";
if (draw->GetDataFormatSupport(Draw::DataFormat::ASTC_4x4_UNORM_BLOCK)) texCompressionFormats += "ASTC ";
if (draw->GetDataFormatSupport(Draw::DataFormat::BC1_RGBA_UNORM_BLOCK)) texCompressionFormats += "BC1-3 ";
if (draw->GetDataFormatSupport(Draw::DataFormat::BC4_UNORM_BLOCK)) texCompressionFormats += "BC4-5 ";
if (draw->GetDataFormatSupport(Draw::DataFormat::BC7_UNORM_BLOCK)) texCompressionFormats += "BC7 ";
deviceSpecs->Add(new InfoItem(si->T("Compressed texture formats"), texCompressionFormats));
deviceSpecs->Add(new ItemHeader(si->T("OS Information")));
deviceSpecs->Add(new InfoItem(si->T("Memory Page Size"), StringFromFormat(si->T("%d bytes"), GetMemoryProtectPageSize())));
deviceSpecs->Add(new InfoItem(si->T("RW/RX exclusive"), PlatformIsWXExclusive() ? di->T("Active") : di->T("Inactive")));

View File

@ -1042,6 +1042,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Erstellungskonfig.
Build Configuration = Erstellungskonfiguration
Built by = Erstellt von
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Kerne
CPU Extensions = CPU Erweiterungen

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1051,6 +1051,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1035,6 +1035,7 @@ Board = Placa
Build Config = Info. de la compilación
Build Configuration = Info. de la compilación
Built by = Compilado por
Compressed texture formats = Compressed texture formats
Core Context = Contexto de núcleo
Cores = Núcleos
CPU Extensions = Extensiones CPU

View File

@ -1034,6 +1034,7 @@ Board = Placa
Build Config = Info. de la compilación
Build Configuration = Info. de la compilación
Built by = Compilado por
Compressed texture formats = Compressed texture formats
Core Context = Contexto de núcleo
Cores = Núcleos
CPU Extensions = Extensiones de CPU

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1025,6 +1025,7 @@ Board = Carte
Build Config = Config de compilation
Build Configuration = Configuration de compilation
Built by = Compilé par
Compressed texture formats = Compressed texture formats
Core Context = Contexte de cœur
Cores = Coeurs
CPU Extensions = Extensions CPU

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Πυρήνες
CPU Extensions = Επεκτάσεις CPU

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Ploča
Build Config = Konfig građe
Build Configuration = Konfiguracija građe
Built by = Građeno od
Compressed texture formats = Compressed texture formats
Core Context = Kontekst jezgre
Cores = Jezgre
CPU Extensions = CPU nastavci

View File

@ -1034,6 +1034,7 @@ Board = Alaplap
Build Config = Build konfig
Build Configuration = Build konfiguráció
Built by = Buildelte:
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Magok
CPU Extensions = CPU kiterjesztések

View File

@ -1034,6 +1034,7 @@ Board = Papan
Build Config = Konfigurasi pembuatan
Build Configuration = Konfigurasi pembuatan
Built by = Dibuat oleh
Compressed texture formats = Compressed texture formats
Core Context = Konteks inti
Cores = Inti
CPU Extensions = Ekstensi CPU

View File

@ -1035,6 +1035,7 @@ Board = Scheda
Build Config = Config della build
Build Configuration = Configurazione della build
Built by = Compilato da
Compressed texture formats = Compressed texture formats
Core Context = Contesto del core
Cores = Core
CPU Extensions = Estensioni della CPU

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = ビルド設定
Build Configuration = ビルド設定
Built by = ビルド作成者
Compressed texture formats = Compressed texture formats
Core Context = コアコンテキスト
Cores = コア数
CPU Extensions = CPU拡張

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1027,6 +1027,7 @@ Board = 보드
Build Config = 빌드 구성
Build Configuration = 빌드 구성
Built by = 빌더
Compressed texture formats = Compressed texture formats
Core Context = 코어 컨텍스트
Cores = 코어
CPU Extensions = CPU 확장

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Bouw
Build Configuration = Bouwconfiguratie
Built by = Gebouwd door
Compressed texture formats = Compressed texture formats
Core Context = Corecontext
Cores = Cores
CPU Extensions = CPU-extensies

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Płyta główna
Build Config = Konfiguracja wersji
Build Configuration = Konfiguracja Wersji
Built by = Zbudowane przez
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Rdzenie
CPU Extensions = Rozszerzenia CPU

View File

@ -1051,6 +1051,7 @@ Board = Placa
Build Config = Configuração do build
Build Configuration = Configuração do build
Built by = Compilado por
Compressed texture formats = Compressed texture formats
Core Context = Contexto do núcleo
Cores = Núcleos
CPU Extensions = Extensões da CPU

View File

@ -1051,6 +1051,7 @@ Board = Placa
Build Config = Definições da build
Build Configuration = Definições da build
Built by = Compilado por
Compressed texture formats = Compressed texture formats
Core Context = Contexto do núcleo
Cores = Núcleos
CPU Extensions = Extensões da CPU

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Плата
Build Config = Конфиг сборки
Build Configuration = Конфигурация сборки
Built by = Собрано
Compressed texture formats = Compressed texture formats
Core Context = Контекст ядра
Cores = Ядра
CPU Extensions = Расширения ЦП

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1034,6 +1034,7 @@ Board = Board
Build Config = Build config
Build Configuration = Build Configuration
Built by = Built by
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Cores
CPU Extensions = CPU extensions

View File

@ -1038,6 +1038,7 @@ Board = ชื่อบอร์ด
Build Config = การกำหนดค่า
Build Configuration = การกำหนดค่าที่ถูกสร้างไว้
Built by = สร้างโดย
Compressed texture formats = Compressed texture formats
Core Context = บริบทของแกน
Cores = จำนวนแกน
CPU Extensions = ส่วนขยายซีพียู

View File

@ -1035,6 +1035,7 @@ Board = Board
Build Config = Yapı konfigürasyonu
Build Configuration = Yapı konfigürasyonu
Built by = Tarafından yapıldı
Compressed texture formats = Compressed texture formats
Core Context = Core context
Cores = Çekirdekler
CPU Extensions = CPU uzantıları

View File

@ -1034,6 +1034,7 @@ Board = Плата
Build Config = Конфіг збірки
Build Configuration = Конфігурація збірки
Built by = Побудував
Compressed texture formats = Compressed texture formats
Core Context = Контекст ядра
Cores = Ядра
CPU Extensions = Розширення CPU

View File

@ -1034,6 +1034,7 @@ Board = Bảng
Build Config = Xây dựng
Build Configuration = Xây dựng cấu hình
Built by = Xây dựng bởi
Compressed texture formats = Compressed texture formats
Core Context = Bối cảnh cốt lõi
Cores = Cốt lõi
CPU Extensions = tiện ích CPU

View File

@ -1028,6 +1028,7 @@ Board = 主板
Build Config = 编译配置
Build Configuration = 编译配置
Built by = 编译者
Compressed texture formats = Compressed texture formats
Core Context = 核心上下文
Cores = 核心数
CPU Extensions = CPU 扩展

View File

@ -1027,6 +1027,7 @@ Board = 主機板
Build Config = 組建組態
Build Configuration = 組建組態
Built by = 建置者
Compressed texture formats = Compressed texture formats
Core Context = 核心內容
Cores = 核心數
CPU Extensions = CPU 擴充