implement support for loading textures from uncompressed TGA files
This commit is contained in:
parent
65455ad471
commit
352958f031
3
Makefile
3
Makefile
@ -25,7 +25,7 @@ CFLAGS += -I./data
|
|||||||
CFLAGS += -I../SDL3-dist/include
|
CFLAGS += -I../SDL3-dist/include
|
||||||
CFLAGS += -fpic
|
CFLAGS += -fpic
|
||||||
|
|
||||||
#FLAGS += -fstack-protector -fstack-protector-all -fno-omit-frame-pointer -fsanitize=address
|
FLAGS += -fstack-protector -fstack-protector-all -fno-omit-frame-pointer -fsanitize=address
|
||||||
|
|
||||||
LDFLAGS += -lm
|
LDFLAGS += -lm
|
||||||
ifeq ($(UNAME),Linux)
|
ifeq ($(UNAME),Linux)
|
||||||
@ -42,6 +42,7 @@ OBJS = \
|
|||||||
src/file.o \
|
src/file.o \
|
||||||
src/pack.o \
|
src/pack.o \
|
||||||
src/dds/validate.o \
|
src/dds/validate.o \
|
||||||
|
src/tga/tga.o \
|
||||||
src/vulkan_helper.o \
|
src/vulkan_helper.o \
|
||||||
src/collada/scene/vulkan.o \
|
src/collada/scene/vulkan.o \
|
||||||
src/collada/scene.o \
|
src/collada/scene.o \
|
||||||
|
|||||||
Binary file not shown.
@ -10,4 +10,18 @@ struct DDS_FILE {
|
|||||||
|
|
||||||
namespace dds {
|
namespace dds {
|
||||||
DDS_FILE const * validate(void const * data, uint32_t size, uint32_t ** out_offsets, void ** out_data, uint32_t * out_size);
|
DDS_FILE const * validate(void const * data, uint32_t size, uint32_t ** out_offsets, void ** out_data, uint32_t * out_size);
|
||||||
|
|
||||||
|
static inline bool isDDSExtension(const char * filename, size_t length)
|
||||||
|
{
|
||||||
|
char a = filename[length - 4];
|
||||||
|
char b = filename[length - 3];
|
||||||
|
char c = filename[length - 2];
|
||||||
|
char d = filename[length - 1];
|
||||||
|
|
||||||
|
return
|
||||||
|
(a == '.') &&
|
||||||
|
(b == 'd' || b == 'D') &&
|
||||||
|
(c == 'd' || c == 'D') &&
|
||||||
|
(d == 's' || d == 'S');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
43
include/tga/tga.h
Normal file
43
include/tga/tga.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define PACKED __attribute__((packed))
|
||||||
|
|
||||||
|
namespace tga {
|
||||||
|
struct PACKED header {
|
||||||
|
uint8_t idLength;
|
||||||
|
uint8_t colorMapType;
|
||||||
|
uint8_t imageTypeCode;
|
||||||
|
struct PACKED {
|
||||||
|
uint16_t origin;
|
||||||
|
uint16_t length;
|
||||||
|
uint8_t depth;
|
||||||
|
} colorMap;
|
||||||
|
struct PACKED {
|
||||||
|
uint16_t xOrigin;
|
||||||
|
uint16_t yOrigin;
|
||||||
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
uint8_t bitsPerPixel;
|
||||||
|
} image;
|
||||||
|
uint8_t descriptor;
|
||||||
|
};
|
||||||
|
static_assert((sizeof (header)) == 18);
|
||||||
|
|
||||||
|
header const * validate(void const * data, uint32_t size, void ** outData, uint32_t * outSize);
|
||||||
|
|
||||||
|
static inline bool isTGAExtension(const char * filename, size_t length)
|
||||||
|
{
|
||||||
|
char a = filename[length - 4];
|
||||||
|
char b = filename[length - 3];
|
||||||
|
char c = filename[length - 2];
|
||||||
|
char d = filename[length - 1];
|
||||||
|
|
||||||
|
return
|
||||||
|
(a == '.') &&
|
||||||
|
(b == 't' || b == 'T') &&
|
||||||
|
(c == 'g' || c == 'G') &&
|
||||||
|
(d == 'a' || d == 'A');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef PACKED
|
||||||
@ -62,3 +62,14 @@ void createImageFromFilenameDDS(VkDevice device,
|
|||||||
VkImage * outImage,
|
VkImage * outImage,
|
||||||
VkDeviceMemory * outMemory,
|
VkDeviceMemory * outMemory,
|
||||||
VkImageView * outImageView);
|
VkImageView * outImageView);
|
||||||
|
|
||||||
|
void createImageFromFilenameTGA(VkDevice device,
|
||||||
|
VkQueue queue,
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkFence fence,
|
||||||
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
|
char const * const filename,
|
||||||
|
VkImage * outImage,
|
||||||
|
VkDeviceMemory * outMemory,
|
||||||
|
VkImageView * outImageView);
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include "vulkan_helper.h"
|
#include "vulkan_helper.h"
|
||||||
#include "dds/validate.h"
|
#include "dds/validate.h"
|
||||||
#include "dds/vulkan.h"
|
#include "dds/vulkan.h"
|
||||||
|
#include "tga/tga.h"
|
||||||
|
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
#include "new.h"
|
#include "new.h"
|
||||||
@ -670,16 +671,34 @@ namespace collada::scene {
|
|||||||
images = NewM<Image>(descriptor->images_count);
|
images = NewM<Image>(descriptor->images_count);
|
||||||
|
|
||||||
for (int i = 0; i < descriptor->images_count; i++) {
|
for (int i = 0; i < descriptor->images_count; i++) {
|
||||||
createImageFromFilenameDDS(device,
|
char const * filename = descriptor->images[i]->uri;
|
||||||
queue,
|
size_t length = strlen(filename);
|
||||||
commandBuffer,
|
if (dds::isDDSExtension(filename, length)) {
|
||||||
fence,
|
createImageFromFilenameDDS(device,
|
||||||
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
queue,
|
||||||
physicalDeviceMemoryProperties,
|
commandBuffer,
|
||||||
descriptor->images[i]->uri,
|
fence,
|
||||||
&images[i].image,
|
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
&images[i].memory,
|
physicalDeviceMemoryProperties,
|
||||||
&images[i].imageView);
|
filename,
|
||||||
|
&images[i].image,
|
||||||
|
&images[i].memory,
|
||||||
|
&images[i].imageView);
|
||||||
|
} else if (tga::isTGAExtension(filename, length)) {
|
||||||
|
createImageFromFilenameTGA(device,
|
||||||
|
queue,
|
||||||
|
commandBuffer,
|
||||||
|
fence,
|
||||||
|
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
filename,
|
||||||
|
&images[i].image,
|
||||||
|
&images[i].memory,
|
||||||
|
&images[i].imageView);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "filename: %s\n", filename);
|
||||||
|
ASSERT(false, "invalid image filename extension");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
|
|||||||
25
src/tga/tga.cpp
Normal file
25
src/tga/tga.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "tga/tga.h"
|
||||||
|
|
||||||
|
namespace tga {
|
||||||
|
header const * validate(void const * data, uint32_t size, void ** outData, uint32_t * outSize)
|
||||||
|
{
|
||||||
|
header const * const tga = (tga::header const *)data;
|
||||||
|
|
||||||
|
assert(tga->colorMapType == 0);
|
||||||
|
assert(tga->imageTypeCode == 2);
|
||||||
|
assert(tga->image.xOrigin == 0);
|
||||||
|
assert(tga->image.yOrigin == 0);
|
||||||
|
assert(tga->image.bitsPerPixel == 32);
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t bytesPerPixel = tga->image.bitsPerPixel / 8;
|
||||||
|
size_t imageOffset = (sizeof (header)) + tga->idLength;
|
||||||
|
*outData = (void *)(((size_t)data) + imageOffset);
|
||||||
|
*outSize = tga->image.width * tga->image.width * bytesPerPixel;
|
||||||
|
|
||||||
|
return tga;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "dds/validate.h"
|
#include "dds/validate.h"
|
||||||
#include "dds/vulkan.h"
|
#include "dds/vulkan.h"
|
||||||
|
#include "tga/tga.h"
|
||||||
|
|
||||||
#include "vulkan_helper.h"
|
#include "vulkan_helper.h"
|
||||||
|
|
||||||
@ -115,85 +116,25 @@ VkDeviceSize allocateFromMemoryRequirements2(VkDevice device,
|
|||||||
return memoryAllocateInfo.allocationSize;
|
return memoryAllocateInfo.allocationSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createImageFromFilenameDDS(VkDevice device,
|
// ddsFile->header.dwWidth
|
||||||
VkQueue queue,
|
// ddsFile->header.dwHeight
|
||||||
VkCommandBuffer commandBuffer,
|
// ddsFile->header.dwMipMapCount
|
||||||
VkFence fence,
|
// uint32_t * mipOffsets;
|
||||||
VkDeviceSize nonCoherentAtomSize,
|
|
||||||
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
void textureTransfer(VkDevice device,
|
||||||
char const * const filename,
|
VkQueue queue,
|
||||||
VkImage * outImage,
|
VkCommandBuffer commandBuffer,
|
||||||
VkDeviceMemory * outMemory,
|
VkFence fence,
|
||||||
VkImageView * outImageView)
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
|
uint32_t imageDataSize,
|
||||||
|
void * imageData,
|
||||||
|
VkImage image,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t levelCount,
|
||||||
|
uint32_t * levelOffsets)
|
||||||
{
|
{
|
||||||
uint32_t imageSize;
|
|
||||||
void const * imageStart = file::open(filename, &imageSize);
|
|
||||||
void * imageData;
|
|
||||||
uint32_t * mipOffsets;
|
|
||||||
uint32_t imageDataSize;
|
|
||||||
DDS_FILE const * ddsFile = dds::validate(imageStart, imageSize, &mipOffsets, &imageData, &imageDataSize);
|
|
||||||
|
|
||||||
VkFormat format = dds::dxgi_to_vulkan(ddsFile->header10.dxgiFormat);
|
|
||||||
|
|
||||||
// image
|
|
||||||
|
|
||||||
VkImage image;
|
|
||||||
VkImageCreateInfo imageCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
|
||||||
.imageType = VK_IMAGE_TYPE_2D,
|
|
||||||
.format = format,
|
|
||||||
.extent = {
|
|
||||||
.width = ddsFile->header.dwWidth,
|
|
||||||
.height = ddsFile->header.dwHeight,
|
|
||||||
.depth = 1
|
|
||||||
},
|
|
||||||
.mipLevels = ddsFile->header.dwMipMapCount,
|
|
||||||
.arrayLayers = 1,
|
|
||||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
|
||||||
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
|
||||||
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
|
||||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreateImage(device, &imageCreateInfo, nullptr, &image));
|
|
||||||
*outImage = image;
|
|
||||||
|
|
||||||
// image view
|
|
||||||
|
|
||||||
VkDeviceMemory imageMemory;
|
|
||||||
VkMemoryRequirements imageMemoryRequirements;
|
|
||||||
vkGetImageMemoryRequirements(device, image, &imageMemoryRequirements);
|
|
||||||
VkMemoryPropertyFlags imageMemoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT };
|
|
||||||
VkMemoryAllocateFlags imageMemoryAllocateFlags{ };
|
|
||||||
VkDeviceSize stride;
|
|
||||||
allocateFromMemoryRequirements(device,
|
|
||||||
nonCoherentAtomSize,
|
|
||||||
physicalDeviceMemoryProperties,
|
|
||||||
imageMemoryRequirements,
|
|
||||||
imageMemoryPropertyFlags,
|
|
||||||
imageMemoryAllocateFlags,
|
|
||||||
1,
|
|
||||||
&imageMemory,
|
|
||||||
&stride);
|
|
||||||
*outMemory = imageMemory;
|
|
||||||
VK_CHECK(vkBindImageMemory(device, image, imageMemory, 0));
|
|
||||||
|
|
||||||
VkImageView imageView;
|
|
||||||
VkImageViewCreateInfo textureViewCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
|
||||||
.image = image,
|
|
||||||
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
|
||||||
.format = format,
|
|
||||||
.subresourceRange{
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.levelCount = ddsFile->header.dwMipMapCount,
|
|
||||||
.layerCount = 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreateImageView(device, &textureViewCreateInfo, nullptr, &imageView));
|
|
||||||
*outImageView = imageView;
|
|
||||||
|
|
||||||
// texture transfer: source buffer
|
|
||||||
|
|
||||||
VkBuffer sourceBuffer{};
|
VkBuffer sourceBuffer{};
|
||||||
VkBufferCreateInfo sourceBufferCreateInfo{
|
VkBufferCreateInfo sourceBufferCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
@ -243,7 +184,7 @@ void createImageFromFilenameDDS(VkDevice device,
|
|||||||
.image = image,
|
.image = image,
|
||||||
.subresourceRange = {
|
.subresourceRange = {
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
.levelCount = ddsFile->header.dwMipMapCount,
|
.levelCount = levelCount,
|
||||||
.layerCount = 1
|
.layerCount = 1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -253,24 +194,23 @@ void createImageFromFilenameDDS(VkDevice device,
|
|||||||
.pImageMemoryBarriers = &imageBarrier
|
.pImageMemoryBarriers = &imageBarrier
|
||||||
};
|
};
|
||||||
vkCmdPipelineBarrier2(commandBuffer, &imageDependencyInfo);
|
vkCmdPipelineBarrier2(commandBuffer, &imageDependencyInfo);
|
||||||
VkBufferImageCopy * copyRegions = NewM<VkBufferImageCopy>(ddsFile->header.dwMipMapCount);
|
VkBufferImageCopy * copyRegions = NewM<VkBufferImageCopy>(levelCount);
|
||||||
for (uint32_t level = 0; level < ddsFile->header.dwMipMapCount; level++) {
|
for (uint32_t level = 0; level < levelCount; level++) {
|
||||||
copyRegions[level] = {
|
copyRegions[level] = {
|
||||||
.bufferOffset = mipOffsets[level],
|
.bufferOffset = levelOffsets[level],
|
||||||
.imageSubresource{
|
.imageSubresource{
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
.mipLevel = level,
|
.mipLevel = level,
|
||||||
.layerCount = 1
|
.layerCount = 1
|
||||||
},
|
},
|
||||||
.imageExtent{
|
.imageExtent{
|
||||||
.width = max(1u, ddsFile->header.dwWidth >> level),
|
.width = max(1u, width >> level),
|
||||||
.height = max(1u, ddsFile->header.dwHeight >> level),
|
.height = max(1u, height >> level),
|
||||||
.depth = 1
|
.depth = 1
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
vkCmdCopyBufferToImage(commandBuffer, sourceBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, ddsFile->header.dwMipMapCount, copyRegions);
|
vkCmdCopyBufferToImage(commandBuffer, sourceBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, levelCount, copyRegions);
|
||||||
free(mipOffsets);
|
|
||||||
free(copyRegions);
|
free(copyRegions);
|
||||||
|
|
||||||
VkImageMemoryBarrier2 readBarrier{
|
VkImageMemoryBarrier2 readBarrier{
|
||||||
@ -282,7 +222,7 @@ void createImageFromFilenameDDS(VkDevice device,
|
|||||||
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
.newLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
|
.newLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
|
||||||
.image = image,
|
.image = image,
|
||||||
.subresourceRange = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .levelCount = ddsFile->header.dwMipMapCount, .layerCount = 1 }
|
.subresourceRange = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .levelCount = levelCount, .layerCount = 1 }
|
||||||
};
|
};
|
||||||
VkDependencyInfo readDependencyInfo{
|
VkDependencyInfo readDependencyInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||||
@ -305,3 +245,175 @@ void createImageFromFilenameDDS(VkDevice device,
|
|||||||
vkDestroyBuffer(device, sourceBuffer, nullptr);
|
vkDestroyBuffer(device, sourceBuffer, nullptr);
|
||||||
vkFreeMemory(device, sourceBufferMemory, nullptr);
|
vkFreeMemory(device, sourceBufferMemory, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createImage(VkDevice device,
|
||||||
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
|
VkFormat format,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t levelCount,
|
||||||
|
VkImage * outImage,
|
||||||
|
VkDeviceMemory * outMemory,
|
||||||
|
VkImageView * outImageView)
|
||||||
|
{
|
||||||
|
// image
|
||||||
|
|
||||||
|
VkImage image;
|
||||||
|
VkImageCreateInfo imageCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||||
|
.imageType = VK_IMAGE_TYPE_2D,
|
||||||
|
.format = format,
|
||||||
|
.extent = {
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
.depth = 1
|
||||||
|
},
|
||||||
|
.mipLevels = levelCount,
|
||||||
|
.arrayLayers = 1,
|
||||||
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||||
|
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
||||||
|
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateImage(device, &imageCreateInfo, nullptr, &image));
|
||||||
|
*outImage = image;
|
||||||
|
|
||||||
|
// image view
|
||||||
|
|
||||||
|
VkDeviceMemory imageMemory;
|
||||||
|
VkMemoryRequirements imageMemoryRequirements;
|
||||||
|
vkGetImageMemoryRequirements(device, image, &imageMemoryRequirements);
|
||||||
|
VkMemoryPropertyFlags imageMemoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT };
|
||||||
|
VkMemoryAllocateFlags imageMemoryAllocateFlags{ };
|
||||||
|
VkDeviceSize stride;
|
||||||
|
allocateFromMemoryRequirements(device,
|
||||||
|
nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
imageMemoryRequirements,
|
||||||
|
imageMemoryPropertyFlags,
|
||||||
|
imageMemoryAllocateFlags,
|
||||||
|
1,
|
||||||
|
&imageMemory,
|
||||||
|
&stride);
|
||||||
|
*outMemory = imageMemory;
|
||||||
|
VK_CHECK(vkBindImageMemory(device, image, imageMemory, 0));
|
||||||
|
|
||||||
|
VkImageView imageView;
|
||||||
|
VkImageViewCreateInfo textureViewCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||||
|
.image = image,
|
||||||
|
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
||||||
|
.format = format,
|
||||||
|
.subresourceRange{
|
||||||
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
.levelCount = levelCount,
|
||||||
|
.layerCount = 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateImageView(device, &textureViewCreateInfo, nullptr, &imageView));
|
||||||
|
*outImageView = imageView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createImageFromFilenameDDS(VkDevice device,
|
||||||
|
VkQueue queue,
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkFence fence,
|
||||||
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
|
char const * const filename,
|
||||||
|
VkImage * outImage,
|
||||||
|
VkDeviceMemory * outMemory,
|
||||||
|
VkImageView * outImageView)
|
||||||
|
{
|
||||||
|
uint32_t imageSize;
|
||||||
|
void const * imageStart = file::open(filename, &imageSize);
|
||||||
|
void * imageData;
|
||||||
|
uint32_t * levelOffsets;
|
||||||
|
uint32_t imageDataSize;
|
||||||
|
DDS_FILE const * ddsFile = dds::validate(imageStart, imageSize, &levelOffsets, &imageData, &imageDataSize);
|
||||||
|
|
||||||
|
VkFormat format = dds::dxgi_to_vulkan(ddsFile->header10.dxgiFormat);
|
||||||
|
uint32_t width = ddsFile->header.dwWidth;
|
||||||
|
uint32_t height = ddsFile->header.dwHeight;
|
||||||
|
uint32_t levelCount = ddsFile->header.dwMipMapCount;
|
||||||
|
|
||||||
|
createImage(device,
|
||||||
|
nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
format,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
levelCount,
|
||||||
|
outImage,
|
||||||
|
outMemory,
|
||||||
|
outImageView);
|
||||||
|
|
||||||
|
textureTransfer(device,
|
||||||
|
queue,
|
||||||
|
commandBuffer,
|
||||||
|
fence,
|
||||||
|
nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
imageDataSize,
|
||||||
|
imageData,
|
||||||
|
*outImage,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
levelCount,
|
||||||
|
levelOffsets);
|
||||||
|
|
||||||
|
free(levelOffsets);
|
||||||
|
// imageData is not malloc'ed, it is a pointer to file:: data, which is also not malloc'ed
|
||||||
|
}
|
||||||
|
|
||||||
|
void createImageFromFilenameTGA(VkDevice device,
|
||||||
|
VkQueue queue,
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkFence fence,
|
||||||
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
|
char const * const filename,
|
||||||
|
VkImage * outImage,
|
||||||
|
VkDeviceMemory * outMemory,
|
||||||
|
VkImageView * outImageView)
|
||||||
|
{
|
||||||
|
uint32_t imageSize;
|
||||||
|
void const * imageStart = file::open(filename, &imageSize);
|
||||||
|
void * imageData;
|
||||||
|
uint32_t imageDataSize;
|
||||||
|
tga::header const * tga = tga::validate(imageStart, imageSize, &imageData, &imageDataSize);
|
||||||
|
|
||||||
|
VkFormat format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
uint32_t width = tga->image.width;
|
||||||
|
uint32_t height = tga->image.height;
|
||||||
|
uint32_t levelCount = 1;
|
||||||
|
uint32_t levelOffset = 0;
|
||||||
|
|
||||||
|
createImage(device,
|
||||||
|
nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
format,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
levelCount,
|
||||||
|
outImage,
|
||||||
|
outMemory,
|
||||||
|
outImageView);
|
||||||
|
|
||||||
|
textureTransfer(device,
|
||||||
|
queue,
|
||||||
|
commandBuffer,
|
||||||
|
fence,
|
||||||
|
nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
imageDataSize,
|
||||||
|
imageData,
|
||||||
|
*outImage,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
levelCount,
|
||||||
|
&levelOffset);
|
||||||
|
|
||||||
|
// imageData is not malloc'ed, it is a pointer to file:: data, which is also not malloc'ed
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user