Skip to content

Instantly share code, notes, and snippets.

@JCash
Created August 11, 2019 08:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JCash/d4835190cb9f985fd262274872a06934 to your computer and use it in GitHub Desktop.
Save JCash/d4835190cb9f985fd262274872a06934 to your computer and use it in GitHub Desktop.
Atrix256's debug container test
// the size of the image that is made into mips
#define IMAGE_SIZE() 512
typedef float ChannelType;
#include <stdio.h>
#include <array>
#include <vector>
#include <chrono>
#include "array.h"
struct ScopedTimer
{
ScopedTimer(const char* label) : m_label(label)
{
m_start = std::chrono::high_resolution_clock::now();
}
~ScopedTimer()
{
std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(end - m_start);
printf("%s: %f ms\n", m_label, time_span.count() * 1000.0f);
}
const char* m_label;
std::chrono::high_resolution_clock::time_point m_start;
};
// calculate the total number of pixels needed to hold the image of size IMAGE_SIZE() as well as all the mips
constexpr size_t TotalPixelsMipped()
{
size_t ret = 0;
size_t size = IMAGE_SIZE();
while (size)
{
ret += size * size;
size /= 2;
}
return ret;
}
constexpr size_t TotalChannelsMipped()
{
// RGBA
return TotalPixelsMipped() * 4;
}
constexpr size_t NumMips()
{
size_t ret = 0;
size_t size = IMAGE_SIZE();
while (size)
{
ret++;
size /= 2;
}
return ret;
}
void GetMipInfo(size_t desiredMipIndex, size_t& offset, size_t& width)
{
offset = 0;
width = IMAGE_SIZE();
for (size_t mipIndex = 0; mipIndex < desiredMipIndex; ++mipIndex)
{
offset += width * width * 4;
width /= 2;
}
}
template<typename T>
void MakeMip(T& image, size_t mipIndex)
{
size_t srcOffset;
size_t srcWidth;
GetMipInfo(mipIndex - 1, srcOffset, srcWidth);
size_t destOffset;
size_t destWidth;
GetMipInfo(mipIndex, destOffset, destWidth);
for (size_t destY = 0; destY < destWidth; ++destY)
{
for (size_t destX = 0; destX < destWidth; ++destX)
{
for (size_t channel = 0; channel < 4; ++channel)
{
// 2x2 box filter source mip pixels
float value =
float(image[((destY * 2 + 0) * srcWidth + destX * 2 + 0) * 4 + srcOffset] + channel) +
float(image[((destY * 2 + 0) * srcWidth + destX * 2 + 1) * 4 + srcOffset] + channel) +
float(image[((destY * 2 + 1) * srcWidth + destX * 2 + 0) * 4 + srcOffset] + channel) +
float(image[((destY * 2 + 1) * srcWidth + destX * 2 + 1) * 4 + srcOffset] + channel);
image[destOffset] = ChannelType(value / 4.0f);
destOffset++;
}
}
}
}
template<typename T>
void MakeMips(T& image)
{
size_t mipCount = NumMips();
for (size_t mipIndex = 1; mipIndex < mipCount; ++mipIndex)
MakeMip(image, mipIndex);
}
template<typename T>
void InitImage(T& image)
{
memset(&image[0], 0, TotalChannelsMipped() * sizeof(float));
// It doesn't matter what we put into the image since we aren't ever looking at it, but initializing it anyhow.
size_t i = 0;
for (size_t y = 0; y < IMAGE_SIZE(); ++y)
{
for (size_t x = 0; x < IMAGE_SIZE(); ++x)
{
image[i * 4 + 0] = ChannelType(x % 256);
image[i * 4 + 1] = ChannelType(y % 256);
image[i * 4 + 2] = ChannelType(0);
image[i * 4 + 3] = ChannelType(255);
i++;
}
}
}
int main(void)
{
// std::array
// dynamically allocated to avoid a stack overflow
{
printf("std::array:\n");
ScopedTimer timer("Full");
std::array<ChannelType, TotalChannelsMipped()>* array_ptr = new std::array<ChannelType, TotalChannelsMipped()>;
std::array<ChannelType, TotalChannelsMipped()>& array = *array_ptr;
{
ScopedTimer timer("InitImage");
InitImage(array);
}
{
ScopedTimer timer("MakeMips");
array[array.size()+1] = ChannelType(127);
MakeMips(array);
}
delete array_ptr;
}
printf("\n");
// std::vector
{
printf("std::vector:\n");
ScopedTimer timer("Full");
std::vector<ChannelType> vector;
{
ScopedTimer timer("InitImage");
vector.resize(TotalChannelsMipped());
InitImage(vector);
}
{
ScopedTimer timer("MakeMips");
vector[TotalChannelsMipped()+1] = ChannelType(127);
MakeMips(vector);
}
}
printf("\n");
// custom array
{
printf("jc::array:\n");
ScopedTimer timer("Full");
jc::Array<ChannelType> customarray;
{
ScopedTimer timer("InitImage");
customarray.SetCapacity(TotalChannelsMipped());
customarray.SetSize(customarray.Capacity());
InitImage(customarray);
}
{
ScopedTimer timer("MakeMips");
MakeMips(customarray);
}
}
printf("\n");
// c array
{
printf("\nc array:\n");
ScopedTimer timer("Full");
ChannelType* carray = nullptr;
{
ScopedTimer timer("InitImage");
carray = (ChannelType*)malloc(sizeof(ChannelType)*TotalChannelsMipped());
InitImage(carray);
}
{
ScopedTimer timer("MakeMips");
MakeMips(carray);
}
free(carray);
}
printf("\n");
system("pause");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment