Skip to content

Commit 1ebb33f

Browse files
committed
Validate texture replacement size before loading
Fixes TwilitRealm/dusklight#1226
1 parent 2d64481 commit 1ebb33f

3 files changed

Lines changed: 37 additions & 5 deletions

File tree

lib/gfx/texture.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct TextureFormatInfo {
3030
};
3131
TextureFormatInfo format_info(wgpu::TextureFormat format) noexcept;
3232
uint64_t calc_texture_size(wgpu::TextureFormat format, uint32_t width, uint32_t height, uint32_t mips) noexcept;
33+
bool is_block_aligned(wgpu::TextureFormat format, uint32_t width, uint32_t height) noexcept;
3334

3435
constexpr u32 InvalidTextureFormat = -1;
3536
struct TextureRef {

lib/gfx/texture_format.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,13 @@ uint64_t calc_texture_size(wgpu::TextureFormat format, u32 width, u32 height, u3
9090
}
9191
return total;
9292
}
93+
94+
bool is_block_aligned(wgpu::TextureFormat format, uint32_t width, uint32_t height) noexcept {
95+
if (width == 0 || height == 0) {
96+
return false;
97+
}
98+
99+
const auto info = format_info(format);
100+
return !info.compressed || (width % info.blockWidth == 0 && height % info.blockHeight == 0);
101+
}
93102
} // namespace aurora::gfx

lib/gfx/texture_replacement.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,20 @@ constexpr bool is_unsupported_texture_format(wgpu::TextureFormat format) {
469469
}
470470
}
471471

472+
bool validate_texture_size(wgpu::TextureFormat format, uint32_t width, uint32_t height,
473+
std::string_view label) noexcept {
474+
if (aurora::gfx::is_block_aligned(format, width, height)) {
475+
return true;
476+
}
477+
478+
const auto info = aurora::gfx::format_info(format);
479+
Log.warn(
480+
"texture_replacement: failed to load texture {} because {}x{} is not aligned to {}x{} texel blocks for "
481+
"format {}",
482+
label, width, height, info.blockWidth, info.blockHeight, static_cast<uint32_t>(format));
483+
return false;
484+
}
485+
472486
std::optional<aurora::gfx::ConvertedTexture> load_file_replacement(const ReplacementEntry& entry) noexcept {
473487
auto base = load_texture_file(entry.path);
474488
if (!base.has_value()) {
@@ -480,6 +494,9 @@ std::optional<aurora::gfx::ConvertedTexture> load_file_replacement(const Replace
480494
fs_path_to_string(entry.path), static_cast<uint32_t>(base->format));
481495
return std::nullopt;
482496
}
497+
if (!validate_texture_size(base->format, base->width, base->height, fs_path_to_string(entry.path))) {
498+
return std::nullopt;
499+
}
483500

484501
if (base->mips > 1) {
485502
return base;
@@ -598,16 +615,21 @@ aurora::gfx::TextureHandle create_raw_texture_handle(const ReplacementEntry& ent
598615
return {};
599616
}
600617

618+
const auto label = entry.label.empty() ? fmt::format("{}", entry.id) : entry.label;
601619
const auto format = aurora::gfx::to_wgpu(entry.gxFormat);
602620
if (is_unsupported_texture_format(format)) {
603-
Log.warn("texture_replacement: failed to load raw replacement {} due to unsupported format: {}",
604-
entry.label.empty() ? fmt::format("{}", entry.id) : entry.label, static_cast<uint32_t>(format));
621+
Log.warn("texture_replacement: failed to load raw replacement {} due to unsupported format: {}", label,
622+
static_cast<uint32_t>(format));
623+
return {};
624+
}
625+
if (!validate_texture_size(format, entry.width, entry.height, label)) {
605626
return {};
606627
}
607628

608-
const auto label = entry.label.empty() ? fmt::format("TextureReplacement {}", entry.id) : entry.label;
609-
auto handle = aurora::gfx::new_static_texture_2d(entry.width, entry.height, entry.mipCount, entry.gxFormat,
610-
{entry.bytes.data(), entry.bytes.size()}, false, label.c_str());
629+
const auto textureLabel = entry.label.empty() ? fmt::format("TextureReplacement {}", entry.id) : entry.label;
630+
auto handle =
631+
aurora::gfx::new_static_texture_2d(entry.width, entry.height, entry.mipCount, entry.gxFormat,
632+
{entry.bytes.data(), entry.bytes.size()}, false, textureLabel.c_str());
611633
if (handle) {
612634
handle->isReplacement = true;
613635
}

0 commit comments

Comments
 (0)