Skip to content

Commit

Permalink
use extractBits
Browse files Browse the repository at this point in the history
  • Loading branch information
isplunke committed Sep 20, 2024
1 parent d076d31 commit 8209042
Showing 1 changed file with 114 additions and 37 deletions.
151 changes: 114 additions & 37 deletions DirectXTex/DirectXTexSwizzle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace
{
#ifdef __AVX2__
#define deposit_bits(v,m) _pdep_u32(v,m)
#define extract_bits(v,m) _pext_u32(v,m)
#else
// N3864 - A constexpr bitwise operations library for C++
// https://github.com/fmatthew5876/stdcxx-bitops
Expand All @@ -35,6 +36,19 @@ namespace
}
return res;
}
uint32_t extract_bits(uint32_t val, uint32_t mask)
{
uint32_t res = 0;
for (uint32_t bb = 1; mask !=0; bb += bb)
{
if (val & mask & -mask)
{
res |= bb;
}
mask &= (mask - 1);
}
return res;
}
#endif
}

Expand Down Expand Up @@ -68,20 +82,37 @@ HRESULT DirectX::StandardSwizzle(const Image& srcImage, bool toSwizzle, ScratchI
size_t height = IsCompressed(srcImage.format) ? (srcImage.height + 3) / 4 : srcImage.height;
size_t width = IsCompressed(srcImage.format) ? (srcImage.width + 3) / 4 : srcImage.width;

for (size_t y = 0; y < height; y++)
if (toSwizzle)
{
for (size_t x = 0; x < width; x++)
size_t rowPitch = srcImage.rowPitch;
for (size_t y = 0; y < height; y++)
{
uint32_t swizzleIndex = deposit_bits(x, xBytesMask) + deposit_bits(y, yBytesMask);
size_t swizzleOffset = swizzleIndex * bytesPerPixel;
for (size_t x = 0; x < width; x++)
{
uint32_t swizzleIndex = deposit_bits(x, xBytesMask) + deposit_bits(y, yBytesMask);
size_t swizzleOffset = swizzleIndex * bytesPerPixel;

size_t rowMajorOffset = y * srcImage.rowPitch + x * bytesPerPixel;
size_t rowMajorOffset = y * rowPitch + x * bytesPerPixel;

size_t sourceOffset = toSwizzle ? rowMajorOffset : swizzleOffset;
size_t destOffset = toSwizzle ? swizzleOffset : rowMajorOffset;
const uint8_t* sourcePixelPointer = sptr + rowMajorOffset;
uint8_t* destPixelPointer = dptr + swizzleOffset;
memcpy(destPixelPointer, sourcePixelPointer, bytesPerPixel);
}
}
}
else
{
size_t rowPitch = result.GetImages()[0].rowPitch;
for (size_t swizzleIndex = 0; swizzleIndex < (width * height); swizzleIndex++)
{
size_t swizzleOffset = swizzleIndex * bytesPerPixel;

const uint8_t* sourcePixelPointer = sptr + sourceOffset;
uint8_t* destPixelPointer = dptr + destOffset;
uint32_t destX = extract_bits(swizzleIndex, xBytesMask);
uint32_t destY = extract_bits(swizzleIndex, yBytesMask);
size_t rowMajorOffset = destY * rowPitch + destX * bytesPerPixel;

const uint8_t* sourcePixelPointer = sptr + swizzleOffset;
uint8_t* destPixelPointer = dptr + rowMajorOffset;
memcpy(destPixelPointer, sourcePixelPointer, bytesPerPixel);
}
}
Expand Down Expand Up @@ -124,20 +155,37 @@ HRESULT DirectX::StandardSwizzle(const Image* srcImages, size_t nimages, const T
uint32_t xBytesMask = 0b1010101010101010;
uint32_t yBytesMask = 0b0101010101010101;

for (size_t y = 0; y <height; y++)
if (toSwizzle)
{
for (size_t x = 0; x < width; x++)
size_t rowPitch = srcImages[imageIndex].rowPitch;
for (size_t y = 0; y < height; y++)
{
uint32_t swizzleIndex = deposit_bits(x, xBytesMask) + deposit_bits(y, yBytesMask);
size_t swizzleOffset = swizzleIndex * bytesPerPixel;
for (size_t x = 0; x < width; x++)
{
uint32_t swizzleIndex = deposit_bits(x, xBytesMask) + deposit_bits(y, yBytesMask);
size_t swizzleOffset = swizzleIndex * bytesPerPixel;

size_t rowMajorOffset = y * srcImages[0].rowPitch + x * bytesPerPixel;
size_t rowMajorOffset = y * rowPitch + x * bytesPerPixel;

size_t sourceOffset = toSwizzle ? rowMajorOffset : swizzleOffset;
size_t destOffset = toSwizzle ? swizzleOffset : rowMajorOffset;
const uint8_t* sourcePixelPointer = sptr + rowMajorOffset;
uint8_t* destPixelPointer = dptr + swizzleOffset;
memcpy(destPixelPointer, sourcePixelPointer, bytesPerPixel);
}
}
}
else
{
size_t rowPitch = result.GetImages()[imageIndex].rowPitch;
for (size_t swizzleIndex = 0; swizzleIndex < (width * height); swizzleIndex++)
{
size_t swizzleOffset = swizzleIndex * bytesPerPixel;

const uint8_t* sourcePixelPointer = sptr + sourceOffset;
uint8_t* destPixelPointer = dptr + destOffset;
uint32_t destX = extract_bits(swizzleIndex, xBytesMask);
uint32_t destY = extract_bits(swizzleIndex, yBytesMask);
size_t rowMajorOffset = destY * rowPitch + destX * bytesPerPixel;

const uint8_t* sourcePixelPointer = sptr + swizzleOffset;
uint8_t* destPixelPointer = dptr + rowMajorOffset;
memcpy(destPixelPointer, sourcePixelPointer, bytesPerPixel);
}
}
Expand Down Expand Up @@ -171,34 +219,63 @@ HRESULT DirectX::StandardSwizzle3D(const Image* srcImages, size_t depth, const T
uint32_t yBytesMask = 0b0100100100100100;
uint32_t zBytesMask = 0b0010010010010010;

for (size_t z = 0; z < depth; z++)
if (toSwizzle)
{
for (size_t y = 0; y < height; y++)
const Image* destImages = result.GetImages();
for (size_t z = 0; z < depth; z++)
{
for (size_t x = 0; x < width; x++)
size_t rowPitch = srcImages[z].rowPitch;
const uint8_t* sptr = srcImages[z].pixels;
if (!sptr)
return E_POINTER;
for (size_t y = 0; y < height; y++)
{
uint32_t swizzle3Dindex = deposit_bits(x, xBytesMask) + deposit_bits(y, yBytesMask) + deposit_bits(z, zBytesMask);
uint32_t swizzle2Dindex = swizzle3Dindex % (metadata.width * metadata.height);
uint32_t swizzleSlice = swizzle3Dindex / (metadata.width * metadata.height);
size_t swizzleOffset = swizzle2Dindex * bytesPerPixel;

size_t rowMajorOffset = y * srcImages[0].rowPitch + x * bytesPerPixel;
for (size_t x = 0; x < width; x++)
{
uint32_t swizzle3Dindex = deposit_bits(x, xBytesMask) + deposit_bits(y, yBytesMask) + deposit_bits(z, zBytesMask);
uint32_t swizzle2Dindex = swizzle3Dindex % (metadata.width * metadata.height);
uint32_t swizzleSlice = swizzle3Dindex / (metadata.width * metadata.height);
size_t swizzleOffset = swizzle2Dindex * bytesPerPixel;

size_t rowMajorOffset = y * rowPitch + x * bytesPerPixel;

uint8_t* dptr = destImages[swizzleSlice].pixels;
if (!dptr)
return E_POINTER;

const uint8_t* sourcePixelPointer = sptr + rowMajorOffset;
uint8_t* destPixelPointer = dptr + swizzleOffset;
memcpy(destPixelPointer, sourcePixelPointer, bytesPerPixel);
}
}
}
}
else
{
const Image* destImages = result.GetImages();
for (size_t z = 0; z < depth; z++)
{
const uint8_t* sptr = srcImages[z].pixels;
if (!sptr)
return E_POINTER;

size_t sourceOffset = toSwizzle ? rowMajorOffset : swizzleOffset;
uint32_t sourceSlice = toSwizzle ? z : swizzleSlice;
for (size_t swizzleIndex = 0; swizzleIndex < (width * height); swizzleIndex++)
{
size_t swizzleOffset = swizzleIndex * bytesPerPixel;
const uint8_t* sourcePixelPointer = sptr + swizzleOffset;

size_t destOffset = toSwizzle ? swizzleOffset : rowMajorOffset;
uint32_t destSlice = toSwizzle ? swizzleSlice : z;
size_t index3D = z * width * height + swizzleIndex;
uint32_t destX = extract_bits(index3D, xBytesMask);
uint32_t destY = extract_bits(index3D, yBytesMask);
uint32_t destZ = extract_bits(index3D, zBytesMask);
size_t rowPitch = destImages[z].rowPitch;
size_t rowMajorOffset = destY * rowPitch + destX * bytesPerPixel;

const uint8_t* sptr = srcImages[sourceSlice].pixels;
if (!sptr)
return E_POINTER;
uint8_t* dptr = result.GetImages()[destSlice].pixels;
uint8_t* dptr = destImages[destZ].pixels;
if (!dptr)
return E_POINTER;
uint8_t* destPixelPointer = dptr + rowMajorOffset;

const uint8_t* sourcePixelPointer = sptr + sourceOffset;
uint8_t* destPixelPointer = dptr + destOffset;
memcpy(destPixelPointer, sourcePixelPointer, bytesPerPixel);
}
}
Expand Down

0 comments on commit 8209042

Please sign in to comment.