extends the simd color conversion to more cases
This commit is contained in:
parent
7915f46526
commit
23efe6decf
268
src/external/rlsw.h
vendored
268
src/external/rlsw.h
vendored
|
|
@ -1384,26 +1384,12 @@ 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_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)); }
|
static inline uint8_t sw_expand_6to8(uint32_t v) { return (uint8_t)((v << 2) | (v >> 4)); }
|
||||||
|
|
||||||
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); }
|
|
||||||
|
|
||||||
static inline uint32_t sw_compress_8to1(uint8_t v) { return v >> 7; }
|
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_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_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_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_8to5(uint8_t v) { return v >> 3; }
|
||||||
static inline uint32_t sw_compress_8to6(uint8_t v) { return v >> 2; }
|
static inline uint32_t sw_compress_8to6(uint8_t v) { return v >> 2; }
|
||||||
|
|
||||||
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; }
|
|
||||||
//-------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Object pool functions
|
// Object pool functions
|
||||||
|
|
@ -1631,6 +1617,94 @@ static inline int sw_pixel_get_format(SWformat format, SWtype type)
|
||||||
return SW_PIXELFORMAT_UNKNOWN;
|
return SW_PIXELFORMAT_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_color8_to_color(float *SW_RESTRICT dst, const uint8_t *SW_RESTRICT src)
|
||||||
|
{
|
||||||
|
#if defined(SW_HAS_NEON)
|
||||||
|
uint8x8_t bytes = vreinterpret_u8_u32(vld1_dup_u32((const uint32_t *)src));
|
||||||
|
uint16x8_t words = vmovl_u8(bytes);
|
||||||
|
uint32x4_t dwords = vmovl_u16(vget_low_u16(words));
|
||||||
|
float32x4_t fvals = vmulq_f32(vcvtq_f32_u32(dwords), vdupq_n_f32(SW_INV_255));
|
||||||
|
vst1q_f32(dst, fvals);
|
||||||
|
|
||||||
|
#elif defined(SW_HAS_SSE41)
|
||||||
|
__m128i bytes = _mm_loadu_si32(src);
|
||||||
|
__m128 fvals = _mm_mul_ps(_mm_cvtepi32_ps(_mm_cvtepu8_epi32(bytes)), _mm_set1_ps(SW_INV_255));
|
||||||
|
_mm_storeu_ps(dst, fvals);
|
||||||
|
|
||||||
|
#elif defined(SW_HAS_SSE2)
|
||||||
|
__m128i zero = _mm_setzero_si128();
|
||||||
|
__m128i bytes = _mm_loadu_si32(src);
|
||||||
|
__m128i words = _mm_unpacklo_epi8(bytes, zero);
|
||||||
|
__m128i dwords = _mm_unpacklo_epi16(words, zero);
|
||||||
|
__m128 fvals = _mm_mul_ps(_mm_cvtepi32_ps(dwords), _mm_set1_ps(SW_INV_255));
|
||||||
|
_mm_storeu_ps(dst, fvals);
|
||||||
|
|
||||||
|
#elif defined(SW_HAS_RVV)
|
||||||
|
// TODO: WARNING: 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
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sw_pixel_color_to_color8(uint8_t *SW_RESTRICT dst, const float *SW_RESTRICT src)
|
||||||
|
{
|
||||||
|
#if defined(SW_HAS_NEON)
|
||||||
|
float32x4_t fvals = vmulq_f32(vld1q_f32(src), vdupq_n_f32(255.0f));
|
||||||
|
uint32x4_t i32 = vcvtq_u32_f32(fvals);
|
||||||
|
uint16x4_t i16 = vmovn_u32(i32);
|
||||||
|
uint8x8_t i8 = vmovn_u16(vcombine_u16(i16, i16));
|
||||||
|
vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(i8), 0);
|
||||||
|
|
||||||
|
#elif defined(SW_HAS_SSE41)
|
||||||
|
__m128 fvals = _mm_mul_ps(_mm_loadu_ps(src), _mm_set1_ps(255.0f));
|
||||||
|
__m128i i32 = _mm_cvttps_epi32(fvals);
|
||||||
|
__m128i i16 = _mm_packus_epi32(i32, i32);
|
||||||
|
__m128i i8 = _mm_packus_epi16(i16, i16);
|
||||||
|
_mm_storeu_si32(dst, i8);
|
||||||
|
|
||||||
|
#elif defined(SW_HAS_SSE2)
|
||||||
|
__m128 fvals = _mm_mul_ps(_mm_loadu_ps(src), _mm_set1_ps(255.0f));
|
||||||
|
__m128i i32 = _mm_cvttps_epi32(fvals);
|
||||||
|
__m128i i16 = _mm_packs_epi32(i32, i32);
|
||||||
|
__m128i i8 = _mm_packus_epi16(i16, i16);
|
||||||
|
_mm_storeu_si32(dst, i8);
|
||||||
|
|
||||||
|
#elif defined(SW_HAS_RVV)
|
||||||
|
// TODO: WARNING: Sample code generated by AI, needs testing and review
|
||||||
|
// REVIEW: It shouldn't perform so many operations; take inspiration from other versions
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Convert to unsigned integer (truncate toward zero)
|
||||||
|
vuint32m1_t vu32 = __riscv_vfcvt_xu_f_v_u32m1(vscaled, vl);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
dst[0] = (uint8_t)(src[0]*255.0f);
|
||||||
|
dst[1] = (uint8_t)(src[1]*255.0f);
|
||||||
|
dst[2] = (uint8_t)(src[2]*255.0f);
|
||||||
|
dst[3] = (uint8_t)(src[3]*255.0f);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_get_color8_GRAYSCALE(uint8_t *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
static inline void sw_pixel_get_color8_GRAYSCALE(uint8_t *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
||||||
{
|
{
|
||||||
uint8_t gray = ((const uint8_t *)pixels)[offset];
|
uint8_t gray = ((const uint8_t *)pixels)[offset];
|
||||||
|
|
@ -1947,88 +2021,42 @@ static inline void sw_pixel_get_color_GRAYALPHA(float *SW_RESTRICT color, const
|
||||||
|
|
||||||
static inline void sw_pixel_get_color_R3G3B2(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
static inline void sw_pixel_get_color_R3G3B2(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
||||||
{
|
{
|
||||||
uint8_t pixel = ((const uint8_t *)pixels)[offset];
|
uint8_t unpack[4];
|
||||||
color[0] = sw_expand_3tof((pixel >> 5) & 0x07);
|
sw_pixel_get_color8_R3G3B2(unpack, pixels, offset);
|
||||||
color[1] = sw_expand_3tof((pixel >> 2) & 0x07);
|
sw_pixel_color8_to_color(color, unpack);
|
||||||
color[2] = sw_expand_2tof( pixel & 0x03);
|
|
||||||
color[3] = 1.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_get_color_R5G6B5(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
static inline void sw_pixel_get_color_R5G6B5(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
||||||
{
|
{
|
||||||
uint16_t pixel = ((const uint16_t *)pixels)[offset];
|
uint8_t unpack[4];
|
||||||
color[0] = sw_expand_5tof((pixel >> 11) & 0x1F);
|
sw_pixel_get_color8_R5G6B5(unpack, pixels, offset);
|
||||||
color[1] = sw_expand_6tof((pixel >> 5) & 0x3F);
|
sw_pixel_color8_to_color(color, unpack);
|
||||||
color[2] = sw_expand_5tof( pixel & 0x1F);
|
|
||||||
color[3] = 1.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_get_color_R8G8B8(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
static inline void sw_pixel_get_color_R8G8B8(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
||||||
{
|
{
|
||||||
const uint8_t *src = &((const uint8_t *)pixels)[offset*3];
|
uint8_t unpack[4];
|
||||||
color[0] = src[0]*SW_INV_255;
|
sw_pixel_get_color8_R8G8B8(unpack, pixels, offset);
|
||||||
color[1] = src[1]*SW_INV_255;
|
sw_pixel_color8_to_color(color, unpack);
|
||||||
color[2] = src[2]*SW_INV_255;
|
|
||||||
color[3] = 1.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_get_color_R5G5B5A1(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
static inline void sw_pixel_get_color_R5G5B5A1(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
||||||
{
|
{
|
||||||
uint16_t pixel = ((const uint16_t *)pixels)[offset];
|
uint8_t unpack[4];
|
||||||
color[0] = sw_expand_5tof((pixel >> 11) & 0x1F);
|
sw_pixel_get_color8_R5G5B5A1(unpack, pixels, offset);
|
||||||
color[1] = sw_expand_5tof((pixel >> 6) & 0x1F);
|
sw_pixel_color8_to_color(color, unpack);
|
||||||
color[2] = sw_expand_5tof((pixel >> 1) & 0x1F);
|
|
||||||
color[3] = sw_expand_1tof( pixel & 0x01);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_get_color_R4G4B4A4(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
static inline void sw_pixel_get_color_R4G4B4A4(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
||||||
{
|
{
|
||||||
uint16_t pixel = ((const uint16_t *)pixels)[offset];
|
uint8_t unpack[4];
|
||||||
color[0] = sw_expand_4tof((pixel >> 12) & 0x0F);
|
sw_pixel_get_color8_R4G4B4A4(unpack, pixels, offset);
|
||||||
color[1] = sw_expand_4tof((pixel >> 8) & 0x0F);
|
sw_pixel_color8_to_color(color, unpack);
|
||||||
color[2] = sw_expand_4tof((pixel >> 4) & 0x0F);
|
|
||||||
color[3] = sw_expand_4tof( pixel & 0x0F);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_get_color_R8G8B8A8(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
static inline void sw_pixel_get_color_R8G8B8A8(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
||||||
{
|
{
|
||||||
const uint8_t *src = &((const uint8_t *)pixels)[offset*4];
|
sw_pixel_color8_to_color(color, &((const uint8_t *)pixels)[offset*4]);
|
||||||
|
|
||||||
#if defined(SW_HAS_NEON)
|
|
||||||
uint32_t tmp = (uint32_t)src[0] | ((uint32_t)src[1] << 8) | ((uint32_t)src[2] << 16) | ((uint32_t)src[3] << 24);
|
|
||||||
uint8x8_t bytes = vreinterpret_u8_u32(vdup_n_u32(tmp));
|
|
||||||
uint16x8_t words = vmovl_u8(bytes);
|
|
||||||
uint32x4_t dwords = vmovl_u16(vget_low_u16(words));
|
|
||||||
float32x4_t fvals = vmulq_f32(vcvtq_f32_u32(dwords), vdupq_n_f32(SW_INV_255));
|
|
||||||
vst1q_f32(color, fvals);
|
|
||||||
|
|
||||||
#elif defined(SW_HAS_SSE41)
|
|
||||||
__m128i bytes = _mm_loadu_si32(src);
|
|
||||||
__m128 fvals = _mm_mul_ps(_mm_cvtepi32_ps(_mm_cvtepu8_epi32(bytes)), _mm_set1_ps(SW_INV_255));
|
|
||||||
_mm_storeu_ps(color, fvals);
|
|
||||||
|
|
||||||
#elif defined(SW_HAS_SSE2)
|
|
||||||
__m128i bytes = _mm_loadu_si32(src);
|
|
||||||
__m128i words = _mm_unpacklo_epi8(bytes, _mm_setzero_si128());
|
|
||||||
__m128i dwords = _mm_unpacklo_epi16(words, _mm_setzero_si128());
|
|
||||||
__m128 fvals = _mm_mul_ps(_mm_cvtepi32_ps(dwords), _mm_set1_ps(SW_INV_255));
|
|
||||||
_mm_storeu_ps(color, fvals);
|
|
||||||
|
|
||||||
#elif defined(SW_HAS_RVV)
|
|
||||||
// TODO: WARNING: 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(color, vnorm, vl); // Store result
|
|
||||||
|
|
||||||
#else
|
|
||||||
color[0] = (float)src[0]*SW_INV_255;
|
|
||||||
color[1] = (float)src[1]*SW_INV_255;
|
|
||||||
color[2] = (float)src[2]*SW_INV_255;
|
|
||||||
color[3] = (float)src[3]*SW_INV_255;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_get_color_R32(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
static inline void sw_pixel_get_color_R32(float *SW_RESTRICT color, const void *SW_RESTRICT pixels, uint32_t offset)
|
||||||
|
|
@ -2133,98 +2161,42 @@ static inline void sw_pixel_set_color_GRAYALPHA(void *SW_RESTRICT pixels, const
|
||||||
|
|
||||||
static inline void sw_pixel_set_color_R3G3B2(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
static inline void sw_pixel_set_color_R3G3B2(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
||||||
{
|
{
|
||||||
uint8_t pixel = (sw_compress_fto3(color[0]) << 5)
|
uint8_t color8[4];
|
||||||
| (sw_compress_fto3(color[1]) << 2)
|
sw_pixel_color_to_color8(color8, color);
|
||||||
| sw_compress_fto2(color[2]);
|
sw_pixel_set_color8_R3G3B2(pixels, color8, offset);
|
||||||
((uint8_t *)pixels)[offset] = pixel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_set_color_R5G6B5(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
static inline void sw_pixel_set_color_R5G6B5(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
||||||
{
|
{
|
||||||
uint16_t pixel = (sw_compress_fto5(color[0]) << 11)
|
uint8_t color8[4];
|
||||||
| (sw_compress_fto6(color[1]) << 5)
|
sw_pixel_color_to_color8(color8, color);
|
||||||
| sw_compress_fto5(color[2]);
|
sw_pixel_set_color8_R5G6B5(pixels, color8, offset);
|
||||||
((uint16_t *)pixels)[offset] = pixel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_set_color_R8G8B8(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
static inline void sw_pixel_set_color_R8G8B8(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
||||||
{
|
{
|
||||||
uint8_t *dst = &((uint8_t *)pixels)[offset*3];
|
uint8_t color8[4];
|
||||||
dst[0] = (uint8_t)(color[0]*255.0f);
|
sw_pixel_color_to_color8(color8, color);
|
||||||
dst[1] = (uint8_t)(color[1]*255.0f);
|
sw_pixel_set_color8_R8G8B8(pixels, color8, offset);
|
||||||
dst[2] = (uint8_t)(color[2]*255.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_set_color_R5G5B5A1(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
static inline void sw_pixel_set_color_R5G5B5A1(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
||||||
{
|
{
|
||||||
uint16_t pixel = (sw_compress_fto5(color[0]) << 11)
|
uint8_t color8[4];
|
||||||
| (sw_compress_fto5(color[1]) << 6)
|
sw_pixel_color_to_color8(color8, color);
|
||||||
| (sw_compress_fto5(color[2]) << 1)
|
sw_pixel_set_color8_R5G5B5A1(pixels, color8, offset);
|
||||||
| sw_compress_fto1(color[3]);
|
|
||||||
((uint16_t *)pixels)[offset] = pixel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_set_color_R4G4B4A4(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
static inline void sw_pixel_set_color_R4G4B4A4(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
||||||
{
|
{
|
||||||
uint16_t pixel = (sw_compress_fto4(color[0]) << 12)
|
uint8_t color8[4];
|
||||||
| (sw_compress_fto4(color[1]) << 8)
|
sw_pixel_color_to_color8(color8, color);
|
||||||
| (sw_compress_fto4(color[2]) << 4)
|
sw_pixel_set_color8_R4G4B4A4(pixels, color8, offset);
|
||||||
| sw_compress_fto4(color[3]);
|
|
||||||
((uint16_t *)pixels)[offset] = pixel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_set_color_R8G8B8A8(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
static inline void sw_pixel_set_color_R8G8B8A8(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
||||||
{
|
{
|
||||||
uint8_t *dst = &((uint8_t *)pixels)[offset*4];
|
sw_pixel_color_to_color8(&((uint8_t *)pixels)[offset*4], color);
|
||||||
|
|
||||||
#if defined(SW_HAS_NEON)
|
|
||||||
float32x4_t fvals = vmulq_f32(vld1q_f32(color), vdupq_n_f32(255.0f));
|
|
||||||
uint32x4_t i32 = vcvtq_u32_f32(fvals);
|
|
||||||
uint16x4_t i16 = vmovn_u32(i32);
|
|
||||||
uint8x8_t i8 = vmovn_u16(vcombine_u16(i16, i16));
|
|
||||||
dst[0] = vget_lane_u8(i8, 0);
|
|
||||||
dst[1] = vget_lane_u8(i8, 1);
|
|
||||||
dst[2] = vget_lane_u8(i8, 2);
|
|
||||||
dst[3] = vget_lane_u8(i8, 3);
|
|
||||||
|
|
||||||
#elif defined(SW_HAS_SSE41)
|
|
||||||
__m128 fvals = _mm_mul_ps(_mm_loadu_ps(color), _mm_set1_ps(255.0f));
|
|
||||||
__m128i i32 = _mm_cvttps_epi32(fvals);
|
|
||||||
__m128i i16 = _mm_packus_epi32(i32, i32);
|
|
||||||
__m128i i8 = _mm_packus_epi16(i16, i16);
|
|
||||||
_mm_storeu_si32(dst, i8);
|
|
||||||
|
|
||||||
#elif defined(SW_HAS_SSE2)
|
|
||||||
__m128 fvals = _mm_mul_ps(_mm_loadu_ps(color), _mm_set1_ps(255.0f));
|
|
||||||
__m128i i32 = _mm_cvttps_epi32(fvals);
|
|
||||||
__m128i i16 = _mm_packs_epi32(i32, i32);
|
|
||||||
__m128i i8 = _mm_packus_epi16(i16, i16);
|
|
||||||
_mm_storeu_si32(dst, i8);
|
|
||||||
|
|
||||||
#elif defined(SW_HAS_RVV)
|
|
||||||
// TODO: WARNING: Sample code generated by AI, needs testing and review
|
|
||||||
// REVIEW: It shouldn't perform so many operations; take inspiration from other versions
|
|
||||||
// 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
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Convert to unsigned integer (truncate toward zero)
|
|
||||||
vuint32m1_t vu32 = __riscv_vfcvt_xu_f_v_u32m1(vscaled, vl);
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sw_pixel_set_color_R32(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
static inline void sw_pixel_set_color_R32(void *SW_RESTRICT pixels, const float *SW_RESTRICT color, uint32_t offset)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user