Various changes to how color blocks are passed

faster-single-tables
Andrew Cassidy 3 years ago
parent a3cc69db64
commit 77cc6a8132

@ -34,6 +34,8 @@ target_compile_features(test_rgbcx PUBLIC cxx_std_20 c_std_11)
set_project_warnings(python_rgbcx)
set_project_warnings(test_rgbcx)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -lc++abi")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -fsanitize=undefined")

@ -24,9 +24,9 @@
#include <array>
#include "../BlockView.h"
#include "../Color.h"
#include "../ColorBlock.h"
#include "../interpolator.h"
#include "../Interpolator.h"
#include "../ndebug.h"
#include "BC1Block.h"
@ -44,9 +44,9 @@ void BC1Decoder::DecodeBlock(Color4x4 dest, BC1Block *const block) const noexcep
assert(selector < 4);
assert((color.a == 0 && selector == 3 && l <= h) || color.a == UINT8_MAX);
if (_write_alpha) {
dest[y][x].SetRGBA(color);
dest.get(x, y).SetRGBA(color);
} else {
dest[y][x].SetRGB(color);
dest.get(x, y).SetRGB(color);
}
}
}

@ -22,8 +22,8 @@
#include <memory>
#include "../BlockDecoder.h"
#include "../ColorBlock.h"
#include "../interpolator.h"
#include "../BlockView.h"
#include "../Interpolator.h"
#include "../ndebug.h"
#include "BC1Block.h"

@ -21,7 +21,7 @@
#include "../BC1/BC1Decoder.h"
#include "../BC4/BC4Decoder.h"
#include "../ColorBlock.h"
#include "../BlockView.h"
#include "../ndebug.h"
namespace rgbcx {

@ -24,8 +24,8 @@
#include "../BC1/BC1Decoder.h"
#include "../BC4/BC4Decoder.h"
#include "../BlockDecoder.h"
#include "../ColorBlock.h"
#include "../interpolator.h"
#include "../BlockView.h"
#include "../Interpolator.h"
#include "../ndebug.h"
#include "BC3Block.h"

@ -23,12 +23,12 @@
#include <array> // for array
#include "../Color.h" // for Color
#include "../ColorBlock.h" // for ColorBlock
#include "../ndebug.h" // for ndebug
#include "../BlockView.h" // for ColorBlock
#include "../Color.h" // for Color
#include "../ndebug.h" // for ndebug
#include "BC4Block.h"
void rgbcx::BC4Decoder::DecodeBlock(Color4x4 dest, BC4Block *const block, size_t channel) const noexcept(ndebug) {
void rgbcx::BC4Decoder::DecodeBlock(Byte4x4 dest, BC4Block *const block) const noexcept(ndebug) {
auto l = block->GetLowAlpha();
auto h = block->GetHighAlpha();
@ -39,7 +39,7 @@ void rgbcx::BC4Decoder::DecodeBlock(Color4x4 dest, BC4Block *const block, size_t
for (unsigned x = 0; x < 4; x++) {
const auto selector = selectors[y][x];
assert(selector < 8);
dest[y][x][channel] = values[selector];
dest.set(x, y, values[selector]);
}
}
}

@ -22,21 +22,23 @@
#include <stddef.h>
#include "../BlockDecoder.h"
#include "../ColorBlock.h"
#include "../BlockView.h"
#include "../ndebug.h"
#include "BC4Block.h"
namespace rgbcx {
class BC4Decoder : public BlockDecoder<BC4Block, 4, 4> {
public:
BC4Decoder(size_t channel = 3) : _channel(channel) {}
using Byte4x4 = BlockView<uint8_t, 4, 4>;
BC4Decoder(uint8_t channel = 3) : _channel(channel) { assert(channel < 4U); }
void DecodeBlock(Color4x4 dest, BC4Block *const block) const noexcept(ndebug) override { DecodeBlock(dest, block, _channel); }
void DecodeBlock(Color4x4 dest, BC4Block *const block, size_t channel) const noexcept(ndebug);
void DecodeBlock(Color4x4 dest, BC4Block *const block) const noexcept(ndebug) override { DecodeBlock(dest.GetChannel(_channel), block); }
void DecodeBlock(Color4x4 dest, BC4Block *const block, uint8_t channel) const noexcept(ndebug) { DecodeBlock(dest.GetChannel(channel), block); }
void DecodeBlock(Byte4x4 dest, BC4Block *const block) const noexcept(ndebug);
constexpr size_t GetChannel() const { return _channel; }
constexpr uint8_t GetChannel() const { return _channel; }
private:
const size_t _channel;
const uint8_t _channel;
};
} // namespace rgbcx

@ -0,0 +1,22 @@
/* Python-rgbcx Texture Compression Library
Copyright (C) 2021 Andrew Cassidy <drewcassidy@me.com>
Partially derived from rgbcx.h written by Richard Geldreich <richgel99@gmail.com>
and licenced under the public domain
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "BC4Encoder.h"
namespace rgbcx {} // namespace rgbcx

@ -0,0 +1,25 @@
/* Python-rgbcx Texture Compression Library
Copyright (C) 2021 Andrew Cassidy <drewcassidy@me.com>
Partially derived from rgbcx.h written by Richard Geldreich <richgel99@gmail.com>
and licenced under the public domain
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
namespace rgbcx {
class BC4Encoder {};
} // namespace rgbcx

@ -20,7 +20,7 @@
#include "BC5Decoder.h"
#include "../BC4/BC4Decoder.h"
#include "../ColorBlock.h"
#include "../BlockView.h"
#include "../ndebug.h"
namespace rgbcx {

@ -20,11 +20,12 @@
#pragma once
#include <stddef.h>
#include <memory>
#include "../BC4/BC4Decoder.h"
#include "../BlockDecoder.h"
#include "../ColorBlock.h"
#include "../BlockView.h"
#include "../ndebug.h"
#include "BC5Block.h"
@ -33,8 +34,12 @@ class BC5Decoder : public BlockDecoder<BC5Block, 4, 4> {
public:
using BC4DecoderPtr = std::shared_ptr<BC4Decoder>;
BC5Decoder(size_t chan0 = 0, size_t chan1 = 1) : BC5Decoder(std::make_shared<BC4Decoder>(), chan0, chan1) {}
BC5Decoder(BC4DecoderPtr bc4_decoder, size_t chan0 = 0, size_t chan1 = 1) : _bc4_decoder(bc4_decoder), _chan0(chan0), _chan1(chan1) {}
BC5Decoder(uint8_t chan0 = 0, uint8_t chan1 = 1) : BC5Decoder(std::make_shared<BC4Decoder>(), chan0, chan1) {}
BC5Decoder(BC4DecoderPtr bc4_decoder, uint8_t chan0 = 0, uint8_t chan1 = 1) : _bc4_decoder(bc4_decoder), _chan0(chan0), _chan1(chan1) {
assert(chan0 < 4U);
assert(chan1 < 4U);
assert(chan0 != chan1);
}
void DecodeBlock(Color4x4 dest, BC5Block *const block) const noexcept(ndebug) override;
@ -43,7 +48,7 @@ class BC5Decoder : public BlockDecoder<BC5Block, 4, 4> {
private:
const BC4DecoderPtr _bc4_decoder;
const size_t _chan0;
const size_t _chan1;
const uint8_t _chan0;
const uint8_t _chan1;
};
} // namespace rgbcx

@ -24,19 +24,20 @@
#include <span>
#include <vector>
#include "ColorBlock.h"
#include "util.h"
#include "BlockView.h"
#include "ndebug.h"
#include "util.h"
namespace rgbcx {
template <class B, size_t M, size_t N> class BlockDecoder {
public:
using DecodedBlock = ColorBlock<M, N>;
using DecodedBlock = ColorBlockView<M, N>;
using EncodedBlock = B;
BlockDecoder() noexcept = default;
virtual ~BlockDecoder() noexcept = default;
virtual void DecodeBlock(DecodedBlock dest, EncodedBlock *const block) const noexcept(ndebug) = 0;
void DecodeRow(std::span<DecodedBlock> dests, std::span<const EncodedBlock> blocks) {
@ -69,8 +70,9 @@ template <class B, size_t M, size_t N> class BlockDecoder {
auto rows = std::array<Row *, M>();
for (unsigned i = 0; i < M; i++) { rows[i] = reinterpret_cast<Row *>(&image[top_left + i * image_width]); }
// auto dest = DecodedBlock(image, image_width, image_height, x, y);
DecodeBlock(DecodedBlock(rows), &blocks[x + block_width * y]);
auto dest = DecodedBlock(&image[top_left],image_width);
DecodeBlock(dest, &blocks[x + block_width * y]);
}
}
}

@ -21,13 +21,13 @@
#include <cstdint>
#include "ColorBlock.h"
#include "BlockView.h"
namespace rgbcx {
template <class B, size_t M, size_t N> class BlockEncoder {
public:
using DecodedBlock = ColorBlock<M, N>;
using DecodedBlock = BlockView<M, N>;
using EncodedBlock = B;
virtual void EncodeBlock(EncodedBlock *dest, DecodedBlock *const pixels) const = 0;
};

@ -0,0 +1,118 @@
/* Python-rgbcx Texture Compression Library
Copyright (C) 2021 Andrew Cassidy <drewcassidy@me.com>
Partially derived from rgbcx.h written by Richard Geldreich <richgel99@gmail.com>
and licenced under the public domain
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <array>
#include <cassert>
#include <cstdint>
#include <cstdio>
#include <vector>
#include "Color.h"
#include "ndebug.h"
namespace rgbcx {
template <typename S, size_t N> class RowView {
public:
RowView(S *start, int pixel_stride = 1) : start(start), pixel_stride(pixel_stride) {}
constexpr S &operator[](size_t index) noexcept(ndebug) {
assert(index < N);
return start[index * pixel_stride];
}
constexpr const S &operator[](size_t index) const noexcept(ndebug) {
assert(index < N);
return start[index * pixel_stride];
}
constexpr int size() noexcept { return N; }
S *const start;
const int pixel_stride;
};
template <typename S, size_t M, size_t N> class BlockView {
public:
using Row = RowView<S, N>;
BlockView(S *start, int row_stride = N, int pixel_stride = 1) : start(start), row_stride(row_stride), pixel_stride(pixel_stride) {}
constexpr Row operator[](size_t index) noexcept(ndebug) {
assert(index < M);
return RowView<S, N>(&start[index * row_stride], pixel_stride);
}
constexpr int width() noexcept { return N; }
constexpr int height() noexcept { return M; }
constexpr int size() noexcept { return N * M; }
constexpr S &get(unsigned x, unsigned y) noexcept(ndebug) {
assert(x < N);
assert(y < M);
return start[(row_stride * y) + (pixel_stride * x)];
}
constexpr S get(unsigned x, unsigned y) const noexcept(ndebug) {
assert(x < N);
assert(y < M);
return start[(row_stride * y) + (pixel_stride * x)];
}
constexpr void set(unsigned x, unsigned y, S value) noexcept(ndebug) {
assert(x < N);
assert(y < M);
start[(row_stride * y) + (pixel_stride * x)] = value;
}
constexpr std::array<S, M * N> flatten() noexcept {
std::array<S, M * N> result;
for (unsigned x = 0; x < N; x++) {
for (unsigned y = 0; y < M; y++) { result[x + (N * y)] = start[(row_stride * y) + (pixel_stride * x)]; }
}
return result;
}
S *const start;
const int row_stride;
const int pixel_stride;
};
template <size_t M, size_t N> class ColorBlockView : public BlockView<Color, M, N> {
public:
using Base = BlockView<Color, M, N>;
using ChannelView = BlockView<uint8_t, M, N>;
ColorBlockView(Color *start, int row_stride = N, int pixel_stride = 1) : Base(start, row_stride, pixel_stride) {}
constexpr ChannelView GetChannel(uint8_t index) noexcept(ndebug) {
assert(index < 4U);
auto channelStart = reinterpret_cast<uint8_t *>(Base::start) + index;
return ChannelView(channelStart, Base::row_stride * 4, Base::pixel_stride * 4);
}
constexpr ChannelView GetR() noexcept(ndebug) { return GetChannel(0); };
constexpr ChannelView GetG() noexcept(ndebug) { return GetChannel(1); };
constexpr ChannelView GetB() noexcept(ndebug) { return GetChannel(2); };
constexpr ChannelView GetA() noexcept(ndebug) { return GetChannel(3); };
};
using Color4x4 = ColorBlockView<4, 4>;
} // namespace rgbcx

@ -1,57 +0,0 @@
/* Python-rgbcx Texture Compression Library
Copyright (C) 2021 Andrew Cassidy <drewcassidy@me.com>
Partially derived from rgbcx.h written by Richard Geldreich <richgel99@gmail.com>
and licenced under the public domain
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <array>
#include <cassert>
#include <cstdint>
#include <cstdio>
#include <vector>
#include "Color.h"
template <size_t N> class ColorRow {
public:
constexpr Color &operator[](size_t n) noexcept { return _colors[n]; }
constexpr const Color &operator[](size_t n) const noexcept { return _colors[n]; }
constexpr int size() noexcept { return N; }
private:
std::array<Color, 4> _colors;
};
template <size_t M, size_t N> class ColorBlock {
public:
using Row = ColorRow<N>;
constexpr Row &operator[](size_t n) noexcept { return *_rows[n]; }
constexpr const Row &operator[](size_t n) const noexcept { return *_rows[n]; }
constexpr int width() noexcept { return N; }
constexpr int height() noexcept { return M; }
constexpr int size() noexcept { return N * M; }
ColorBlock(const std::array<Row *, M> &Rows) : _rows(Rows) {}
private:
std::array<Row *, M> _rows;
};
using Color4x4 = ColorBlock<4, 4>;

@ -17,7 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "interpolator.h"
#include "Interpolator.h"
#include <array>
#include <cassert>

@ -59,7 +59,7 @@
#include "BC3/BC3Block.h"
#include "BC4/BC4Block.h"
#include "BC5/BC5Block.h"
#include "interpolator.h"
#include "Interpolator.h"
// By default, the table used to accelerate cluster fit on 4 color blocks uses a 969x128 entry table.
// To reduce the executable size, set RGBCX_USE_SMALLER_TABLES to 1, which selects the smaller 969x32 entry table.

@ -742,6 +742,8 @@ int main(int argc, char *argv[]) {
printf("Wrote DDS file %s\n", dds_output_filename.c_str());
if ((!no_output_png) && (png_output_filename.size())) {
clock_t start_decode_t = clock();
image_u8 unpacked_image(source_image.width(), source_image.height());
bool punchthrough_flag = false;
@ -801,6 +803,9 @@ int main(int argc, char *argv[]) {
// unpacked_image.set_block(bx, by, 4, 4, unpacked_pixels);
// } // bx
// } // by
clock_t end_decode_t = clock();
printf("\nDecode time: %f secs\n", (double)(end_decode_t - start_decode_t) / CLOCKS_PER_SEC);
if ((punchthrough_flag) && (dxgi_format == DXGI_FORMAT_BC3_UNORM))
fprintf(stderr, "Warning: BC3 mode selected, but rgbcx::unpack_bc3() returned one or more blocks using 3-color mode!\n");

Loading…
Cancel
Save