diff --git a/basisu_gpu_texture.cpp b/basisu_gpu_texture.cpp index fb9c392..117668c 100644 --- a/basisu_gpu_texture.cpp +++ b/basisu_gpu_texture.cpp @@ -1042,7 +1042,7 @@ namespace basisu return true; } - bool gpu_image::unpack(image& img, bool pvrtc_wrap_addressing) const + bool gpu_image::unpack(image& img) const { img.resize(get_pixel_width(), get_pixel_height()); img.set_all(g_black_color); @@ -1052,7 +1052,7 @@ namespace basisu if ((m_fmt == texture_format::cPVRTC1_4_RGB) || (m_fmt == texture_format::cPVRTC1_4_RGBA)) { - pvrtc4_image pi(m_width, m_height, pvrtc_wrap_addressing); + pvrtc4_image pi(m_width, m_height); if (get_total_blocks() != pi.get_total_blocks()) return false; diff --git a/basisu_gpu_texture.h b/basisu_gpu_texture.h index 26a507e..8a49757 100644 --- a/basisu_gpu_texture.h +++ b/basisu_gpu_texture.h @@ -101,7 +101,7 @@ namespace basisu m_blocks.resize(m_blocks_x * m_blocks_y * m_qwords_per_block); } - bool unpack(image& img, bool pvrtc_wrap_addressing = true) const; + bool unpack(image& img) const; void override_dimensions(uint32_t w, uint32_t h) { diff --git a/basisu_pvrtc1_4.cpp b/basisu_pvrtc1_4.cpp index 5a732b2..f0122fc 100644 --- a/basisu_pvrtc1_4.cpp +++ b/basisu_pvrtc1_4.cpp @@ -193,21 +193,12 @@ namespace basisu int block_x1 = block_x0 + 1; int block_y0 = (static_cast(y) - 2) >> 2; int block_y1 = block_y0 + 1; - if (m_wrap_addressing) - { - block_x0 = posmod(block_x0, m_block_width); - block_x1 = posmod(block_x1, m_block_width); - block_y0 = posmod(block_y0, m_block_height); - block_y1 = posmod(block_y1, m_block_height); - } - else - { - block_x0 = clamp(block_x0, 0, m_block_width - 1); - block_x1 = clamp(block_x1, 0, m_block_width - 1); - block_y0 = clamp(block_y0, 0, m_block_height - 1); - block_y1 = clamp(block_y1, 0, m_block_height - 1); - } - + + block_x0 = posmod(block_x0, m_block_width); + block_x1 = posmod(block_x1, m_block_width); + block_y0 = posmod(block_y0, m_block_height); + block_y1 = posmod(block_y1, m_block_height); + pColors[0] = interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0)); pColors[3] = interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1)); @@ -240,21 +231,12 @@ namespace basisu int block_x1 = block_x0 + 1; int block_y0 = (static_cast(y) - 2) >> 2; int block_y1 = block_y0 + 1; - if (m_wrap_addressing) - { - block_x0 = posmod(block_x0, m_block_width); - block_x1 = posmod(block_x1, m_block_width); - block_y0 = posmod(block_y0, m_block_height); - block_y1 = posmod(block_y1, m_block_height); - } - else - { - block_x0 = clamp(block_x0, 0, m_block_width - 1); - block_x1 = clamp(block_x1, 0, m_block_width - 1); - block_y0 = clamp(block_y0, 0, m_block_height - 1); - block_y1 = clamp(block_y1, 0, m_block_height - 1); - } - + + block_x0 = posmod(block_x0, m_block_width); + block_x1 = posmod(block_x1, m_block_width); + block_y0 = posmod(block_y0, m_block_height); + block_y1 = posmod(block_y1, m_block_height); + if (get_block_uses_transparent_modulation(x >> 2, y >> 2)) { if (m == 0) diff --git a/basisu_pvrtc1_4.h b/basisu_pvrtc1_4.h index 71c4fba..80b4413 100644 --- a/basisu_pvrtc1_4.h +++ b/basisu_pvrtc1_4.h @@ -168,15 +168,14 @@ namespace basisu { public: inline pvrtc4_image() : - m_width(0), m_height(0), m_block_width(0), m_block_height(0), m_wrap_addressing(false), m_uses_alpha(false) + m_width(0), m_height(0), m_block_width(0), m_block_height(0), m_uses_alpha(false) { } - inline pvrtc4_image(uint32_t width, uint32_t height, bool wrap_addressing = false) : - m_width(0), m_height(0), m_block_width(0), m_block_height(0), m_wrap_addressing(false), m_uses_alpha(false) + inline pvrtc4_image(uint32_t width, uint32_t height) : + m_width(0), m_height(0), m_block_width(0), m_block_height(0), m_uses_alpha(false) { resize(width, height); - set_wrap_addressing(wrap_addressing); } inline void clear() @@ -187,7 +186,6 @@ namespace basisu m_block_height = 0; m_blocks.clear(); m_uses_alpha = false; - m_wrap_addressing = false; } inline void resize(uint32_t width, uint32_t height) @@ -218,9 +216,6 @@ namespace basisu inline bool get_uses_alpha() const { return m_uses_alpha; } inline void set_uses_alpha(bool uses_alpha) { m_uses_alpha = uses_alpha; } - inline void set_wrap_addressing(bool wrapping) { m_wrap_addressing = wrapping; } - inline bool get_wrap_addressing() const { return m_wrap_addressing; } - inline bool are_blocks_equal(const pvrtc4_image& rhs) const { return m_blocks == rhs.m_blocks; @@ -298,24 +293,24 @@ namespace basisu dst(x, y) = get_pixel(block_x * 4 + x, block_y * 4 + y); } - inline int wrap_or_clamp_x(int x) const + inline int wrap_x(int x) const { - return m_wrap_addressing ? posmod(x, m_width) : clamp(x, 0, m_width - 1); + return posmod(x, m_width); } - inline int wrap_or_clamp_y(int y) const + inline int wrap_y(int y) const { - return m_wrap_addressing ? posmod(y, m_height) : clamp(y, 0, m_height - 1); + return posmod(y, m_height); } - inline int wrap_or_clamp_block_x(int bx) const + inline int wrap_block_x(int bx) const { - return m_wrap_addressing ? posmod(bx, m_block_width) : clamp(bx, 0, m_block_width - 1); + return posmod(bx, m_block_width); } - inline int wrap_or_clamp_block_y(int by) const + inline int wrap_block_y(int by) const { - return m_wrap_addressing ? posmod(by, m_block_height) : clamp(by, 0, m_block_height - 1); + return posmod(by, m_block_height); } inline vec2F get_interpolation_factors(uint32_t x, uint32_t y) const @@ -362,7 +357,6 @@ namespace basisu pvrtc4_block_vector2D m_blocks; uint32_t m_block_width, m_block_height; - bool m_wrap_addressing; bool m_uses_alpha; }; diff --git a/basisu_tool.cpp b/basisu_tool.cpp index f90f398..4003a01 100644 --- a/basisu_tool.cpp +++ b/basisu_tool.cpp @@ -88,7 +88,6 @@ static void print_usage() " -etc1_only: Only unpack to ETC1, skipping the other texture formats during -unpack\n" " -disable_hierarchical_endpoint_codebooks: Disable hierarchical endpoint codebook usage, slower but higher quality on some compression levels\n" " -compare_ssim: Compute and display SSIM of image comparison (slow)\n" - " -pvrtc_clamp: Use clamp addressing when transcoding and unpacking PVRTC1 textures\n" "\n" "Mipmap generation options:\n" " -mipmap: Generate mipmaps for each source image\n" @@ -228,8 +227,7 @@ public: m_no_ktx(false), m_etc1_only(false), m_fuzz_testing(false), - m_compare_ssim(false), - m_pvrtc_clamp(false) + m_compare_ssim(false) { } @@ -254,8 +252,6 @@ public: m_mode = cValidate; else if (strcasecmp(pArg, "-compare_ssim") == 0) m_compare_ssim = true; - else if (strcasecmp(pArg, "-pvrtc_clamp") == 0) - m_pvrtc_clamp = true; else if (strcasecmp(pArg, "-file") == 0) { REMAINING_ARGS_CHECK(1); @@ -584,7 +580,6 @@ public: bool m_etc1_only; bool m_fuzz_testing; bool m_compare_ssim; - bool m_pvrtc_clamp; }; static bool expand_multifile(command_line_params &opts) @@ -1016,7 +1011,7 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl // Fill the buffer with psuedo-random bytes, to help more visibly detect cases where the transcoder fails to write to part of the output. fill_buffer_with_random_bytes(gi.get_ptr(), gi.get_size_in_bytes()); - uint32_t decode_flags = (opts.m_pvrtc_clamp ? 0 : basist::basisu_transcoder::cDecodeFlagsPVRTCWrapAddressing); + uint32_t decode_flags = 0; tm.start(); @@ -1103,8 +1098,7 @@ static bool unpack_and_validate_mode(command_line_params &opts, bool validate_fl } image u; - const bool pvrtc_wrap_addressing = !opts.m_pvrtc_clamp; - if (!gi[level_index].unpack(u, pvrtc_wrap_addressing)) + if (!gi[level_index].unpack(u)) { printf("Warning: Failed unpacking GPU texture data (%u %u %u). Unpacking as much as possible.\n", format_iter, image_index, level_index); total_unpack_warnings++; diff --git a/transcoder/basisu_transcoder.cpp b/transcoder/basisu_transcoder.cpp index d7386d1..ddaf949 100644 --- a/transcoder/basisu_transcoder.cpp +++ b/transcoder/basisu_transcoder.cpp @@ -3402,7 +3402,7 @@ namespace basist } // TODO: Support decoding a non-pow2 ETC1S texture into the next larger pow2 PVRTC texture. - static void fixup_pvrtc1_4_modulation_rgb(const decoder_etc_block* pETC_Blocks, const uint32_t* pPVRTC_endpoints, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool pvrtc_wrap_addressing) + static void fixup_pvrtc1_4_modulation_rgb(const decoder_etc_block* pETC_Blocks, const uint32_t* pPVRTC_endpoints, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y) { const uint32_t x_mask = num_blocks_x - 1; const uint32_t y_mask = num_blocks_y - 1; @@ -3423,7 +3423,7 @@ namespace basist for (int ey = 0; ey < 3; ey++) { - int by = y + ey - 1; if (!pvrtc_wrap_addressing) by = basisu::clamp(by, 0, y_mask); + int by = y + ey - 1; const uint32_t* pE = &pPVRTC_endpoints[(by & y_mask) * num_blocks_x]; @@ -3431,7 +3431,7 @@ namespace basist for (int ex = 0; ex < 3; ex++) { - int bx = 0 + ex - 1; if (!pvrtc_wrap_addressing) bx = basisu::clamp(bx, 0, x_mask); + int bx = 0 + ex - 1; const uint32_t e = pE[bx & x_mask]; @@ -3477,8 +3477,6 @@ namespace basist { const uint32_t ex = 2; int bx = x + ex - 1; - if (!pvrtc_wrap_addressing) - bx = basisu::clamp(bx, 0, x_mask); bx &= x_mask; #define DO_ROW(ey) \ @@ -3584,7 +3582,7 @@ namespace basist static void fixup_pvrtc1_4_modulation_rgba( const decoder_etc_block* pETC_Blocks, const uint32_t* pPVRTC_endpoints, - void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool pvrtc_wrap_addressing, void *pAlpha_blocks, + void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, void *pAlpha_blocks, const endpoint* pEndpoints, const selector* pSelectors) { const uint32_t x_mask = num_blocks_x - 1; @@ -3606,7 +3604,7 @@ namespace basist for (int ey = 0; ey < 3; ey++) { - int by = y + ey - 1; if (!pvrtc_wrap_addressing) by = basisu::clamp(by, 0, y_mask); + int by = y + ey - 1; const uint32_t* pE = &pPVRTC_endpoints[(by & y_mask) * num_blocks_x]; @@ -3614,7 +3612,7 @@ namespace basist for (int ex = 0; ex < 3; ex++) { - int bx = 0 + ex - 1; if (!pvrtc_wrap_addressing) bx = basisu::clamp(bx, 0, x_mask); + int bx = 0 + ex - 1; const uint32_t e = pE[bx & x_mask]; @@ -3674,8 +3672,6 @@ namespace basist { const uint32_t ex = 2; int bx = x + ex - 1; - if (!pvrtc_wrap_addressing) - bx = basisu::clamp(bx, 0, x_mask); bx &= x_mask; #define DO_ROW(ey) \ @@ -8138,12 +8134,11 @@ namespace basist } bool basisu_lowlevel_transcoder::transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt, - uint32_t output_block_or_pixel_stride_in_bytes, bool pvrtc_wrap_addressing, bool bc1_allow_threecolor_blocks, const basis_file_header& header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels, + uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const basis_file_header& header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels, basisu_transcoder_state* pState, bool transcode_alpha, void *pAlpha_blocks, uint32_t output_rows_in_pixels) { (void)transcode_alpha; (void)pAlpha_blocks; - (void)pvrtc_wrap_addressing; if (!pState) pState = &m_def_state; @@ -8915,9 +8910,9 @@ namespace basist #if BASISD_SUPPORT_PVRTC1 // PVRTC post process - create per-pixel modulation values. if (fmt == block_format::cPVRTC1_4_RGB) - fixup_pvrtc1_4_modulation_rgb((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y, pvrtc_wrap_addressing); + fixup_pvrtc1_4_modulation_rgb((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y); else if (fmt == block_format::cPVRTC1_4_RGBA) - fixup_pvrtc1_4_modulation_rgba((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y, pvrtc_wrap_addressing, pAlpha_blocks, &m_endpoints[0], &m_selectors[0]); + fixup_pvrtc1_4_modulation_rgba((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y, pAlpha_blocks, &m_endpoints[0], &m_selectors[0]); #endif // BASISD_SUPPORT_PVRTC1 if (pPVRTC_work_mem) @@ -9535,7 +9530,7 @@ namespace basist return m_lowlevel_decoder.transcode_slice(pOutput_blocks, slice_desc.m_num_blocks_x, slice_desc.m_num_blocks_y, pDataU8 + slice_desc.m_file_ofs, slice_desc.m_file_size, - fmt, output_block_or_pixel_stride_in_bytes, (decode_flags & cDecodeFlagsPVRTCWrapAddressing) != 0, (decode_flags & cDecodeFlagsBC1ForbidThreeColorBlocks) == 0, *pHeader, slice_desc, output_row_pitch_in_blocks_or_pixels, pState, + fmt, output_block_or_pixel_stride_in_bytes, (decode_flags & cDecodeFlagsBC1ForbidThreeColorBlocks) == 0, *pHeader, slice_desc, output_row_pitch_in_blocks_or_pixels, pState, (decode_flags & cDecodeFlagsOutputHasAlphaIndices) != 0, pAlpha_blocks, output_rows_in_pixels); } diff --git a/transcoder/basisu_transcoder.h b/transcoder/basisu_transcoder.h index 6d96255..770c641 100644 --- a/transcoder/basisu_transcoder.h +++ b/transcoder/basisu_transcoder.h @@ -139,7 +139,7 @@ namespace basist bool decode_tables(const uint8_t *pTable_data, uint32_t table_data_size); bool transcode_slice(void *pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t *pImage_data, uint32_t image_data_size, block_format fmt, - uint32_t output_block_or_pixel_stride_in_bytes, bool wrap_addressing, bool bc1_allow_threecolor_blocks, const basis_file_header &header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels = 0, + uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const basis_file_header &header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state *pState = nullptr, bool astc_transcode_alpha = false, void* pAlpha_blocks = nullptr, uint32_t output_rows_in_pixels = 0); private: @@ -304,9 +304,6 @@ namespace basist enum { - // PVRTC1: texture will use wrap addressing vs. clamp (most PVRTC viewer tools assume wrap addressing, so we default to wrap although that can cause edge artifacts) - cDecodeFlagsPVRTCWrapAddressing = 1, - // PVRTC1: decode non-pow2 ETC1S texture level to the next larger power of 2 (not implemented yet, but we're going to support it). Ignored if the slice's dimensions are already a power of 2. cDecodeFlagsPVRTCDecodeToNextPow2 = 2, @@ -339,7 +336,7 @@ namespace basist uint32_t image_index, uint32_t level_index, void *pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, transcoder_texture_format fmt, - uint32_t decode_flags = cDecodeFlagsPVRTCWrapAddressing, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state *pState = nullptr, uint32_t output_rows_in_pixels = 0) const; + uint32_t decode_flags = 0, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state *pState = nullptr, uint32_t output_rows_in_pixels = 0) const; // Finds the basis slice corresponding to the specified image/level/alpha params, or -1 if the slice can't be found. int find_slice(const void *pData, uint32_t data_size, uint32_t image_index, uint32_t level_index, bool alpha_data) const; @@ -355,7 +352,7 @@ namespace basist // - basisu_transcoder_init() must have been called first to initialize the transcoder lookup tables before calling this function. bool transcode_slice(const void *pData, uint32_t data_size, uint32_t slice_index, void *pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, - block_format fmt, uint32_t output_block_stride_in_bytes, uint32_t decode_flags = cDecodeFlagsPVRTCWrapAddressing, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state * pState = nullptr, void* pAlpha_blocks = nullptr, uint32_t output_rows_in_pixels = 0) const; + block_format fmt, uint32_t output_block_stride_in_bytes, uint32_t decode_flags = 0, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state * pState = nullptr, void* pAlpha_blocks = nullptr, uint32_t output_rows_in_pixels = 0) const; private: mutable basisu_lowlevel_transcoder m_lowlevel_decoder; diff --git a/webgl/texture/index.html b/webgl/texture/index.html index 97191eb..8991f80 100644 --- a/webgl/texture/index.html +++ b/webgl/texture/index.html @@ -236,7 +236,8 @@ function dataLoaded(data) const dstSize = basisFile.getImageTranscodedSizeInBytes(0, 0, format); const dst = new Uint8Array(dstSize); - if (!basisFile.transcodeImage(dst, 0, 0, format, 1, 0)) { +// if (!basisFile.transcodeImage(dst, 0, 0, format, 1, 0)) { + if (!basisFile.transcodeImage(dst, 0, 0, format, 0, 0)) { log('basisFile.transcodeImage failed'); console.warn('transcodeImage failed'); basisFile.close(); diff --git a/webgl/transcoder/basis_wrappers.cpp b/webgl/transcoder/basis_wrappers.cpp index c281af0..356a4f9 100644 --- a/webgl/transcoder/basis_wrappers.cpp +++ b/webgl/transcoder/basis_wrappers.cpp @@ -154,7 +154,9 @@ struct basis_file return m_transcoder.start_transcoding(m_file.data(), m_file.size()); } - uint32_t transcodeImage(const emscripten::val& dst, uint32_t image_index, uint32_t level_index, uint32_t format, uint32_t pvrtc_wrap_addressing, uint32_t get_alpha_for_opaque_formats) { + uint32_t transcodeImage(const emscripten::val& dst, uint32_t image_index, uint32_t level_index, uint32_t format, uint32_t unused, uint32_t get_alpha_for_opaque_formats) { + (void)unused; + assert(m_magic == MAGIC); if (m_magic != MAGIC) return 0; @@ -170,7 +172,7 @@ struct basis_file std::vector dst_data; - uint32_t flags = (pvrtc_wrap_addressing ? basisu_transcoder::cDecodeFlagsPVRTCWrapAddressing : 0) | (get_alpha_for_opaque_formats ? basisu_transcoder::cDecodeFlagsTranscodeAlphaDataToOpaqueFormats : 0); + uint32_t flags = get_alpha_for_opaque_formats ? basisu_transcoder::cDecodeFlagsTranscodeAlphaDataToOpaqueFormats : 0; uint32_t status; @@ -255,8 +257,8 @@ EMSCRIPTEN_BINDINGS(basis_transcoder) { .function("startTranscoding", optional_override([](basis_file& self) { return self.startTranscoding(); })) - .function("transcodeImage", optional_override([](basis_file& self, const emscripten::val& dst, uint32_t imageIndex, uint32_t levelIndex, uint32_t format, uint32_t pvrtcWrapAddressing, uint32_t getAlphaForOpaqueFormats) { - return self.transcodeImage(dst, imageIndex, levelIndex, format, pvrtcWrapAddressing, getAlphaForOpaqueFormats); + .function("transcodeImage", optional_override([](basis_file& self, const emscripten::val& dst, uint32_t imageIndex, uint32_t levelIndex, uint32_t format, uint32_t unused, uint32_t getAlphaForOpaqueFormats) { + return self.transcodeImage(dst, imageIndex, levelIndex, format, unused, getAlphaForOpaqueFormats); })) ;