mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-02-04 02:51:18 +01:00
fix etc2/bc7
This commit is contained in:
@@ -482,8 +482,10 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
|
||||
{Settings::EnumMetadata<Settings::AstcRecompression>::Index(),
|
||||
{
|
||||
PAIR(AstcRecompression, Uncompressed, tr("Uncompressed (Best quality)")),
|
||||
PAIR(AstcRecompression, Bc1, tr("BC1 (Low quality)")),
|
||||
PAIR(AstcRecompression, Bc3, tr("BC3 (Medium quality)")),
|
||||
PAIR(AstcRecompression, Bc1, tr("BC1")),
|
||||
PAIR(AstcRecompression, Bc3, tr("BC3")),
|
||||
PAIR(AstcRecompression, Bc7, tr("BC7")),
|
||||
PAIR(AstcRecompression, Etc2, tr("ETC2")),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::VramUsageMode>::Index(),
|
||||
{
|
||||
|
||||
@@ -437,8 +437,7 @@ void DecodeIntegerSequence(uint max_range, uint num_values) {
|
||||
EncodingData val = EncodingData(encoding_values[max_range]);
|
||||
const uint encoding = Encoding(val);
|
||||
const uint num_bits = NumBits(val);
|
||||
uint vals_decoded = 0;
|
||||
while (vals_decoded < num_values && !result_limit_reached) {
|
||||
for (uint vals_decoded = 0; vals_decoded < num_values && !result_limit_reached; ) {
|
||||
switch (encoding) {
|
||||
case QUINT:
|
||||
DecodeQuintBlock(num_bits);
|
||||
@@ -571,10 +570,8 @@ void DecodeColorValues(uvec4 modes, uint num_partitions, uint color_data_bits, o
|
||||
|
||||
ivec2 BitTransferSigned(int a, int b) {
|
||||
ivec2 transferred;
|
||||
transferred.y = b >> 1;
|
||||
transferred.y |= a & 0x80;
|
||||
transferred.x = a >> 1;
|
||||
transferred.x &= 0x3F;
|
||||
transferred.x = (a >> 1) & 0x3F;
|
||||
transferred.y = (b >> 1) | (a & 0x80);
|
||||
if ((transferred.x & 0x20) > 0) {
|
||||
transferred.x -= 0x40;
|
||||
}
|
||||
@@ -831,38 +828,6 @@ uvec4 GetUnquantizedWeightVector(uint t, uint s, uvec2 size, uint plane_index, b
|
||||
return weight_vec;
|
||||
}
|
||||
|
||||
int FindLayout(uint mode) {
|
||||
if ((mode & 3) != 0) {
|
||||
if ((mode & 8) != 0) {
|
||||
if ((mode & 4) != 0) {
|
||||
if ((mode & 0x100) != 0) {
|
||||
return 4;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
if ((mode & 4) != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if ((mode & 0x100) != 0) {
|
||||
if ((mode & 0x80) != 0) {
|
||||
if ((mode & 0x20) != 0) {
|
||||
return 8;
|
||||
}
|
||||
return 7;
|
||||
}
|
||||
return 9;
|
||||
}
|
||||
if ((mode & 0x80) != 0) {
|
||||
return 6;
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
||||
void FillError(ivec3 coord) {
|
||||
for (uint j = 0; j < block_dims.y; j++) {
|
||||
for (uint i = 0; i < block_dims.x; i++) {
|
||||
@@ -908,9 +873,40 @@ bool IsError(uint mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uvec2 DecodeBlockSize(uint mode) {
|
||||
int FindLayout(uint mode) {
|
||||
if ((mode & 3) != 0) {
|
||||
if ((mode & 8) != 0) {
|
||||
if ((mode & 4) != 0) {
|
||||
if ((mode & 0x100) != 0) {
|
||||
return 4;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
if ((mode & 4) != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if ((mode & 0x100) != 0) {
|
||||
if ((mode & 0x80) != 0) {
|
||||
if ((mode & 0x20) != 0) {
|
||||
return 8;
|
||||
}
|
||||
return 7;
|
||||
}
|
||||
return 9;
|
||||
}
|
||||
if ((mode & 0x80) != 0) {
|
||||
return 6;
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
|
||||
uvec2 DecodeBlockSize(uint layout, uint mode) {
|
||||
uint A, B;
|
||||
switch (FindLayout(mode)) {
|
||||
switch (layout) {
|
||||
case 0:
|
||||
A = (mode >> 5) & 0x3;
|
||||
B = (mode >> 7) & 0x3;
|
||||
@@ -967,6 +963,11 @@ uint DecodeMaxWeight(uint mode) {
|
||||
|
||||
void DecompressBlock(ivec3 coord) {
|
||||
uint mode = StreamBits(11);
|
||||
const uint num_partitions = StreamBits(2) + 1;
|
||||
const uint mode_layout = FindLayout(mode);
|
||||
const bool dual_plane = (mode_layout != 9) && ((mode & 0x400) != 0);
|
||||
const uvec2 size_params = DecodeBlockSize(mode_layout, mode);
|
||||
|
||||
if (IsError(mode)) {
|
||||
FillError(coord);
|
||||
return;
|
||||
@@ -976,15 +977,8 @@ void DecompressBlock(ivec3 coord) {
|
||||
FillVoidExtentLDR(coord);
|
||||
return;
|
||||
}
|
||||
const uvec2 size_params = DecodeBlockSize(mode);
|
||||
if ((size_params.x > block_dims.x) || (size_params.y > block_dims.y)) {
|
||||
FillError(coord);
|
||||
return;
|
||||
}
|
||||
const uint num_partitions = StreamBits(2) + 1;
|
||||
const uint mode_layout = FindLayout(mode);
|
||||
const bool dual_plane = (mode_layout != 9) && ((mode & 0x400) != 0);
|
||||
if (num_partitions > 4 || (num_partitions == 4 && dual_plane)) {
|
||||
if (((size_params.x > block_dims.x) || (size_params.y > block_dims.y))
|
||||
|| (num_partitions > 4 || (num_partitions == 4 && dual_plane))) {
|
||||
FillError(coord);
|
||||
return;
|
||||
}
|
||||
@@ -1002,25 +996,10 @@ void DecompressBlock(ivec3 coord) {
|
||||
const uint base_mode = base_cem & 3;
|
||||
const uint max_weight = DecodeMaxWeight(mode);
|
||||
const uint weight_bits = GetPackedBitSize(size_params, dual_plane, max_weight);
|
||||
uint remaining_bits = 128 - weight_bits - total_bitsread;
|
||||
uint extra_cem_bits = 0;
|
||||
if (base_mode > 0) {
|
||||
switch (num_partitions) {
|
||||
case 2:
|
||||
extra_cem_bits += 2;
|
||||
break;
|
||||
case 3:
|
||||
extra_cem_bits += 5;
|
||||
break;
|
||||
case 4:
|
||||
extra_cem_bits += 8;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
remaining_bits -= extra_cem_bits;
|
||||
const uint extra_cem_bits = base_mode > 0 ? ((0x85200 >> (num_partitions * 4)) & 0x0f) : 0;
|
||||
const uint plane_selector_bits = dual_plane ? 2 : 0;
|
||||
const uint remaining_bits = 128 - weight_bits - total_bitsread;
|
||||
remaining_bits -= extra_cem_bits;
|
||||
remaining_bits -= plane_selector_bits;
|
||||
if (remaining_bits > 128) {
|
||||
// Bad data, more remaining bits than 4 bytes
|
||||
|
||||
@@ -538,16 +538,16 @@ ASTCDecoderPass::ASTCDecoderPass(const Device& device_, Scheduler& scheduler_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_,
|
||||
MemoryAllocator& memory_allocator_)
|
||||
: ComputePass(device_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS,
|
||||
ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO,
|
||||
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(AstcPushConstants)>, ASTC_DECODER_COMP_SPV),
|
||||
scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_},
|
||||
compute_pass_descriptor_queue{compute_pass_descriptor_queue_}, memory_allocator{
|
||||
memory_allocator_} {}
|
||||
ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO,
|
||||
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(AstcPushConstants)>, ASTC_DECODER_COMP_SPV)
|
||||
, scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}
|
||||
, compute_pass_descriptor_queue{compute_pass_descriptor_queue_}, memory_allocator{memory_allocator_}
|
||||
{}
|
||||
|
||||
ASTCDecoderPass::~ASTCDecoderPass() = default;
|
||||
|
||||
void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map,
|
||||
std::span<const VideoCommon::SwizzleParameters> swizzles) {
|
||||
void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, std::span<const VideoCommon::SwizzleParameters> swizzles) {
|
||||
ASSERT(image.info.size.depth == 1);
|
||||
using namespace VideoCommon::Accelerated;
|
||||
const std::array<u32, 2> block_dims{
|
||||
VideoCore::Surface::DefaultBlockWidth(image.info.format),
|
||||
|
||||
@@ -2437,16 +2437,13 @@ void TextureCacheRuntime::AccelerateImageUpload(
|
||||
if (IsPixelFormatASTC(image.info.format)) {
|
||||
return astc_decoder_pass->Assemble(image, map, swizzles);
|
||||
}
|
||||
|
||||
if (bl3d_unswizzle_pass &&
|
||||
IsPixelFormatBCn(image.info.format) &&
|
||||
image.info.type == ImageType::e3D &&
|
||||
image.info.resources.levels == 1 &&
|
||||
image.info.resources.layers == 1) {
|
||||
|
||||
return bl3d_unswizzle_pass->Unswizzle(image, map, swizzles, z_start, z_count);
|
||||
}
|
||||
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user