1#include "TextureData.h"
9 const char* getResourceDimensionsName(ResourceDimensions target)
11 static const char* names[] =
28 static_assert(
sizeof(names) ==
sizeof(names[0]) * (size_t(ResourceDimensions::ResourceDimensions_Size) + 1));
29 return names[size_t(target) < size_t(ResourceDimensions::ResourceDimensions_Size) ? size_t(target) : size_t(ResourceDimensions::ResourceDimensions_Size)];
32 size_t getBlockSize(TextureFormat format)
37 TextureExtent getBlockExtent(TextureFormat format)
42 size_t getComponents(TextureFormat format)
44 return getFormatInfo(format)->
elements;
47 uint32_t getMipLevels(
const uint32_t width,
const uint32_t height)
49 return 1 +
static_cast<uint32_t
>(std::floor(std::log2((
double)std::max(width, height))));
52 uint32_t getMipSize(uint32_t size, uint32_t level)
54 return std::max(1u, size /
static_cast<uint32_t
>(std::pow(2, level)));
59 size_t size = getBlockSize(format) * width * height * depth * faces * layers;
72 blockSize(getBlockSize(format)),
73 blockExtent(getBlockExtent(format)),
74 blockCount(
TextureExtent{ (extent.width + getBlockExtent(format).width - 1) / getBlockExtent(format).width, (extent.height + getBlockExtent(format).height - 1) / getBlockExtent(format).height, extent.depth / getBlockExtent(format).depth }),
81 TextureData::TextureData(
const void * data, TextureExtent extent,
size_t layers,
size_t faces,
size_t levels, TextureFormat format) :
82 TextureData(extent, layers, faces, levels, format)
87 void TextureData::init(TextureExtent extent,
size_t layers,
size_t faces,
size_t levels, TextureFormat format, Memory::Allocator * allocator)
89 this->format = format;
90 this->layers = layers;
92 this->levels = levels;
93 blockSize = getBlockSize(format);
94 blockExtent = getBlockExtent(format);
95 blockCount = TextureExtent{ (extent.width + getBlockExtent(format).width -1) / getBlockExtent(format).width, (extent.height + getBlockExtent(format).height - 1) / getBlockExtent(format).height, extent.depth / getBlockExtent(format).depth };
96 this->extent = extent;
97 data.reset(getSize(), allocator);
99 initOffsets(data.data());
102 void TextureData::initExternal(intptr_t external)
104 externalHandle = external;
107 void TextureData::initExternal(
const void ** data,
size_t layers,
size_t faces,
size_t levels)
109 assert(this->layers == layers &&
"External data not compatible.");
110 assert(this->faces == faces &&
"External data not compatible.");
111 assert(this->levels == levels &&
"External data not compatible.");
113 size_t numOffsets = layers * faces * levels;
114 for (
size_t i = 0; i < numOffsets; ++i) {
115 offsets.push_back(data[i]);
119 void TextureData::clearData()
121 format = Cogs::TextureFormat::Unknown;
133 data.resize(0,
false,
true);
137 void * TextureData::getData(
size_t layer,
size_t face,
size_t level)
139 assert(data.size() &&
"Cannot modify external data.");
141 return static_cast<uint8_t *
>(data.data()) + getOffset(layer, face, level);
144 const void * TextureData::getData(
size_t layer,
size_t face,
size_t level)
const
146 return offsets[layer * (faces * levels) + face * levels + level];
149 size_t TextureData::getPitch(
size_t level)
const
151 return blockSize * getBlockCount(level).width;
154 size_t TextureData::getLevelSize(
size_t level)
const
156 const auto levelBlocks = getBlockCount(level);
158 return blockSize * levelBlocks.width * levelBlocks.height * levelBlocks.depth;
161 size_t TextureData::getFaceSize(
size_t baseLevel,
size_t maxLevel)
const
164 for (
size_t i = baseLevel; i <= maxLevel; ++i) {
165 faceSize += getLevelSize(i);
170 size_t TextureData::getLayerSize(
size_t baseFace,
size_t maxFace,
size_t baseLevel,
size_t maxLevel)
const
172 return getFaceSize(baseLevel, maxLevel) * (maxFace - baseFace + 1);
175 size_t TextureData::getSize()
const
177 return layers * getLayerSize(0, faces - 1, 0, levels - 1);
180 TextureExtent TextureData::getExtent(
size_t level)
const
182 return TextureExtent{
183 std::max(1u, extent.width >> (uint32_t)level),
184 std::max(1u, extent.height >> (uint32_t)level),
185 std::max(1u, extent.depth >> (uint32_t)level),
189 TextureExtent TextureData::getBlockCount(
size_t level)
const
191 return TextureExtent{
192 std::max(1u, ((blockCount.width + (1 << (uint32_t)level) - 1 )) >> (uint32_t)level),
193 std::max(1u, ((blockCount.height + (1 << (uint32_t)level) - 1 )) >> (uint32_t)level),
194 std::max(1u, ((blockCount.depth + (1 << (uint32_t)level) - 1 )) >> (uint32_t)level),
198 size_t TextureData::getOffset(
size_t layer,
size_t face,
size_t level)
const
200 auto layerSize = getLayerSize(0, faces - 1, 0, levels - 1);
201 auto faceSize = getFaceSize(0, levels - 1);
203 size_t offset = layer * layerSize + face * faceSize;
205 for (
size_t i = 0; i < level; ++i) {
206 offset += getLevelSize(i);
212 void TextureData::initOffsets(
const void * data)
214 for (
size_t i = 0; i < layers; ++i) {
215 for (
size_t j = 0; j < faces; ++j) {
216 for (
size_t k = 0; k < levels; ++k) {
217 offsets.push_back(
static_cast<const uint8_t *
>(data) + getOffset(i, j, k));
Base allocator implementation.
Contains all Cogs related functionality.
COGSRENDERING_DLL_API size_t estimateMemorySize() const
Attempts to estimate the amount of memory a texture with these attributes will require.