Experimental support for explicit mip levels

This commit is contained in:
leblane 2023-08-16 01:27:48 +03:00
parent 111547fee9
commit 4c9f5802dd

View file

@ -41,20 +41,20 @@ const std::map<std::string, std::tuple<std::string, int, vk::Format>> formats =
{"BC7_SRGB", {"8 bit RGBA - Good general purpose. 16 bytes per block.", 16, vk::Format::eBc7SrgbBlock}} {"BC7_SRGB", {"8 bit RGBA - Good general purpose. 16 bytes per block.", 16, vk::Format::eBc7SrgbBlock}}
}; };
const std::string usage = "[cube|array] <input> [input2, input3...] <output> <format> [fast|normal|slow|veryslow]"; const std::string usage = "[cube|array] <input> [input2, input3...] <output> <format> [fast|normal|slow|veryslow] [explicitmips]";
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
ISPCInit(); ISPCInit();
if (argc < 4) { if (argc < 4) {
std::cout << "Usage: " << argv[0] << " " << usage << std::endl; std::cerr << "Usage: " << argv[0] << " " << usage << std::endl;
std::cout << "Formats:" << std::endl; std::cerr << "Formats:" << std::endl;
for (auto & formatName : formatOrder) { for (auto & formatName : formatOrder) {
auto format = formats.at(formatName); auto format = formats.at(formatName);
std::cout << " " << formatName << " - " << std::get<0>(format) << std::endl; std::cerr << " " << formatName << " - " << std::get<0>(format) << std::endl;
} }
return 1; return -1;
} }
int numInputs = argc - 3; int numInputs = argc - 3;
@ -72,10 +72,19 @@ int main(int argc, char ** argv)
std::string speedString(argv[argc - 1]); std::string speedString(argv[argc - 1]);
std::string formatString; std::string formatString;
int speed = 2; int speed = 2;
bool explicitmips = false;
int formatPosition = -1;
if (speedString == "explicitmips") {
speedString = std::string(argv[argc - 2]);
numInputs -= 1;
explicitmips = true;
}
if (speedString == "fast" || speedString == "normal" || speedString == "slow" || speedString == "veryslow") { if (speedString == "fast" || speedString == "normal" || speedString == "slow" || speedString == "veryslow") {
formatString = std::string(argv[argc - 2]);
numInputs -= 1; numInputs -= 1;
formatPosition -= 1;
if (speedString == "slow") { if (speedString == "slow") {
speed = 1; speed = 1;
@ -86,29 +95,34 @@ int main(int argc, char ** argv)
} else { } else {
speed = 2; speed = 2;
} }
} else {
formatString = std::string(argv[argc - 1]);
} }
formatString = std::string(argv[argc + formatPosition]);
if (numInputs < 1) { if (numInputs < 1) {
std::cout << "Usage: " << argv[0] << usage << " " << std::endl; std::cerr << "Usage: " << argv[0] << usage << " " << std::endl;
return 1; return -1;
} }
if (option == "cube" && numInputs != 6) { if (option == "cube" && numInputs != 6) {
std::cout << "Cube maps must have 6 inputs." << std::endl; std::cerr << "Cube maps must have 6 inputs." << std::endl;
return 1; return -1;
} }
if (option == "array" && numInputs < 2) { if (option == "array" && numInputs < 2) {
std::cout << "Array maps must have at least 2 inputs." << std::endl; std::cerr << "Array maps must have at least 2 inputs." << std::endl;
return 1; return -1;
}
if (option == "array" && explicitmips) {
std::cerr << "Explicit mips are not supported for arrays." << std::endl;
return -1;
} }
if (formats.find(formatString) == formats.end()) { if (formats.find(formatString) == formats.end()) {
std::cout << "Invalid format: " << formatString << std::endl; std::cerr << "Invalid format: " << formatString << std::endl;
std::cout << usage << std::endl; std::cerr << usage << std::endl;
std::cout << "Formats:" << std::endl; std::cerr << "Formats:" << std::endl;
for (auto & formatName : formatOrder) { for (auto & formatName : formatOrder) {
auto format = formats.at(formatName); auto format = formats.at(formatName);
std::cout << " " << formatName << " - " << std::get<0>(format) << std::endl; std::cout << " " << formatName << " - " << std::get<0>(format) << std::endl;
@ -190,6 +204,40 @@ int main(int argc, char ** argv)
uint32_t levelCount; uint32_t levelCount;
if (explicitmips) {
int levelWidth = 0, levelHeight = 0;
for (int input = 0; input < numInputs; input++) {
std::cout << "Loading/scaling " << input << ": " << inputs[input] << std::endl;
if (hdr) {
hdrBufferA = stbi_loadf(inputs[input].c_str(), &width, &height, &channels, forcedChannels);
} else {
ldrBufferA = stbi_load(inputs[input].c_str(), &width, &height, &channels, forcedChannels);
}
if (input == 0) {
levelWidth = width;
levelHeight = height;
} else {
if (width != levelWidth || height != levelHeight) {
std::cout << "Input " << inputs[input] << " for level " << input << ", dimensions " << width << "x" << height << " do not match expected " << levelWidth << "x" << levelHeight << std::endl;
return -1;
}
}
if (hdr) {
hdrLevels[input].push_back(std::vector<float>(hdrBufferA, hdrBufferA + width * height * forcedChannels));
stbi_image_free(hdrBufferA);
} else {
ldrLevels[input].push_back(std::vector<uint8_t>(ldrBufferA, ldrBufferA + width * height * forcedChannels));
stbi_image_free(ldrBufferA);
}
levelWidth = std::max(1, (int)floorf((float)levelWidth / 2));
levelHeight = std::max(1, (int)floorf((float)levelHeight / 2));
}
} else {
for (int input = 0; input < numInputs; input++) { for (int input = 0; input < numInputs; input++) {
int level = 0; int level = 0;
@ -278,6 +326,7 @@ int main(int argc, char ** argv)
delete[] ldrBufferB; delete[] ldrBufferB;
} }
} }
}
bc6h_enc_settings bc6henc; bc6h_enc_settings bc6henc;
bc7_enc_settings bc7enc; bc7_enc_settings bc7enc;
@ -401,7 +450,6 @@ int main(int argc, char ** argv)
level++; level++;
} }
/* Compress */ /* Compress */
levelBlocksCompressed[input].resize(levelCount); levelBlocksCompressed[input].resize(levelCount);
for (unsigned int l = 0; l < levelCount; l++) { for (unsigned int l = 0; l < levelCount; l++) {