From 10ca5b7c91527c9c9d5a24704f3a96ada6cb1336 Mon Sep 17 00:00:00 2001 From: Bigfoot71 Date: Sun, 15 Mar 2026 03:14:25 +0100 Subject: [PATCH] review pixel get/set less ops for certain formats + fixes --- src/external/rlsw.h | 305 +++++++++++++++++--------------------------- 1 file changed, 120 insertions(+), 185 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 42824af0f..b661f51d6 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -954,6 +954,13 @@ static inline void sw_matrix_mul(sw_matrix_t dst, const sw_matrix_t left, const for (int i = 0; i < 16; i++) dst[i] = result[i]; } +static inline int sw_clampi(int v, int min, int max) +{ + if (v < min) return min; + if (v > max) return max; + return v; +} + static inline float sw_saturate(float x) { union { float f; uint32_t u; } fb; @@ -976,11 +983,14 @@ static inline float sw_fract(float x) return (x - floorf(x)); } -static inline int sw_clampi(int v, int min, int max) +static inline uint8_t sw_luminancei(const uint8_t *color) { - if (v < min) return min; - if (v > max) return max; - return v; + return (uint8_t)((color[0]*77 + color[1]*150 + color[2]*29) >> 8); +} + +static inline float sw_luminance(const float *color) +{ + return color[0]*0.299f + color[1]*0.587f + color[2]*0.114f; } static inline void sw_lerp_vertex_PTCH(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT a, const sw_vertex_t *SW_RESTRICT b, float t) @@ -1141,102 +1151,35 @@ static inline float sw_half_to_float(uint16_t y) return v.f; } -// !!! TEMP !!! -// ------------------------------------------------------------------------------------------ -static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) -{ -#if defined(SW_HAS_NEON) - float32x4_t values = vld1q_f32(src); - float32x4_t scaled = vmulq_n_f32(values, 255.0f); - int32x4_t clamped_s32 = vcvtq_s32_f32(scaled); // f32 -> s32 (truncated) - int16x4_t narrow16_s = vqmovn_s32(clamped_s32); - int16x8_t combined16_s = vcombine_s16(narrow16_s, narrow16_s); - uint8x8_t narrow8_u = vqmovun_s16(combined16_s); - vst1_lane_u32((uint32_t*)dst, vreinterpret_u32_u8(narrow8_u), 0); -#elif defined(SW_HAS_SSE41) - __m128 values = _mm_loadu_ps(src); - __m128 scaled = _mm_mul_ps(values, _mm_set1_ps(255.0f)); - __m128i clamped = _mm_cvtps_epi32(scaled); // f32 -> s32 (truncated) - clamped = _mm_packus_epi32(clamped, clamped); // s32 -> u16 (saturated < 0 to 0) - clamped = _mm_packus_epi16(clamped, clamped); // u16 -> u8 (saturated > 255 to 255) - *(uint32_t*)dst = _mm_cvtsi128_si32(clamped); -#elif defined(SW_HAS_SSE2) - __m128 values = _mm_loadu_ps(src); - __m128 scaled = _mm_mul_ps(values, _mm_set1_ps(255.0f)); - __m128i clamped = _mm_cvtps_epi32(scaled); // f32 -> s32 (truncated) - clamped = _mm_packs_epi32(clamped, clamped); // s32 -> s16 (saturated) - clamped = _mm_packus_epi16(clamped, clamped); // s16 -> u8 (saturated < 0 to 0) - *(uint32_t*)dst = _mm_cvtsi128_si32(clamped); -#elif defined(SW_HAS_RVV) - // TODO: Sample code generated by AI, needs testing and review - // NOTE: RVV 1.0 specs define the use of __riscv_ prefix for instrinsic functions - size_t vl = __riscv_vsetvl_e32m1(4); // Load up to 4 floats into a vector register - vfloat32m1_t vsrc = __riscv_vle32_v_f32m1(src, vl); // Load float32 values +static inline uint8_t sw_expand_1to8(uint32_t v) { return v ? 255 : 0; } +static inline uint8_t sw_expand_2to8(uint32_t v) { return (uint8_t)(v*85); } +static inline uint8_t sw_expand_3to8(uint32_t v) { return (uint8_t)((v << 5) | (v << 2) | (v >> 1)); } +static inline uint8_t sw_expand_4to8(uint32_t v) { return (uint8_t)((v << 4) | v); } +static inline uint8_t sw_expand_5to8(uint32_t v) { return (uint8_t)((v << 3) | (v >> 2)); } +static inline uint8_t sw_expand_6to8(uint32_t v) { return (uint8_t)((v << 2) | (v >> 4)); } - // Clamp to [0.0f, 1.0f] - vfloat32m1_t vzero = __riscv_vfmv_v_f_f32m1(0.0f, vl); - vfloat32m1_t vone = __riscv_vfmv_v_f_f32m1(1.0f, vl); - vsrc = __riscv_vfmin_vv_f32m1(vsrc, vone, vl); - vsrc = __riscv_vfmax_vv_f32m1(vsrc, vzero, vl); +static inline float sw_expand_1tof(uint32_t v) { return v ? 1.0f : 0.0f; } +static inline float sw_expand_2tof(uint32_t v) { return (float)v*(1.0f/3.0f); } +static inline float sw_expand_3tof(uint32_t v) { return (float)v*(1.0f/7.0f); } +static inline float sw_expand_4tof(uint32_t v) { return (float)v*(1.0f/15.0f); } +static inline float sw_expand_5tof(uint32_t v) { return (float)v*(1.0f/31.0f); } +static inline float sw_expand_6tof(uint32_t v) { return (float)v*(1.0f/63.0f); } - // Multiply by 255.0f and add 0.5f for rounding - vfloat32m1_t vscaled = __riscv_vfmul_vf_f32m1(vsrc, 255.0f, vl); - vscaled = __riscv_vfadd_vf_f32m1(vscaled, 0.5f, vl); +static inline uint32_t sw_compress_8to1(uint8_t v) { return v >> 7; } +static inline uint32_t sw_compress_8to2(uint8_t v) { return v >> 6; } +static inline uint32_t sw_compress_8to3(uint8_t v) { return v >> 5; } +static inline uint32_t sw_compress_8to4(uint8_t v) { return v >> 4; } +static inline uint32_t sw_compress_8to5(uint8_t v) { return v >> 3; } +static inline uint32_t sw_compress_8to6(uint8_t v) { return v >> 2; } - // Convert to unsigned integer (truncate toward zero) - vuint32m1_t vu32 = __riscv_vfcvt_xu_f_v_u32m1(vscaled, vl); +static inline uint32_t sw_compress_fto1(float v) { return v >= 0.5f ? 1 : 0; } +static inline uint32_t sw_compress_fto2(float v) { return (uint32_t)(v* 3.0f + 0.5f) & 0x03; } +static inline uint32_t sw_compress_fto3(float v) { return (uint32_t)(v* 7.0f + 0.5f) & 0x07; } +static inline uint32_t sw_compress_fto4(float v) { return (uint32_t)(v*15.0f + 0.5f) & 0x0F; } +static inline uint32_t sw_compress_fto5(float v) { return (uint32_t)(v*31.0f + 0.5f) & 0x1F; } +static inline uint32_t sw_compress_fto6(float v) { return (uint32_t)(v*63.0f + 0.5f) & 0x3F; } +static inline uint32_t sw_compress_fto8(float v) { return (uint32_t)(v*255.0f); } - // Narrow from u32 -> u8 - vuint8m1_t vu8 = __riscv_vnclipu_wx_u8m1(vu32, 0, vl); // Round toward zero - __riscv_vse8_v_u8m1(dst, vu8, vl); // Store result -#else - for (int i = 0; i < 4; i++) - { - float val = src[i]*255.0f; - val = (val > 255.0f)? 255.0f : val; - val = (val < 0.0f)? 0.0f : val; - dst[i] = (uint8_t)val; - } -#endif -} - -static inline void sw_float_from_unorm8_simd(float dst[4], const uint8_t src[4]) -{ -#if defined(SW_HAS_NEON) - uint8x8_t bytes8 = vld1_u8(src); // Reading 8 bytes, faster, but let's hope not hitting the end of the page (unlikely)... - uint16x8_t bytes16 = vmovl_u8(bytes8); - uint32x4_t ints = vmovl_u16(vget_low_u16(bytes16)); - float32x4_t floats = vcvtq_f32_u32(ints); - floats = vmulq_n_f32(floats, SW_INV_255); - vst1q_f32(dst, floats); -#elif defined(SW_HAS_SSE41) - __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t *)src); - __m128i ints = _mm_cvtepu8_epi32(bytes); - __m128 floats = _mm_cvtepi32_ps(ints); - floats = _mm_mul_ps(floats, _mm_set1_ps(SW_INV_255)); - _mm_storeu_ps(dst, floats); -#elif defined(SW_HAS_SSE2) - __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t *)src); - bytes = _mm_unpacklo_epi8(bytes, _mm_setzero_si128()); - __m128i ints = _mm_unpacklo_epi16(bytes, _mm_setzero_si128()); - __m128 floats = _mm_cvtepi32_ps(ints); - floats = _mm_mul_ps(floats, _mm_set1_ps(SW_INV_255)); - _mm_storeu_ps(dst, floats); -#elif defined(SW_HAS_RVV) - // TODO: Sample code generated by AI, needs testing and review - size_t vl = __riscv_vsetvl_e8m1(4); // Set vector length for 8-bit input elements - vuint8m1_t vsrc_u8 = __riscv_vle8_v_u8m1(src, vl); // Load 4 unsigned 8-bit integers - vuint32m1_t vsrc_u32 = __riscv_vwcvt_xu_u_v_u32m1(vsrc_u8, vl); // Widen to 32-bit unsigned integers - vfloat32m1_t vsrc_f32 = __riscv_vfcvt_f_xu_v_f32m1(vsrc_u32, vl); // Convert to float32 - vfloat32m1_t vnorm = __riscv_vfmul_vf_f32m1(vsrc_f32, SW_INV_255, vl); // Multiply by 1/255.0 to normalize - __riscv_vse32_v_f32m1(dst, vnorm, vl); // Store result -#else - dst[0] = (float)src[0]*SW_INV_255; - dst[1] = (float)src[1]*SW_INV_255; - dst[2] = (float)src[2]*SW_INV_255; - dst[3] = (float)src[3]*SW_INV_255; -#endif -} // ------------------------------------------------------------------------------------------ // Pixel format management functions @@ -1340,18 +1283,18 @@ static inline void sw_pixel_get_color8_GRAYALPHA(uint8_t *color, const void *pix static inline void sw_pixel_get_color8_R3G3B2(uint8_t *color, const void *pixels, uint32_t offset) { uint8_t pixel = ((const uint8_t*)pixels)[offset]; - color[0] = ((pixel >> 5) & 0x07)*255/7; // R (3 bits) - color[1] = ((pixel >> 2) & 0x07)*255/7; // G (3 bits) - color[2] = (pixel & 0x03)*255/3; // B (2 bits) + color[0] = sw_expand_3to8((pixel >> 5) & 0x07); + color[1] = sw_expand_3to8((pixel >> 2) & 0x07); + color[2] = sw_expand_2to8( pixel & 0x03); color[3] = 255; } static inline void sw_pixel_get_color8_R5G6B5(uint8_t *color, const void *pixels, uint32_t offset) { uint16_t pixel = ((const uint16_t*)pixels)[offset]; - color[0] = ((pixel >> 11) & 0x1F)*255/31; // R (5 bits) - color[1] = ((pixel >> 5) & 0x3F)*255/63; // G (6 bits) - color[2] = (pixel & 0x1F)*255/31; // B (5 bits) + color[0] = sw_expand_5to8((pixel >> 11) & 0x1F); + color[1] = sw_expand_6to8((pixel >> 5) & 0x3F); + color[2] = sw_expand_5to8( pixel & 0x1F); color[3] = 255; } @@ -1367,19 +1310,19 @@ static inline void sw_pixel_get_color8_R8G8B8(uint8_t *color, const void *pixels static inline void sw_pixel_get_color8_R5G5B5A1(uint8_t *color, const void *pixels, uint32_t offset) { uint16_t pixel = ((const uint16_t*)pixels)[offset]; - color[0] = ((pixel >> 11) & 0x1F)*255/31; // R (5 bits) - color[1] = ((pixel >> 6) & 0x1F)*255/31; // G (5 bits) - color[2] = ((pixel >> 1) & 0x1F)*255/31; // B (5 bits) - color[3] = (pixel & 0x01)*255; // A (1 bit) + color[0] = sw_expand_5to8((pixel >> 11) & 0x1F); + color[1] = sw_expand_5to8((pixel >> 6) & 0x1F); + color[2] = sw_expand_5to8((pixel >> 1) & 0x1F); + color[3] = sw_expand_1to8( pixel & 0x01); } static inline void sw_pixel_get_color8_R4G4B4A4(uint8_t *color, const void *pixels, uint32_t offset) { uint16_t pixel = ((const uint16_t*)pixels)[offset]; - color[0] = ((pixel >> 12) & 0x0F)*255/15; // R (4 bits) - color[1] = ((pixel >> 8) & 0x0F)*255/15; // G (4 bits) - color[2] = ((pixel >> 4) & 0x0F)*255/15; // B (4 bits) - color[3] = (pixel & 0x0F)*255/15; // A (4 bits) + color[0] = sw_expand_4to8((pixel >> 12) & 0x0F); + color[1] = sw_expand_4to8((pixel >> 8) & 0x0F); + color[2] = sw_expand_4to8((pixel >> 4) & 0x0F); + color[3] = sw_expand_4to8( pixel & 0x0F); } static inline void sw_pixel_get_color8_R8G8B8A8(uint8_t *color, const void *pixels, uint32_t offset) @@ -1393,8 +1336,7 @@ static inline void sw_pixel_get_color8_R8G8B8A8(uint8_t *color, const void *pixe static inline void sw_pixel_get_color8_R32(uint8_t *color, const void *pixels, uint32_t offset) { - float val = ((const float*)pixels)[offset]; - uint8_t gray = (uint8_t)(val*255.0f); + uint8_t gray = (uint8_t)(((const float*)pixels)[offset]*255.0f); color[0] = gray; color[1] = gray; color[2] = gray; @@ -1421,8 +1363,7 @@ static inline void sw_pixel_get_color8_R32G32B32A32(uint8_t *color, const void * static inline void sw_pixel_get_color8_R16(uint8_t *color, const void *pixels, uint32_t offset) { - uint16_t val = ((const uint16_t*)pixels)[offset]; - uint8_t gray = sw_half_to_float(val)*SW_INV_255; + uint8_t gray = (uint8_t)(sw_half_to_float(((const uint16_t*)pixels)[offset])*255.0f); color[0] = gray; color[1] = gray; color[2] = gray; @@ -1432,19 +1373,19 @@ static inline void sw_pixel_get_color8_R16(uint8_t *color, const void *pixels, u static inline void sw_pixel_get_color8_R16G16B16(uint8_t *color, const void *pixels, uint32_t offset) { const uint16_t *src = &((const uint16_t*)pixels)[offset*3]; - color[0] = sw_half_to_float(src[0])*SW_INV_255; - color[1] = sw_half_to_float(src[1])*SW_INV_255; - color[2] = sw_half_to_float(src[2])*SW_INV_255; + color[0] = (uint8_t)(sw_half_to_float(src[0])*255.0f); + color[1] = (uint8_t)(sw_half_to_float(src[1])*255.0f); + color[2] = (uint8_t)(sw_half_to_float(src[2])*255.0f); color[3] = 255; } static inline void sw_pixel_get_color8_R16G16B16A16(uint8_t *color, const void *pixels, uint32_t offset) { const uint16_t *src = &((const uint16_t*)pixels)[offset*4]; - color[0] = sw_half_to_float(src[0])*SW_INV_255; - color[1] = sw_half_to_float(src[1])*SW_INV_255; - color[2] = sw_half_to_float(src[2])*SW_INV_255; - color[3] = sw_half_to_float(src[3])*SW_INV_255; + color[0] = (uint8_t)(sw_half_to_float(src[0])*255.0f); + color[1] = (uint8_t)(sw_half_to_float(src[1])*255.0f); + color[2] = (uint8_t)(sw_half_to_float(src[2])*255.0f); + color[3] = (uint8_t)(sw_half_to_float(src[3])*255.0f); } static inline void sw_pixel_get_color8(uint8_t *color, const void *pixels, uint32_t offset, sw_pixelformat_t format) @@ -1511,30 +1452,29 @@ static inline void sw_pixel_get_color8(uint8_t *color, const void *pixels, uint3 static inline void sw_pixel_set_color8_GRAYSCALE(void *pixels, const uint8_t *color, uint32_t offset) { - uint8_t gray = (uint8_t)(color[0]*77 + color[1]*150 + color[2]*29) >> 8; // luminance - ((uint8_t*)pixels)[offset] = gray; + ((uint8_t*)pixels)[offset] = sw_luminancei(color); } static inline void sw_pixel_set_color8_GRAYALPHA(void *pixels, const uint8_t *color, uint32_t offset) { uint8_t *dst = &((uint8_t*)pixels)[offset*2]; - dst[0] = (uint8_t)(color[0]*77 + color[1]*150 + color[2]*29) >> 8; + dst[0] = sw_luminancei(color); dst[1] = color[3]; } static inline void sw_pixel_set_color8_R3G3B2(void *pixels, const uint8_t *color, uint32_t offset) { - uint8_t pixel = ((color[0]*7/255) & 0x07) << 5 // R (3 bits) - | ((color[1]*7/255) & 0x07) << 2 // G (3 bits) - | ((color[2]*3/255) & 0x03); // B (2 bits) + uint8_t pixel = (sw_compress_8to3(color[0]) << 5) + | (sw_compress_8to3(color[1]) << 2) + | sw_compress_8to2(color[2]); ((uint8_t*)pixels)[offset] = pixel; } static inline void sw_pixel_set_color8_R5G6B5(void *pixels, const uint8_t *color, uint32_t offset) { - uint16_t pixel = ((color[0]*31/255) & 0x1F) << 11 // R (5 bits) - | ((color[1]*63/255) & 0x3F) << 5 // G (6 bits) - | ((color[2]*31/255) & 0x1F); // B (5 bits) + uint16_t pixel = (sw_compress_8to5(color[0]) << 11) + | (sw_compress_8to6(color[1]) << 5) + | sw_compress_8to5(color[2]); ((uint16_t*)pixels)[offset] = pixel; } @@ -1548,19 +1488,19 @@ static inline void sw_pixel_set_color8_R8G8B8(void *pixels, const uint8_t *color static inline void sw_pixel_set_color8_R5G5B5A1(void *pixels, const uint8_t *color, uint32_t offset) { - uint16_t pixel = ((color[0]*31/255) & 0x1F) << 11 // R (5 bits) - | ((color[1]*31/255) & 0x1F) << 6 // G (5 bits) - | ((color[2]*31/255) & 0x1F) << 1 // B (5 bits) - | ((color[3] > 127) ? 1 : 0); // A (1 bit) + uint16_t pixel = (sw_compress_8to5(color[0]) << 11) + | (sw_compress_8to5(color[1]) << 6) + | (sw_compress_8to5(color[2]) << 1) + | sw_compress_8to1(color[3]); ((uint16_t*)pixels)[offset] = pixel; } static inline void sw_pixel_set_color8_R4G4B4A4(void *pixels, const uint8_t *color, uint32_t offset) { - uint16_t pixel = ((color[0]*15/255) & 0x0F) << 12 // R (4 bits) - | ((color[1]*15/255) & 0x0F) << 8 // G (4 bits) - | ((color[2]*15/255) & 0x0F) << 4 // B (4 bits) - | ((color[3]*15/255) & 0x0F); // A (4 bits) + uint16_t pixel = (sw_compress_8to4(color[0]) << 12) + | (sw_compress_8to4(color[1]) << 8) + | (sw_compress_8to4(color[2]) << 4) + | sw_compress_8to4(color[3]); ((uint16_t*)pixels)[offset] = pixel; } @@ -1575,8 +1515,7 @@ static inline void sw_pixel_set_color8_R8G8B8A8(void *pixels, const uint8_t *col static inline void sw_pixel_set_color8_R32(void *pixels, const uint8_t *color, uint32_t offset) { - float gray = (color[0]*77 + color[1]*150 + color[2]*29) / (255.0f*256.0f); - ((float*)pixels)[offset] = gray; + ((float*)pixels)[offset] = sw_luminancei(color)*SW_INV_255; } static inline void sw_pixel_set_color8_R32G32B32(void *pixels, const uint8_t *color, uint32_t offset) @@ -1598,8 +1537,7 @@ static inline void sw_pixel_set_color8_R32G32B32A32(void *pixels, const uint8_t static inline void sw_pixel_set_color8_R16(void *pixels, const uint8_t *color, uint32_t offset) { - float gray = (color[0]*77 + color[1]*150 + color[2]*29) / (255.0f*256.0f); - ((uint16_t*)pixels)[offset] = sw_float_to_half(gray); + ((uint16_t*)pixels)[offset] = sw_float_to_half(sw_luminancei(color)*SW_INV_255); } static inline void sw_pixel_set_color8_R16G16B16(void *pixels, const uint8_t *color, uint32_t offset) @@ -1697,18 +1635,18 @@ static inline void sw_pixel_get_color_GRAYALPHA(float *color, const void *pixels static inline void sw_pixel_get_color_R3G3B2(float *color, const void *pixels, uint32_t offset) { uint8_t pixel = ((const uint8_t*)pixels)[offset]; - color[0] = ((pixel >> 5) & 0x07)/7.0f; // R (3 bits) - color[1] = ((pixel >> 2) & 0x07)/7.0f; // G (3 bits) - color[2] = (pixel & 0x03)/3.0f; // B (2 bits) + color[0] = sw_expand_3tof((pixel >> 5) & 0x07); + color[1] = sw_expand_3tof((pixel >> 2) & 0x07); + color[2] = sw_expand_2tof( pixel & 0x03); color[3] = 1.0f; } static inline void sw_pixel_get_color_R5G6B5(float *color, const void *pixels, uint32_t offset) { uint16_t pixel = ((const uint16_t*)pixels)[offset]; - color[0] = ((pixel >> 11) & 0x1F)/31.0f; // R (5 bits) - color[1] = ((pixel >> 5) & 0x3F)/63.0f; // G (6 bits) - color[2] = (pixel & 0x1F)/31.0f; // B (5 bits) + color[0] = sw_expand_5tof((pixel >> 11) & 0x1F); + color[1] = sw_expand_6tof((pixel >> 5) & 0x3F); + color[2] = sw_expand_5tof( pixel & 0x1F); color[3] = 1.0f; } @@ -1724,19 +1662,19 @@ static inline void sw_pixel_get_color_R8G8B8(float *color, const void *pixels, u static inline void sw_pixel_get_color_R5G5B5A1(float *color, const void *pixels, uint32_t offset) { uint16_t pixel = ((const uint16_t*)pixels)[offset]; - color[0] = ((pixel >> 11) & 0x1F)/31.0f; // R (5 bits) - color[1] = ((pixel >> 6) & 0x1F)/31.0f; // G (5 bits) - color[2] = ((pixel >> 1) & 0x1F)/31.0f; // B (5 bits) - color[3] = (pixel & 0x01)? 1.0f : 0.0f; // A (1 bit) + color[0] = sw_expand_5tof((pixel >> 11) & 0x1F); + color[1] = sw_expand_5tof((pixel >> 6) & 0x1F); + color[2] = sw_expand_5tof((pixel >> 1) & 0x1F); + color[3] = sw_expand_1tof( pixel & 0x01); } static inline void sw_pixel_get_color_R4G4B4A4(float *color, const void *pixels, uint32_t offset) { uint16_t pixel = ((const uint16_t*)pixels)[offset]; - color[0] = ((pixel >> 12) & 0x0F)/15.0f; // R (4 bits) - color[1] = ((pixel >> 8) & 0x0F)/15.0f; // G (4 bits) - color[2] = ((pixel >> 4) & 0x0F)/15.0f; // B (4 bits) - color[3] = (pixel & 0x0F)/15.0f; // A (4 bits) + color[0] = sw_expand_4tof((pixel >> 12) & 0x0F); + color[1] = sw_expand_4tof((pixel >> 8) & 0x0F); + color[2] = sw_expand_4tof((pixel >> 4) & 0x0F); + color[3] = sw_expand_4tof( pixel & 0x0F); } static inline void sw_pixel_get_color_R8G8B8A8(float *color, const void *pixels, uint32_t offset) @@ -1866,72 +1804,70 @@ static inline void sw_pixel_get_color(float *color, const void *pixels, uint32_t static inline void sw_pixel_set_color_GRAYSCALE(void *pixels, const float *color, uint32_t offset) { - uint8_t gray = (uint8_t)((color[0]*0.299f + color[1]*0.587f + color[2]*0.114f)*255.0f); - ((uint8_t*)pixels)[offset] = gray; + ((uint8_t*)pixels)[offset] = (uint8_t)(sw_luminance(color)*255.0f); } static inline void sw_pixel_set_color_GRAYALPHA(void *pixels, const float *color, uint32_t offset) { uint8_t *dst = &((uint8_t*)pixels)[offset*2]; - dst[0] = (uint8_t)((color[0]*0.299f + color[1]*0.587f + color[2]*0.114f)*255.0f); - dst[1] = (uint8_t)(color[3]*255.0f); + dst[0] = (uint8_t)(sw_luminance(color)*255.0f); + dst[1] = sw_compress_fto8(color[3]); } static inline void sw_pixel_set_color_R3G3B2(void *pixels, const float *color, uint32_t offset) { - uint8_t pixel = ((uint8_t)(color[0]*7.0f + 0.5f) & 0x07) << 5 // R (3 bits) - | ((uint8_t)(color[1]*7.0f + 0.5f) & 0x07) << 2 // G (3 bits) - | ((uint8_t)(color[2]*3.0f + 0.5f) & 0x03); // B (2 bits) + uint8_t pixel = (sw_compress_fto3(color[0]) << 5) + | (sw_compress_fto3(color[1]) << 2) + | sw_compress_fto2(color[2]); ((uint8_t*)pixels)[offset] = pixel; } static inline void sw_pixel_set_color_R5G6B5(void *pixels, const float *color, uint32_t offset) { - uint16_t pixel = ((uint16_t)(color[0]*31.0f + 0.5f) & 0x1F) << 11 // R (5 bits) - | ((uint16_t)(color[1]*63.0f + 0.5f) & 0x3F) << 5 // G (6 bits) - | ((uint16_t)(color[2]*31.0f + 0.5f) & 0x1F); // B (5 bits) + uint16_t pixel = (sw_compress_fto5(color[0]) << 11) + | (sw_compress_fto6(color[1]) << 5) + | sw_compress_fto5(color[2]); ((uint16_t*)pixels)[offset] = pixel; } static inline void sw_pixel_set_color_R8G8B8(void *pixels, const float *color, uint32_t offset) { uint8_t *dst = &((uint8_t*)pixels)[offset*3]; - dst[0] = (uint8_t)(color[0]*255.0f); - dst[1] = (uint8_t)(color[1]*255.0f); - dst[2] = (uint8_t)(color[2]*255.0f); + dst[0] = sw_compress_fto8(color[0]); + dst[1] = sw_compress_fto8(color[1]); + dst[2] = sw_compress_fto8(color[2]); } static inline void sw_pixel_set_color_R5G5B5A1(void *pixels, const float *color, uint32_t offset) { - uint16_t pixel = ((uint16_t)(color[0]*31.0f + 0.5f) & 0x1F) << 11 // R (5 bits) - | ((uint16_t)(color[1]*31.0f + 0.5f) & 0x1F) << 6 // G (5 bits) - | ((uint16_t)(color[2]*31.0f + 0.5f) & 0x1F) << 1 // B (5 bits) - | (color[3] >= 0.5f? 1 : 0); // A (1 bit) + uint16_t pixel = (sw_compress_fto5(color[0]) << 11) + | (sw_compress_fto5(color[1]) << 6) + | (sw_compress_fto5(color[2]) << 1) + | sw_compress_fto1(color[3]); ((uint16_t*)pixels)[offset] = pixel; } static inline void sw_pixel_set_color_R4G4B4A4(void *pixels, const float *color, uint32_t offset) { - uint16_t pixel = ((uint16_t)(color[0]*15.0f + 0.5f) & 0x0F) << 12 // R (4 bits) - | ((uint16_t)(color[1]*15.0f + 0.5f) & 0x0F) << 8 // G (4 bits) - | ((uint16_t)(color[2]*15.0f + 0.5f) & 0x0F) << 4 // B (4 bits) - | ((uint16_t)(color[3]*15.0f + 0.5f) & 0x0F); // A (4 bits) + uint16_t pixel = (sw_compress_fto4(color[0]) << 12) + | (sw_compress_fto4(color[1]) << 8) + | (sw_compress_fto4(color[2]) << 4) + | sw_compress_fto4(color[3]); ((uint16_t*)pixels)[offset] = pixel; } static inline void sw_pixel_set_color_R8G8B8A8(void *pixels, const float *color, uint32_t offset) { uint8_t *dst = &((uint8_t*)pixels)[offset*4]; - dst[0] = (uint8_t)(color[0]*255.0f); - dst[1] = (uint8_t)(color[1]*255.0f); - dst[2] = (uint8_t)(color[2]*255.0f); - dst[3] = (uint8_t)(color[3]*255.0f); + dst[0] = sw_compress_fto8(color[0]); + dst[1] = sw_compress_fto8(color[1]); + dst[2] = sw_compress_fto8(color[2]); + dst[3] = sw_compress_fto8(color[3]); } static inline void sw_pixel_set_color_R32(void *pixels, const float *color, uint32_t offset) { - float gray = color[0]*0.299f + color[1]*0.587f + color[2]*0.114f; - ((float*)pixels)[offset] = gray; + ((float*)pixels)[offset] = sw_luminance(color); } static inline void sw_pixel_set_color_R32G32B32(void *pixels, const float *color, uint32_t offset) @@ -1953,8 +1889,7 @@ static inline void sw_pixel_set_color_R32G32B32A32(void *pixels, const float *co static inline void sw_pixel_set_color_R16(void *pixels, const float *color, uint32_t offset) { - float gray = color[0]*0.299f + color[1]*0.587f + color[2]*0.114f; - ((uint16_t*)pixels)[offset] = sw_float_to_half(gray); + ((uint16_t*)pixels)[offset] = sw_float_to_half(sw_luminance(color)); } static inline void sw_pixel_set_color_R16G16B16(void *pixels, const float *color, uint32_t offset)