summaryrefslogtreecommitdiff
path: root/bitmap_calls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'bitmap_calls.cpp')
-rw-r--r--bitmap_calls.cpp103
1 files changed, 85 insertions, 18 deletions
diff --git a/bitmap_calls.cpp b/bitmap_calls.cpp
index 09d1cb1..2031459 100644
--- a/bitmap_calls.cpp
+++ b/bitmap_calls.cpp
@@ -117,46 +117,113 @@ Bitmap_Clear(void *Buffer, uint16 Width, uint16 Height, uint16 BytesPerPixel)
bytes += ByteOffset;
}
}
-#if 0
-// 0 - original -> effect
-// 1 - effect -> original
+
static void
-CopyToBuffer(pixel_buffer *Raster, uint16 Which)
+Bitmap_CalcPackedDimensions(uint16 Width, uint16 Height, uint16 *WidthP, uint16 *HeightP) {
+ uint16 ExtraWidth = 4 - (Width % 4);
+ if (ExtraWidth == 4)
+ ExtraWidth = 0;
+ uint16 ExtraHeight = 4 - (Height % 4);
+ if (ExtraHeight == 4)
+ ExtraHeight = 0;
+ *WidthP = Width + ExtraWidth;
+ *HeightP = Height + ExtraHeight;
+}
+
+static uint16
+Bitmap_CalcByteOffset(uint16 BytesPerPixel) {
+ uint16 ByteOffset = BytesPerPixel;
+ if (InstructionMode == instruction_mode_avx)
+ ByteOffset = 8*BytesPerPixel;
+ if (InstructionMode == instruction_mode_sse)
+ ByteOffset = 4*BytesPerPixel;
+ return ByteOffset;
+}
+
+static uint64
+Bitmap_CalcUnpackedBytes(uint16 Width, uint16 Height, uint16 BytesPerPixel) {
+ uint64 TotalBytes = (uint64)Width*Height*BytesPerPixel;
+ return TotalBytes;
+}
+
+static uint64
+Bitmap_CalcTotalBytes(uint16 Width, uint16 Height, uint16 BytesPerPixel) {
+ uint16 WidthP, HeightP;
+ Bitmap_CalcPackedDimensions(Width, Height, &WidthP, &HeightP);
+ uint64 TotalBytes = (uint64)WidthP*HeightP*BytesPerPixel;
+ return TotalBytes;
+}
+
+// TODO(fox): Maybe turn this into a generic memory copy; we don't need to care
+// about pixels for any particular reason here.
+static void
+Bitmap_CopyToPointer(void *Input, void *Output, uint16 BytesPerPixel, uint64 TotalBytes)
{
- uint8 *Row, *Row2;
- if (Which == 0) {
- Row = ((uint8 *)Raster->OriginalBuffer);
- Row2 = ((uint8 *)Raster->EffectBuffer);
- } else {
- Row = ((uint8 *)Raster->EffectBuffer);
- Row2 = ((uint8 *)Raster->OriginalBuffer);
- }
+ uint8 *Row = (uint8 *)Input;
+ uint8 *Row2 = (uint8 *)Output;
uint64 bytes = 0;
- uint16 ByteOffset = Bitmap_CalculateByteOffset(BytesPerPixel);
- uint64 TotalBytes = Bitmap_CalculateTotalBytes(Width, Height, BytesPerPixel);
+ uint16 ByteOffset = Bitmap_CalcByteOffset(BytesPerPixel);
uint64 RemainderBytes = TotalBytes % ByteOffset;
while (bytes <= TotalBytes - RemainderBytes) {
uint8 *Pixel = (uint8 *)Row + bytes;
uint8 *Pixel2 = (uint8 *)Row2 + bytes;
- if (InstructionMode == instruction_mode_sse || InstructionMode == instruction_mode_avx) {
+ if (InstructionMode == instruction_mode_avx) {
+ __m256i OutputPixel = _mm256_loadu_si256((__m256i *)Pixel);
+ _mm256_storeu_si256((__m256i *)Pixel2, OutputPixel);
+ } else if (InstructionMode == instruction_mode_sse) {
__m128i OutputPixel = _mm_loadu_si128((__m128i *)Pixel);
_mm_storeu_si128((__m128i *)Pixel2, OutputPixel);
- bytes += 4*Raster->BytesPerPixel;
} else {
*(uint32 *)Pixel2 = *(uint32 *)Pixel;
- bytes += Raster->BytesPerPixel;
}
+ bytes += ByteOffset;
}
while (bytes <= TotalBytes) {
uint8 *Pixel = (uint8 *)Row + bytes;
uint8 *Pixel2 = (uint8 *)Row2 + bytes;
*(uint32 *)Pixel2 = *(uint32 *)Pixel;
- bytes += Raster->BytesPerPixel;
+ bytes += BytesPerPixel;
+ }
+}
+
+// This would be an easy SIMD if only AVX had a scatter call...
+// NOTE(fox): Only works with unpacked bitmaps for now.
+static void
+Bitmap_CalcHistogram(void *Data, void *Input, uint16 BytesPerPixel, uint64 TotalBytes)
+{
+ uint32 *Slot = (uint32 *)Data;
+ uint8 *Row = (uint8 *)Input;
+ uint64 bytes = 0;
+ uint16 ByteOffset = Bitmap_CalcByteOffset(BytesPerPixel);
+ uint64 RemainderBytes = TotalBytes % ByteOffset;
+
+ for (int i = 0; i < 256*5; i++) {
+ *(real32 *)((uint8 *)Slot + i*sizeof(real32)) = 0;
+ }
+
+ while (bytes <= TotalBytes) {
+ uint8 *Pixel = (uint8 *)Row + bytes;
+
+ uint8 A = (*(uint32 *)Pixel >> 24);
+ uint8 R = (*(uint32 *)Pixel >> 16);
+ uint8 G = (*(uint32 *)Pixel >> 8);
+ uint8 B = (*(uint32 *)Pixel >> 0);
+
+ uint8 Avg = (uint8)((real32)(R + G + B) / 3.0f);
+
+ *(real32 *)((uint8 *)Slot + Avg*sizeof(real32)) += 1;
+ *(real32 *)((uint8 *)Slot + (256 + R)*sizeof(real32)) += 1;
+ *(real32 *)((uint8 *)Slot + (256*2 + G)*sizeof(real32)) += 1;
+ *(real32 *)((uint8 *)Slot + (256*3 + B)*sizeof(real32)) += 1;
+ *(real32 *)((uint8 *)Slot + (256*4 + A)*sizeof(real32)) += 1;
+
+ bytes += BytesPerPixel;
}
}
+#if 0
static void
BitmapPackRGB(pixel_buffer *Buffer) {
Assert(Buffer->Pitch);