collada: load scene textures
This commit is contained in:
parent
635e27b03f
commit
e9c0c9627c
2
Makefile
2
Makefile
@ -41,7 +41,7 @@ OBJS = \
|
|||||||
src/volk/volk.o \
|
src/volk/volk.o \
|
||||||
src/file.o \
|
src/file.o \
|
||||||
src/pack.o \
|
src/pack.o \
|
||||||
src/dds_validate.o \
|
src/dds/validate.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 \
|
||||||
|
|||||||
BIN
checker.dds
BIN
checker.dds
Binary file not shown.
BIN
data/scenes/shadow_test/images/0_leaf_white.dds
Normal file
BIN
data/scenes/shadow_test/images/0_leaf_white.dds
Normal file
Binary file not shown.
BIN
data/scenes/shadow_test/images/0_leaf_white.png
Normal file
BIN
data/scenes/shadow_test/images/0_leaf_white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
@ -6,14 +6,24 @@
|
|||||||
<authoring_tool>OpenCOLLADA for 3ds Max; Version: 1.6; Revision: 68</authoring_tool>
|
<authoring_tool>OpenCOLLADA for 3ds Max; Version: 1.6; Revision: 68</authoring_tool>
|
||||||
<source_data>file:///C:/Users/bilbo/Documents/wood/scenes/shadow_test.max</source_data>
|
<source_data>file:///C:/Users/bilbo/Documents/wood/scenes/shadow_test.max</source_data>
|
||||||
</contributor>
|
</contributor>
|
||||||
<created>2026-04-14T19:52:07</created>
|
<created>2026-04-15T19:19:21</created>
|
||||||
<modified>2026-04-14T19:52:07</modified>
|
<modified>2026-04-15T19:19:21</modified>
|
||||||
<unit name="inch" meter="0.0254"/>
|
<unit name="inch" meter="0.0254"/>
|
||||||
<up_axis>Z_UP</up_axis>
|
<up_axis>Z_UP</up_axis>
|
||||||
</asset>
|
</asset>
|
||||||
<library_effects>
|
<library_effects>
|
||||||
<effect id="PlaneMaterial">
|
<effect id="PlaneMaterial">
|
||||||
<profile_COMMON>
|
<profile_COMMON>
|
||||||
|
<newparam sid="leaf_white_png-surface">
|
||||||
|
<surface type="2D">
|
||||||
|
<init_from>leaf_white_png</init_from>
|
||||||
|
</surface>
|
||||||
|
</newparam>
|
||||||
|
<newparam sid="leaf_white_png-sampler">
|
||||||
|
<sampler2D>
|
||||||
|
<source>leaf_white_png-surface</source>
|
||||||
|
</sampler2D>
|
||||||
|
</newparam>
|
||||||
<technique sid="common">
|
<technique sid="common">
|
||||||
<blinn>
|
<blinn>
|
||||||
<emission>
|
<emission>
|
||||||
@ -23,7 +33,7 @@
|
|||||||
<color>0.6627451 0.5882353 0.6196079 1</color>
|
<color>0.6627451 0.5882353 0.6196079 1</color>
|
||||||
</ambient>
|
</ambient>
|
||||||
<diffuse>
|
<diffuse>
|
||||||
<color>0.6627451 0.5882353 0.6196079 1</color>
|
<texture texture="leaf_white_png-sampler" texcoord="CHANNEL1"/>
|
||||||
</diffuse>
|
</diffuse>
|
||||||
<specular>
|
<specular>
|
||||||
<color>0 0 0 1</color>
|
<color>0 0 0 1</color>
|
||||||
@ -677,6 +687,11 @@
|
|||||||
</extra>
|
</extra>
|
||||||
</light>
|
</light>
|
||||||
</library_lights>
|
</library_lights>
|
||||||
|
<library_images>
|
||||||
|
<image id="leaf_white_png">
|
||||||
|
<init_from>./images/0_leaf_white.png</init_from>
|
||||||
|
</image>
|
||||||
|
</library_images>
|
||||||
<library_visual_scenes>
|
<library_visual_scenes>
|
||||||
<visual_scene id="MaxScene">
|
<visual_scene id="MaxScene">
|
||||||
<node name="EnvironmentAmbientLight">
|
<node name="EnvironmentAmbientLight">
|
||||||
@ -686,7 +701,9 @@
|
|||||||
<instance_geometry url="#geom-Plane">
|
<instance_geometry url="#geom-Plane">
|
||||||
<bind_material>
|
<bind_material>
|
||||||
<technique_common>
|
<technique_common>
|
||||||
<instance_material symbol="PlaneMaterial" target="#PlaneMaterial-material"/>
|
<instance_material symbol="PlaneMaterial" target="#PlaneMaterial-material">
|
||||||
|
<bind_vertex_input semantic="CHANNEL1" input_semantic="TEXCOORD" input_set="0"/>
|
||||||
|
</instance_material>
|
||||||
</technique_common>
|
</technique_common>
|
||||||
</bind_material>
|
</bind_material>
|
||||||
</instance_geometry>
|
</instance_geometry>
|
||||||
|
|||||||
@ -1747,7 +1747,13 @@ channel const node_channel_node_camera001_matrix = {
|
|||||||
.target_attribute = target_attribute::ALL,
|
.target_attribute = target_attribute::ALL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// leaf_white_png
|
||||||
|
image const image_leaf_white_png = {
|
||||||
|
.uri = "data/scenes/shadow_test/images/0_leaf_white.dds"
|
||||||
|
};
|
||||||
|
|
||||||
image const * const images[] = {
|
image const * const images[] = {
|
||||||
|
&image_leaf_white_png,
|
||||||
};
|
};
|
||||||
|
|
||||||
effect const effect_planematerial = {
|
effect const effect_planematerial = {
|
||||||
@ -1762,8 +1768,8 @@ effect const effect_planematerial = {
|
|||||||
.color = {0.6627451f, 0.5882353f, 0.6196079f, 1.0f},
|
.color = {0.6627451f, 0.5882353f, 0.6196079f, 1.0f},
|
||||||
},
|
},
|
||||||
.diffuse = {
|
.diffuse = {
|
||||||
.type = color_or_texture_type::COLOR,
|
.type = color_or_texture_type::TEXTURE,
|
||||||
.color = {0.6627451f, 0.5882353f, 0.6196079f, 1.0f},
|
.texture = { .image_index = 0 }, // leaf_white_png
|
||||||
},
|
},
|
||||||
.specular = {
|
.specular = {
|
||||||
.type = color_or_texture_type::COLOR,
|
.type = color_or_texture_type::COLOR,
|
||||||
@ -2215,7 +2221,7 @@ instance_material const instance_geometry_instance_materials_node_plane_0[] = {
|
|||||||
|
|
||||||
.emission = { .input_set = -1 },
|
.emission = { .input_set = -1 },
|
||||||
.ambient = { .input_set = -1 },
|
.ambient = { .input_set = -1 },
|
||||||
.diffuse = { .input_set = -1 },
|
.diffuse = { .input_set = 0 },
|
||||||
.specular = { .input_set = -1 },
|
.specular = { .input_set = -1 },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -2283,8 +2289,8 @@ instance_light const instance_lights_node_camera001_target[] = {
|
|||||||
|
|
||||||
channel const * const node_channels_node_camera001_target[] = {
|
channel const * const node_channels_node_camera001_target[] = {
|
||||||
&node_channel_node_camera001_target_translation_z,
|
&node_channel_node_camera001_target_translation_z,
|
||||||
&node_channel_node_camera001_target_translation_y,
|
|
||||||
&node_channel_node_camera001_target_translation_x,
|
&node_channel_node_camera001_target_translation_x,
|
||||||
|
&node_channel_node_camera001_target_translation_y,
|
||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_camera001_target = {
|
node const node_node_camera001_target = {
|
||||||
@ -2570,9 +2576,9 @@ instance_light const instance_lights_node_lighthelper[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
channel const * const node_channels_node_lighthelper[] = {
|
channel const * const node_channels_node_lighthelper[] = {
|
||||||
&node_channel_node_lighthelper_translation_z,
|
|
||||||
&node_channel_node_lighthelper_translation_y,
|
|
||||||
&node_channel_node_lighthelper_translation_x,
|
&node_channel_node_lighthelper_translation_x,
|
||||||
|
&node_channel_node_lighthelper_translation_y,
|
||||||
|
&node_channel_node_lighthelper_translation_z,
|
||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_lighthelper = {
|
node const node_node_lighthelper = {
|
||||||
@ -2759,9 +2765,9 @@ instance_light const instance_lights_node_camerahelper[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
channel const * const node_channels_node_camerahelper[] = {
|
channel const * const node_channels_node_camerahelper[] = {
|
||||||
|
&node_channel_node_camerahelper_translation_z,
|
||||||
&node_channel_node_camerahelper_translation_x,
|
&node_channel_node_camerahelper_translation_x,
|
||||||
&node_channel_node_camerahelper_translation_y,
|
&node_channel_node_camerahelper_translation_y,
|
||||||
&node_channel_node_camerahelper_translation_z,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_camerahelper = {
|
node const node_node_camerahelper = {
|
||||||
|
|||||||
@ -2,8 +2,7 @@ shader/triangle.spv
|
|||||||
shader/collada.spv
|
shader/collada.spv
|
||||||
data/scenes/shadow_test/shadow_test.vtx
|
data/scenes/shadow_test/shadow_test.vtx
|
||||||
data/scenes/shadow_test/shadow_test.idx
|
data/scenes/shadow_test/shadow_test.idx
|
||||||
|
data/scenes/shadow_test/images/0_leaf_white.dds
|
||||||
checker.idx
|
checker.idx
|
||||||
checker.vtx
|
checker.vtx
|
||||||
checker.data
|
|
||||||
checker.dds
|
|
||||||
sprite.data
|
sprite.data
|
||||||
|
|||||||
@ -30,9 +30,17 @@ namespace collada::scene {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct vulkan {
|
struct vulkan {
|
||||||
|
static constexpr uint32_t maxFrames = 2;
|
||||||
|
static constexpr uint32_t perFrameDescriptorCount = 2;
|
||||||
|
static constexpr uint32_t constantDescriptorCount = 1;
|
||||||
|
static constexpr uint32_t uniformBufferDescriptorCount = maxFrames * perFrameDescriptorCount + constantDescriptorCount;
|
||||||
|
static constexpr uint32_t descriptorCount = uniformBufferDescriptorCount + 2;
|
||||||
|
|
||||||
// externally initialized, opaque handle
|
// externally initialized, opaque handle
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
VkDevice device;
|
VkDevice device;
|
||||||
|
VkQueue queue;
|
||||||
|
VkCommandPool commandPool;
|
||||||
// externally initialized, structures
|
// externally initialized, structures
|
||||||
VkPhysicalDeviceProperties physicalDeviceProperties;
|
VkPhysicalDeviceProperties physicalDeviceProperties;
|
||||||
VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties;
|
VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties;
|
||||||
@ -56,16 +64,18 @@ namespace collada::scene {
|
|||||||
} vertexIndex;
|
} vertexIndex;
|
||||||
|
|
||||||
VkDescriptorPool descriptorPool{ VK_NULL_HANDLE };
|
VkDescriptorPool descriptorPool{ VK_NULL_HANDLE };
|
||||||
static constexpr uint32_t maxFrames = 2;
|
|
||||||
static constexpr uint32_t perFrameDescriptorCount = 2;
|
|
||||||
static constexpr uint32_t constantDescriptorCount = 1;
|
|
||||||
static constexpr uint32_t uniformBufferDescriptorCount = maxFrames * perFrameDescriptorCount + constantDescriptorCount;
|
|
||||||
static constexpr uint32_t descriptorCount = uniformBufferDescriptorCount + 2;
|
|
||||||
|
|
||||||
VkDescriptorSetLayout descriptorSetLayouts[2]; // unrelated to maxFrames, unrelated to descriptorCount
|
VkDescriptorSetLayout descriptorSetLayouts[2]; // unrelated to maxFrames, unrelated to descriptorCount
|
||||||
VkDescriptorSet descriptorSets0[maxFrames];
|
VkDescriptorSet descriptorSets0[maxFrames];
|
||||||
VkDescriptorSet descriptorSet1;
|
VkDescriptorSet descriptorSet1;
|
||||||
|
|
||||||
|
struct Image {
|
||||||
|
VkImage image;
|
||||||
|
VkDeviceMemory memory;
|
||||||
|
VkImageView imageView;
|
||||||
|
};
|
||||||
|
Image * images;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Scene scene; // global(?)
|
Scene scene; // global(?)
|
||||||
Node * nodes; // per-scene
|
Node * nodes; // per-scene
|
||||||
@ -106,6 +116,8 @@ namespace collada::scene {
|
|||||||
|
|
||||||
void initial_state(VkInstance instance,
|
void initial_state(VkInstance instance,
|
||||||
VkDevice device,
|
VkDevice device,
|
||||||
|
VkQueue queue,
|
||||||
|
VkCommandPool commandPool,
|
||||||
VkPhysicalDeviceProperties const & physicalDeviceProperties,
|
VkPhysicalDeviceProperties const & physicalDeviceProperties,
|
||||||
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
VkFormat colorFormat,
|
VkFormat colorFormat,
|
||||||
@ -134,6 +146,7 @@ namespace collada::scene {
|
|||||||
void create_descriptor_sets();
|
void create_descriptor_sets();
|
||||||
void write_descriptor_sets(collada::types::descriptor const * const descriptor);
|
void write_descriptor_sets(collada::types::descriptor const * const descriptor);
|
||||||
void load_material_constants(collada::types::descriptor const * const descriptor);
|
void load_material_constants(collada::types::descriptor const * const descriptor);
|
||||||
|
void load_images(collada::types::descriptor const * const descriptor);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// called by state::draw
|
// called by state::draw
|
||||||
|
|||||||
13
include/dds/validate.h
Normal file
13
include/dds/validate.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dds/dds.h"
|
||||||
|
|
||||||
|
struct DDS_FILE {
|
||||||
|
unsigned int dwMagic;
|
||||||
|
DDS_HEADER header;
|
||||||
|
DDS_HEADER_DXT10 header10;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace dds {
|
||||||
|
DDS_FILE const * validate(void const * data, uint32_t size, uint32_t ** out_offsets, void ** out_data, uint32_t * out_size);
|
||||||
|
}
|
||||||
27
include/dds/vulkan.h
Normal file
27
include/dds/vulkan.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "dds/dds.h"
|
||||||
|
#include "volk/volk.h"
|
||||||
|
|
||||||
|
namespace dds {
|
||||||
|
inline constexpr VkFormat dxgi_to_vulkan(DXGI_FORMAT dxgiFormat)
|
||||||
|
{
|
||||||
|
switch (dxgiFormat) {
|
||||||
|
case DXGI_FORMAT_BC1_UNORM: return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
|
||||||
|
case DXGI_FORMAT_BC1_UNORM_SRGB: return VK_FORMAT_BC1_RGB_SRGB_BLOCK;
|
||||||
|
case DXGI_FORMAT_BC3_UNORM: return VK_FORMAT_BC3_UNORM_BLOCK;
|
||||||
|
case DXGI_FORMAT_BC3_UNORM_SRGB: return VK_FORMAT_BC3_SRGB_BLOCK;
|
||||||
|
case DXGI_FORMAT_BC7_UNORM: return VK_FORMAT_BC7_UNORM_BLOCK;
|
||||||
|
case DXGI_FORMAT_BC7_UNORM_SRGB: return VK_FORMAT_BC7_SRGB_BLOCK;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_UNORM: return VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return VK_FORMAT_B8G8R8A8_SRGB;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_UINT: return VK_FORMAT_R8G8B8A8_UINT;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_SNORM: return VK_FORMAT_R8G8B8A8_SNORM;
|
||||||
|
case DXGI_FORMAT_R8G8B8A8_SINT: return VK_FORMAT_R8G8B8A8_SINT;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,11 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "dds.h"
|
|
||||||
|
|
||||||
struct DDS_FILE {
|
|
||||||
unsigned int dwMagic;
|
|
||||||
DDS_HEADER header;
|
|
||||||
DDS_HEADER_DXT10 header10;
|
|
||||||
};
|
|
||||||
|
|
||||||
DDS_FILE const * dds_validate(void const * data, uint32_t size, uint32_t ** out_offsets, void ** out_data);
|
|
||||||
19
include/minmax.h
Normal file
19
include/minmax.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline static constexpr T min(T a, T b)
|
||||||
|
{
|
||||||
|
return (a < b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline static constexpr T max(T a, T b)
|
||||||
|
{
|
||||||
|
return (a > b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline static constexpr T clamp(T n, T minVal, T maxVal)
|
||||||
|
{
|
||||||
|
return min(max(n, minVal), maxVal);
|
||||||
|
}
|
||||||
@ -33,15 +33,17 @@ inline static constexpr void alignMappedMemoryRanges(uint32_t nonCoherentAtomSiz
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkDeviceSize allocateFromMemoryRequirements(VkDevice device,
|
VkDeviceSize allocateFromMemoryRequirements(VkDevice device,
|
||||||
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
VkMemoryRequirements const & memoryRequirements,
|
VkMemoryRequirements const & memoryRequirements,
|
||||||
VkMemoryPropertyFlags memoryPropertyFlags,
|
VkMemoryPropertyFlags memoryPropertyFlags,
|
||||||
VkMemoryAllocateFlags memoryAllocateFlags,
|
VkMemoryAllocateFlags memoryAllocateFlags,
|
||||||
uint32_t count,
|
uint32_t count,
|
||||||
VkDeviceMemory * memory);
|
VkDeviceMemory * memory,
|
||||||
|
VkDeviceSize * stride);
|
||||||
|
|
||||||
VkDeviceSize allocateFromMemoryRequirements2(VkDevice device,
|
VkDeviceSize allocateFromMemoryRequirements2(VkDevice device,
|
||||||
VkPhysicalDeviceProperties const & physicalDeviceProperties,
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
VkMemoryPropertyFlags memoryPropertyFlags,
|
VkMemoryPropertyFlags memoryPropertyFlags,
|
||||||
VkMemoryAllocateFlags memoryAllocateFlags,
|
VkMemoryAllocateFlags memoryAllocateFlags,
|
||||||
@ -49,3 +51,14 @@ VkDeviceSize allocateFromMemoryRequirements2(VkDevice device,
|
|||||||
VkMemoryRequirements const * memoryRequirements,
|
VkMemoryRequirements const * memoryRequirements,
|
||||||
VkDeviceMemory * memory,
|
VkDeviceMemory * memory,
|
||||||
VkDeviceSize * offsets);
|
VkDeviceSize * offsets);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|||||||
@ -17,6 +17,7 @@ namespace collada::scene {
|
|||||||
vulkan.create_descriptor_sets();
|
vulkan.create_descriptor_sets();
|
||||||
vulkan.write_descriptor_sets(descriptor);
|
vulkan.write_descriptor_sets(descriptor);
|
||||||
vulkan.load_material_constants(descriptor);
|
vulkan.load_material_constants(descriptor);
|
||||||
|
vulkan.load_images(descriptor);
|
||||||
vulkan.create_pipelines(descriptor);
|
vulkan.create_pipelines(descriptor);
|
||||||
|
|
||||||
node_state.allocate_node_instances(descriptor->nodes, descriptor->nodes_count);
|
node_state.allocate_node_instances(descriptor->nodes, descriptor->nodes_count);
|
||||||
|
|||||||
@ -9,7 +9,10 @@
|
|||||||
#include "collada/inputs.h"
|
#include "collada/inputs.h"
|
||||||
#include "collada/scene/vulkan.h"
|
#include "collada/scene/vulkan.h"
|
||||||
|
|
||||||
|
#include "minmax.h"
|
||||||
#include "vulkan_helper.h"
|
#include "vulkan_helper.h"
|
||||||
|
#include "dds/validate.h"
|
||||||
|
#include "dds/vulkan.h"
|
||||||
|
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
#include "new.h"
|
#include "new.h"
|
||||||
@ -102,6 +105,8 @@ namespace collada::scene {
|
|||||||
|
|
||||||
void vulkan::initial_state(VkInstance instance,
|
void vulkan::initial_state(VkInstance instance,
|
||||||
VkDevice device,
|
VkDevice device,
|
||||||
|
VkQueue queue,
|
||||||
|
VkCommandPool commandPool,
|
||||||
VkPhysicalDeviceProperties const & physicalDeviceProperties,
|
VkPhysicalDeviceProperties const & physicalDeviceProperties,
|
||||||
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
VkFormat colorFormat,
|
VkFormat colorFormat,
|
||||||
@ -111,6 +116,8 @@ namespace collada::scene {
|
|||||||
{
|
{
|
||||||
this->instance = instance;
|
this->instance = instance;
|
||||||
this->device = device;
|
this->device = device;
|
||||||
|
this->queue = queue;
|
||||||
|
this->commandPool = commandPool;
|
||||||
|
|
||||||
this->physicalDeviceProperties = physicalDeviceProperties;
|
this->physicalDeviceProperties = physicalDeviceProperties;
|
||||||
this->physicalDeviceMemoryProperties = physicalDeviceMemoryProperties;
|
this->physicalDeviceMemoryProperties = physicalDeviceMemoryProperties;
|
||||||
@ -155,14 +162,16 @@ namespace collada::scene {
|
|||||||
vkGetBufferMemoryRequirements(device, vertexIndex.buffer, &memoryRequirements);
|
vkGetBufferMemoryRequirements(device, vertexIndex.buffer, &memoryRequirements);
|
||||||
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
||||||
VkMemoryAllocateFlags memoryAllocateFlags{};
|
VkMemoryAllocateFlags memoryAllocateFlags{};
|
||||||
|
VkDeviceSize stride;
|
||||||
allocateFromMemoryRequirements(device,
|
allocateFromMemoryRequirements(device,
|
||||||
|
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
physicalDeviceMemoryProperties,
|
physicalDeviceMemoryProperties,
|
||||||
memoryRequirements,
|
memoryRequirements,
|
||||||
memoryPropertyFlags,
|
memoryPropertyFlags,
|
||||||
memoryAllocateFlags,
|
memoryAllocateFlags,
|
||||||
1,
|
1,
|
||||||
&vertexIndex.memory);
|
&vertexIndex.memory,
|
||||||
|
&stride);
|
||||||
|
|
||||||
VK_CHECK(vkBindBufferMemory(device, vertexIndex.buffer, vertexIndex.memory, 0));
|
VK_CHECK(vkBindBufferMemory(device, vertexIndex.buffer, vertexIndex.memory, 0));
|
||||||
|
|
||||||
@ -237,7 +246,7 @@ namespace collada::scene {
|
|||||||
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
||||||
VkMemoryAllocateFlags memoryAllocateFlags{ };
|
VkMemoryAllocateFlags memoryAllocateFlags{ };
|
||||||
shaderDataDevice.memorySize = allocateFromMemoryRequirements2(device,
|
shaderDataDevice.memorySize = allocateFromMemoryRequirements2(device,
|
||||||
physicalDeviceProperties,
|
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
physicalDeviceMemoryProperties,
|
physicalDeviceMemoryProperties,
|
||||||
memoryPropertyFlags,
|
memoryPropertyFlags,
|
||||||
memoryAllocateFlags,
|
memoryAllocateFlags,
|
||||||
@ -531,9 +540,52 @@ namespace collada::scene {
|
|||||||
alignMappedMemoryRanges(physicalDeviceProperties.limits.nonCoherentAtomSize,
|
alignMappedMemoryRanges(physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
shaderDataDevice.memorySize,
|
shaderDataDevice.memorySize,
|
||||||
1, mappedMemoryRanges);
|
1, mappedMemoryRanges);
|
||||||
//fprintf(stderr, "flush materials start %ld %ld %ld %ld : %ld\n", offset, size, alignedOffset, alignedSize, shaderDataDevice.memorySize);
|
|
||||||
vkFlushMappedMemoryRanges(device, 1, mappedMemoryRanges);
|
vkFlushMappedMemoryRanges(device, 1, mappedMemoryRanges);
|
||||||
//fprintf(stderr, "flush materials end\n");
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// material textures
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void vulkan::load_images(collada::types::descriptor const * const descriptor)
|
||||||
|
{
|
||||||
|
VkCommandBuffer commandBuffer{};
|
||||||
|
VkCommandBufferAllocateInfo commandBufferAllocateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||||
|
.commandPool = commandPool,
|
||||||
|
.commandBufferCount = 1
|
||||||
|
};
|
||||||
|
VK_CHECK(vkAllocateCommandBuffers(device, &commandBufferAllocateInfo, &commandBuffer));
|
||||||
|
|
||||||
|
VkFenceCreateInfo fenceCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
|
||||||
|
};
|
||||||
|
VkFence fence{};
|
||||||
|
VK_CHECK(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
|
||||||
|
|
||||||
|
// images
|
||||||
|
images = NewM<Image>(descriptor->images_count);
|
||||||
|
|
||||||
|
for (int i = 0; i < descriptor->images_count; i++) {
|
||||||
|
createImageFromFilenameDDS(device,
|
||||||
|
queue,
|
||||||
|
commandBuffer,
|
||||||
|
fence,
|
||||||
|
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
descriptor->images[i]->uri,
|
||||||
|
&images[i].image,
|
||||||
|
&images[i].memory,
|
||||||
|
&images[i].imageView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
|
||||||
|
vkDestroyFence(device, fence, nullptr);
|
||||||
|
vkFreeCommandBuffers(device,
|
||||||
|
commandPool,
|
||||||
|
1,
|
||||||
|
&commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -865,6 +917,13 @@ namespace collada::scene {
|
|||||||
|
|
||||||
void vulkan::destroy_all(collada::types::descriptor const * const descriptor)
|
void vulkan::destroy_all(collada::types::descriptor const * const descriptor)
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < descriptor->images_count; i++) {
|
||||||
|
vkDestroyImage(device, images[i].image, nullptr);
|
||||||
|
vkDestroyImageView(device, images[i].imageView, nullptr);
|
||||||
|
vkFreeMemory(device, images[i].memory, nullptr);
|
||||||
|
}
|
||||||
|
free(images);
|
||||||
|
|
||||||
free(shaderData.nodes);
|
free(shaderData.nodes);
|
||||||
free(shaderData.materialColors);
|
free(shaderData.materialColors);
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "new.h"
|
#include "new.h"
|
||||||
#include "dds_validate.h"
|
#include "dds/validate.h"
|
||||||
|
|
||||||
static inline uint32_t max(uint32_t a, uint32_t b)
|
static inline uint32_t max(uint32_t a, uint32_t b)
|
||||||
{
|
{
|
||||||
@ -14,9 +14,9 @@ struct dds_size_levels {
|
|||||||
uint32_t const levels;
|
uint32_t const levels;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline uint32_t dim(uint32_t d)
|
static inline uint32_t bc(uint32_t d)
|
||||||
{
|
{
|
||||||
return max(1, (d / 4));
|
return max(4, d) / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t mip_size(DXGI_FORMAT dxgiFormat, uint32_t height, uint32_t width)
|
static inline uint32_t mip_size(DXGI_FORMAT dxgiFormat, uint32_t height, uint32_t width)
|
||||||
@ -25,7 +25,14 @@ static inline uint32_t mip_size(DXGI_FORMAT dxgiFormat, uint32_t height, uint32_
|
|||||||
case DXGI_FORMAT_BC1_TYPELESS: [[fallthrough]];
|
case DXGI_FORMAT_BC1_TYPELESS: [[fallthrough]];
|
||||||
case DXGI_FORMAT_BC1_UNORM: [[fallthrough]];
|
case DXGI_FORMAT_BC1_UNORM: [[fallthrough]];
|
||||||
case DXGI_FORMAT_BC1_UNORM_SRGB:
|
case DXGI_FORMAT_BC1_UNORM_SRGB:
|
||||||
return dim(height) * dim(width) * 8;
|
return bc(height) * bc(width) * 8;
|
||||||
|
case DXGI_FORMAT_BC3_TYPELESS: [[fallthrough]];
|
||||||
|
case DXGI_FORMAT_BC3_UNORM: [[fallthrough]];
|
||||||
|
case DXGI_FORMAT_BC3_UNORM_SRGB: [[fallthrough]];
|
||||||
|
case DXGI_FORMAT_BC7_TYPELESS: [[fallthrough]];
|
||||||
|
case DXGI_FORMAT_BC7_UNORM: [[fallthrough]];
|
||||||
|
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||||
|
return bc(height) * bc(width) * 16;
|
||||||
case DXGI_FORMAT_R8G8B8A8_TYPELESS: [[fallthrough]];
|
case DXGI_FORMAT_R8G8B8A8_TYPELESS: [[fallthrough]];
|
||||||
case DXGI_FORMAT_R8G8B8A8_UNORM: [[fallthrough]];
|
case DXGI_FORMAT_R8G8B8A8_UNORM: [[fallthrough]];
|
||||||
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: [[fallthrough]];
|
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: [[fallthrough]];
|
||||||
@ -64,8 +71,9 @@ static inline dds_size_levels dds_mip_total_size(DXGI_FORMAT dxgiFormat,
|
|||||||
return {mip_total_size, mip_levels};
|
return {mip_total_size, mip_levels};
|
||||||
}
|
}
|
||||||
|
|
||||||
DDS_FILE const * dds_validate(void const * data, uint32_t size, uint32_t ** out_offsets, void ** out_data)
|
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 * const dds = (DDS_FILE const *)data;
|
DDS_FILE const * const dds = (DDS_FILE const *)data;
|
||||||
assert(dds->dwMagic == DDS_MAGIC);
|
assert(dds->dwMagic == DDS_MAGIC);
|
||||||
assert(dds->header.dwSize == 124);
|
assert(dds->header.dwSize == 124);
|
||||||
@ -87,5 +95,7 @@ DDS_FILE const * dds_validate(void const * data, uint32_t size, uint32_t ** out_
|
|||||||
|
|
||||||
*out_offsets = offsets;
|
*out_offsets = offsets;
|
||||||
*out_data = (void *)image_data;
|
*out_data = (void *)image_data;
|
||||||
|
*out_size = ret.size;
|
||||||
return dds;
|
return dds;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
242
src/main.cpp
242
src/main.cpp
@ -10,33 +10,16 @@
|
|||||||
#include "check.h"
|
#include "check.h"
|
||||||
#include "new.h"
|
#include "new.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "dds_validate.h"
|
#include "dds/validate.h"
|
||||||
#include "vulkan_helper.h"
|
#include "vulkan_helper.h"
|
||||||
#include "shader_data.h"
|
#include "shader_data.h"
|
||||||
|
#include "minmax.h"
|
||||||
|
|
||||||
#include "collada/scene.h"
|
#include "collada/scene.h"
|
||||||
#include "collada/scene/vulkan.h"
|
#include "collada/scene/vulkan.h"
|
||||||
|
|
||||||
#include "scenes/shadow_test/shadow_test.h"
|
#include "scenes/shadow_test/shadow_test.h"
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline static constexpr T min(T a, T b)
|
|
||||||
{
|
|
||||||
return (a < b) ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline static constexpr T max(T a, T b)
|
|
||||||
{
|
|
||||||
return (a > b) ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline static constexpr T clamp(T n, T minVal, T maxVal)
|
|
||||||
{
|
|
||||||
return min(max(n, minVal), maxVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
VkInstance instance{ VK_NULL_HANDLE };
|
VkInstance instance{ VK_NULL_HANDLE };
|
||||||
VkDevice device{ VK_NULL_HANDLE };
|
VkDevice device{ VK_NULL_HANDLE };
|
||||||
VkQueue queue{ VK_NULL_HANDLE };
|
VkQueue queue{ VK_NULL_HANDLE };
|
||||||
@ -136,7 +119,8 @@ XMMATRIX currentModel()
|
|||||||
return XMMatrixTranslation(0, 0, 0.0) * XMMatrixRotationX(theta) * XMMatrixRotationZ(XM_PI * 0.5f);
|
return XMMatrixTranslation(0, 0, 0.0) * XMMatrixRotationX(theta) * XMMatrixRotationZ(XM_PI * 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createDepth(VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
void createDepth(VkDeviceSize nonCoherentAtomSize,
|
||||||
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
uint32_t height,
|
uint32_t height,
|
||||||
VkFormat format,
|
VkFormat format,
|
||||||
@ -167,13 +151,16 @@ void createDepth(VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryPr
|
|||||||
vkGetImageMemoryRequirements(device, *image, &memoryRequirements);
|
vkGetImageMemoryRequirements(device, *image, &memoryRequirements);
|
||||||
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT };
|
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT };
|
||||||
VkMemoryAllocateFlags memoryAllocateFlags{ };
|
VkMemoryAllocateFlags memoryAllocateFlags{ };
|
||||||
|
VkDeviceSize stride;
|
||||||
allocateFromMemoryRequirements(device,
|
allocateFromMemoryRequirements(device,
|
||||||
|
nonCoherentAtomSize,
|
||||||
physicalDeviceMemoryProperties,
|
physicalDeviceMemoryProperties,
|
||||||
memoryRequirements,
|
memoryRequirements,
|
||||||
memoryPropertyFlags,
|
memoryPropertyFlags,
|
||||||
memoryAllocateFlags,
|
memoryAllocateFlags,
|
||||||
1,
|
1,
|
||||||
memory);
|
memory,
|
||||||
|
&stride);
|
||||||
VK_CHECK(vkBindImageMemory(device, *image, *memory, 0));
|
VK_CHECK(vkBindImageMemory(device, *image, *memory, 0));
|
||||||
|
|
||||||
VkImageViewCreateInfo imageViewCreateInfo{
|
VkImageViewCreateInfo imageViewCreateInfo{
|
||||||
@ -190,7 +177,11 @@ void createDepth(VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryPr
|
|||||||
VK_CHECK(vkCreateImageView(device, &imageViewCreateInfo, nullptr, imageView));
|
VK_CHECK(vkCreateImageView(device, &imageViewCreateInfo, nullptr, imageView));
|
||||||
}
|
}
|
||||||
|
|
||||||
void recreateSwapchain(VkSurfaceFormatKHR surfaceFormat, VkFormat depthFormat, VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties, VkSurfaceCapabilitiesKHR const & surfaceCapabilities)
|
void recreateSwapchain(VkSurfaceFormatKHR surfaceFormat,
|
||||||
|
VkFormat depthFormat,
|
||||||
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
|
VkSurfaceCapabilitiesKHR const & surfaceCapabilities)
|
||||||
{
|
{
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// swapchain and images
|
// swapchain and images
|
||||||
@ -286,7 +277,8 @@ void recreateSwapchain(VkSurfaceFormatKHR surfaceFormat, VkFormat depthFormat, V
|
|||||||
vkDestroyImageView(device, depthImageView, nullptr);
|
vkDestroyImageView(device, depthImageView, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
createDepth(physicalDeviceMemoryProperties,
|
createDepth(nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
imageExtent.width,
|
imageExtent.width,
|
||||||
imageExtent.height,
|
imageExtent.height,
|
||||||
depthFormat,
|
depthFormat,
|
||||||
@ -495,13 +487,14 @@ int main()
|
|||||||
ASSERT(depthFormat != VK_FORMAT_UNDEFINED, "no depth format with VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT");
|
ASSERT(depthFormat != VK_FORMAT_UNDEFINED, "no depth format with VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT");
|
||||||
printf("depthFormat: %s\n", string_VkFormat(depthFormat));
|
printf("depthFormat: %s\n", string_VkFormat(depthFormat));
|
||||||
|
|
||||||
recreateSwapchain(surfaceFormat, depthFormat, physicalDeviceMemoryProperties, surfaceCapabilities);
|
recreateSwapchain(surfaceFormat, depthFormat, physicalDeviceProperties.limits.nonCoherentAtomSize, physicalDeviceMemoryProperties, surfaceCapabilities);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// shadow
|
// shadow
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
createDepth(physicalDeviceMemoryProperties,
|
createDepth(physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
1024,
|
1024,
|
||||||
1024,
|
1024,
|
||||||
depthFormat,
|
depthFormat,
|
||||||
@ -549,15 +542,16 @@ int main()
|
|||||||
vkGetBufferMemoryRequirements(device, vertexIndexBuffer, &memoryRequirements);
|
vkGetBufferMemoryRequirements(device, vertexIndexBuffer, &memoryRequirements);
|
||||||
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
||||||
VkMemoryAllocateFlags memoryAllocateFlags{};
|
VkMemoryAllocateFlags memoryAllocateFlags{};
|
||||||
|
VkDeviceSize stride;
|
||||||
allocateFromMemoryRequirements(device,
|
allocateFromMemoryRequirements(device,
|
||||||
|
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
physicalDeviceMemoryProperties,
|
physicalDeviceMemoryProperties,
|
||||||
memoryRequirements,
|
memoryRequirements,
|
||||||
memoryPropertyFlags,
|
memoryPropertyFlags,
|
||||||
memoryAllocateFlags,
|
memoryAllocateFlags,
|
||||||
1,
|
1,
|
||||||
&vertexIndexBufferMemory);
|
&vertexIndexBufferMemory,
|
||||||
|
&stride);
|
||||||
VK_CHECK(vkBindBufferMemory(device, vertexIndexBuffer, vertexIndexBufferMemory, 0));
|
VK_CHECK(vkBindBufferMemory(device, vertexIndexBuffer, vertexIndexBufferMemory, 0));
|
||||||
|
|
||||||
void * vertexIndexMappedData;
|
void * vertexIndexMappedData;
|
||||||
@ -597,13 +591,15 @@ int main()
|
|||||||
|
|
||||||
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
||||||
VkMemoryAllocateFlags memoryAllocateFlags{ };
|
VkMemoryAllocateFlags memoryAllocateFlags{ };
|
||||||
shaderDataDevice.stride = allocateFromMemoryRequirements(device,
|
allocateFromMemoryRequirements(device,
|
||||||
|
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
physicalDeviceMemoryProperties,
|
physicalDeviceMemoryProperties,
|
||||||
memoryRequirements,
|
memoryRequirements,
|
||||||
memoryPropertyFlags,
|
memoryPropertyFlags,
|
||||||
memoryAllocateFlags,
|
memoryAllocateFlags,
|
||||||
maxFramesInFlight,
|
maxFramesInFlight,
|
||||||
&shaderDataDevice.memory);
|
&shaderDataDevice.memory,
|
||||||
|
&shaderDataDevice.stride);
|
||||||
|
|
||||||
VkDeviceSize offset{ 0 };
|
VkDeviceSize offset{ 0 };
|
||||||
VkDeviceSize size{ VK_WHOLE_SIZE };
|
VkDeviceSize size{ VK_WHOLE_SIZE };
|
||||||
@ -652,188 +648,8 @@ int main()
|
|||||||
VK_CHECK(vkAllocateCommandBuffers(device, &commandBufferAllocateCreateInfo, commandBuffers));
|
VK_CHECK(vkAllocateCommandBuffers(device, &commandBufferAllocateCreateInfo, commandBuffers));
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// texture
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
uint32_t checkerSize;
|
|
||||||
void const * checkerStart = file::open("checker.dds", &checkerSize);
|
|
||||||
void * checkerData;
|
|
||||||
uint32_t * mipOffsets;
|
|
||||||
DDS_FILE const * ddsFile = dds_validate(checkerStart, checkerSize, &mipOffsets, &checkerData);
|
|
||||||
uint32_t checkerDataSize = checkerSize - (sizeof (DDS_FILE));
|
|
||||||
|
|
||||||
VkFormat textureFormat{ VK_FORMAT_B8G8R8A8_SRGB };
|
|
||||||
|
|
||||||
VkImageCreateInfo textureImageCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
|
||||||
.imageType = VK_IMAGE_TYPE_2D,
|
|
||||||
.format = textureFormat,
|
|
||||||
.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, &textureImageCreateInfo, nullptr, &textureImage));
|
|
||||||
|
|
||||||
VkMemoryRequirements textureImageMemoryRequirements;
|
|
||||||
vkGetImageMemoryRequirements(device, textureImage, &textureImageMemoryRequirements);
|
|
||||||
VkMemoryPropertyFlags textureImageMemoryPropertyFlags{
|
|
||||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
|
||||||
};
|
|
||||||
VkMemoryAllocateFlags textureImageMemoryAllocateFlags{ };
|
|
||||||
allocateFromMemoryRequirements(device,
|
|
||||||
physicalDeviceMemoryProperties,
|
|
||||||
textureImageMemoryRequirements,
|
|
||||||
textureImageMemoryPropertyFlags,
|
|
||||||
textureImageMemoryAllocateFlags,
|
|
||||||
1,
|
|
||||||
&textureImageMemory);
|
|
||||||
VK_CHECK(vkBindImageMemory(device, textureImage, textureImageMemory, 0));
|
|
||||||
|
|
||||||
VkImageViewCreateInfo textureViewCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
|
||||||
.image = textureImage,
|
|
||||||
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
|
||||||
.format = textureFormat,
|
|
||||||
.subresourceRange{
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.levelCount = ddsFile->header.dwMipMapCount,
|
|
||||||
.layerCount = 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreateImageView(device, &textureViewCreateInfo, nullptr, &textureImageView));
|
|
||||||
|
|
||||||
// texture transfer: source buffer
|
|
||||||
|
|
||||||
VkBuffer textureSourceBuffer{};
|
|
||||||
VkBufferCreateInfo textureSourceBufferCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
||||||
.size = checkerDataSize,
|
|
||||||
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreateBuffer(device, &textureSourceBufferCreateInfo, nullptr, &textureSourceBuffer));
|
|
||||||
VkMemoryRequirements textureSourceBufferMemoryRequirements;
|
|
||||||
vkGetBufferMemoryRequirements(device, textureSourceBuffer, &textureSourceBufferMemoryRequirements);
|
|
||||||
VkMemoryPropertyFlags textureSourceBufferMemoryPropertyFlags{
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
|
||||||
};
|
|
||||||
VkMemoryAllocateFlags textureSourceBufferMemoryAllocateFlags{ };
|
|
||||||
VkDeviceMemory textureSourceBufferMemory;
|
|
||||||
allocateFromMemoryRequirements(device,
|
|
||||||
physicalDeviceMemoryProperties,
|
|
||||||
textureSourceBufferMemoryRequirements,
|
|
||||||
textureSourceBufferMemoryPropertyFlags,
|
|
||||||
textureSourceBufferMemoryAllocateFlags,
|
|
||||||
1,
|
|
||||||
&textureSourceBufferMemory);
|
|
||||||
VK_CHECK(vkBindBufferMemory(device, textureSourceBuffer, textureSourceBufferMemory, 0));
|
|
||||||
|
|
||||||
void * textureSourceMappedData;
|
|
||||||
VK_CHECK(vkMapMemory(device, textureSourceBufferMemory, 0, textureSourceBufferCreateInfo.size, 0, &textureSourceMappedData));
|
|
||||||
memcpy((void *)(((ptrdiff_t)textureSourceMappedData) + 0), checkerData, checkerDataSize);
|
|
||||||
vkUnmapMemory(device, textureSourceBufferMemory);
|
|
||||||
|
|
||||||
VkFenceCreateInfo textureFenceCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
|
|
||||||
};
|
|
||||||
VkFence textureFence{};
|
|
||||||
VK_CHECK(vkCreateFence(device, &textureFenceCreateInfo, nullptr, &textureFence));
|
|
||||||
|
|
||||||
// texture transfer: command buffer
|
|
||||||
|
|
||||||
VkCommandBuffer textureCommandBuffer{};
|
|
||||||
VkCommandBufferAllocateInfo textureCommandBufferAllocateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
|
||||||
.commandPool = commandPool,
|
|
||||||
.commandBufferCount = 1
|
|
||||||
};
|
|
||||||
VK_CHECK(vkAllocateCommandBuffers(device, &textureCommandBufferAllocateInfo, &textureCommandBuffer));
|
|
||||||
|
|
||||||
VkCommandBufferBeginInfo textureCommandBufferBeginInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
|
||||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
|
|
||||||
};
|
|
||||||
VK_CHECK(vkBeginCommandBuffer(textureCommandBuffer, &textureCommandBufferBeginInfo));
|
|
||||||
VkImageMemoryBarrier2 barrierTextureImage{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
|
||||||
.srcStageMask = VK_PIPELINE_STAGE_2_NONE,
|
|
||||||
.srcAccessMask = VK_ACCESS_2_NONE,
|
|
||||||
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
|
|
||||||
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
|
|
||||||
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
||||||
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
||||||
.image = textureImage,
|
|
||||||
.subresourceRange = {
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.levelCount = ddsFile->header.dwMipMapCount,
|
|
||||||
.layerCount = 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
VkDependencyInfo barrierTextureImageDependencyInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
|
||||||
.imageMemoryBarrierCount = 1,
|
|
||||||
.pImageMemoryBarriers = &barrierTextureImage
|
|
||||||
};
|
|
||||||
vkCmdPipelineBarrier2(textureCommandBuffer, &barrierTextureImageDependencyInfo);
|
|
||||||
VkBufferImageCopy * copyRegions = NewM<VkBufferImageCopy>(ddsFile->header.dwMipMapCount);
|
|
||||||
for (uint32_t level = 0; level < ddsFile->header.dwMipMapCount; level++) {
|
|
||||||
copyRegions[level] = {
|
|
||||||
.bufferOffset = mipOffsets[level],
|
|
||||||
.imageSubresource{
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.mipLevel = level,
|
|
||||||
.layerCount = 1
|
|
||||||
},
|
|
||||||
.imageExtent{
|
|
||||||
.width = max(1u, ddsFile->header.dwWidth >> level),
|
|
||||||
.height = max(1u, ddsFile->header.dwHeight >> level),
|
|
||||||
.depth = 1
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
vkCmdCopyBufferToImage(textureCommandBuffer, textureSourceBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, ddsFile->header.dwMipMapCount, copyRegions);
|
|
||||||
free(mipOffsets);
|
|
||||||
free(copyRegions);
|
|
||||||
|
|
||||||
VkImageMemoryBarrier2 barrierTextureRead{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
|
||||||
.srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
||||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
||||||
.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
|
||||||
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
|
||||||
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
||||||
.newLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
|
|
||||||
.image = textureImage,
|
|
||||||
.subresourceRange = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .levelCount = ddsFile->header.dwMipMapCount, .layerCount = 1 }
|
|
||||||
};
|
|
||||||
VkDependencyInfo barrierTextureReadDependencyInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
|
||||||
.imageMemoryBarrierCount = 1,
|
|
||||||
.pImageMemoryBarriers = &barrierTextureRead
|
|
||||||
};
|
|
||||||
vkCmdPipelineBarrier2(textureCommandBuffer, &barrierTextureReadDependencyInfo);
|
|
||||||
|
|
||||||
VK_CHECK(vkEndCommandBuffer(textureCommandBuffer));
|
|
||||||
|
|
||||||
VkSubmitInfo textureSubmitInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
|
||||||
.commandBufferCount = 1,
|
|
||||||
.pCommandBuffers = &textureCommandBuffer
|
|
||||||
};
|
|
||||||
VK_CHECK(vkQueueSubmit(queue, 1, &textureSubmitInfo, textureFence));
|
|
||||||
VK_CHECK(vkWaitForFences(device, 1, &textureFence, VK_TRUE, UINT64_MAX));
|
|
||||||
vkDestroyFence(device, textureFence, nullptr);
|
|
||||||
vkDestroyBuffer(device, textureSourceBuffer, nullptr);
|
|
||||||
vkFreeMemory(device, textureSourceBufferMemory, nullptr);
|
|
||||||
|
|
||||||
// texture sampler
|
// texture sampler
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
VkSamplerCreateInfo samplerCreateInfo0{
|
VkSamplerCreateInfo samplerCreateInfo0{
|
||||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||||
@ -1237,6 +1053,8 @@ int main()
|
|||||||
|
|
||||||
collada_state.vulkan.initial_state(instance,
|
collada_state.vulkan.initial_state(instance,
|
||||||
device,
|
device,
|
||||||
|
queue,
|
||||||
|
commandPool,
|
||||||
physicalDeviceProperties,
|
physicalDeviceProperties,
|
||||||
physicalDeviceMemoryProperties,
|
physicalDeviceMemoryProperties,
|
||||||
surfaceFormat.format,
|
surfaceFormat.format,
|
||||||
@ -1627,7 +1445,7 @@ int main()
|
|||||||
surfaceCapabilities.currentExtent.width = windowSize.x;
|
surfaceCapabilities.currentExtent.width = windowSize.x;
|
||||||
surfaceCapabilities.currentExtent.height = windowSize.y;
|
surfaceCapabilities.currentExtent.height = windowSize.y;
|
||||||
}
|
}
|
||||||
recreateSwapchain(surfaceFormat, depthFormat, physicalDeviceMemoryProperties, surfaceCapabilities);
|
recreateSwapchain(surfaceFormat, depthFormat, physicalDeviceProperties.limits.nonCoherentAtomSize, physicalDeviceMemoryProperties, surfaceCapabilities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,19 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "volk/volk.h"
|
#include "volk/volk.h"
|
||||||
#include "vulkan/vk_enum_string_helper.h"
|
#include "vulkan/vk_enum_string_helper.h"
|
||||||
|
|
||||||
|
#include "minmax.h"
|
||||||
|
#include "new.h"
|
||||||
|
#include "file.h"
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
|
|
||||||
|
#include "dds/validate.h"
|
||||||
|
#include "dds/vulkan.h"
|
||||||
|
|
||||||
#include "vulkan_helper.h"
|
#include "vulkan_helper.h"
|
||||||
|
|
||||||
inline static uint32_t findMemoryTypeIndex(VkPhysicalDeviceMemoryProperties const & memoryProperties, uint32_t memoryTypeBits, VkMemoryPropertyFlags propertyFlags)
|
inline static uint32_t findMemoryTypeIndex(VkPhysicalDeviceMemoryProperties const & memoryProperties, uint32_t memoryTypeBits, VkMemoryPropertyFlags propertyFlags)
|
||||||
@ -36,18 +43,21 @@ inline static uint32_t findMemoryTypeIndex(VkPhysicalDeviceMemoryProperties cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkDeviceSize allocateFromMemoryRequirements(VkDevice device,
|
VkDeviceSize allocateFromMemoryRequirements(VkDevice device,
|
||||||
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
VkMemoryRequirements const & memoryRequirements,
|
VkMemoryRequirements const & memoryRequirements,
|
||||||
VkMemoryPropertyFlags memoryPropertyFlags,
|
VkMemoryPropertyFlags memoryPropertyFlags,
|
||||||
VkMemoryAllocateFlags memoryAllocateFlags,
|
VkMemoryAllocateFlags memoryAllocateFlags,
|
||||||
uint32_t count,
|
uint32_t count,
|
||||||
VkDeviceMemory * memory)
|
VkDeviceMemory * memory,
|
||||||
|
VkDeviceSize * outStride)
|
||||||
{
|
{
|
||||||
uint32_t memoryTypeIndex = findMemoryTypeIndex(physicalDeviceMemoryProperties,
|
uint32_t memoryTypeIndex = findMemoryTypeIndex(physicalDeviceMemoryProperties,
|
||||||
memoryRequirements.memoryTypeBits,
|
memoryRequirements.memoryTypeBits,
|
||||||
memoryPropertyFlags);
|
memoryPropertyFlags);
|
||||||
|
|
||||||
VkDeviceSize stride = (count == 1) ? memoryRequirements.size : roundAlignment(memoryRequirements.size, memoryRequirements.alignment);
|
VkDeviceSize alignedSize = roundAlignment(memoryRequirements.size, memoryRequirements.alignment);
|
||||||
|
VkDeviceSize stride = (count == 1) ? memoryRequirements.size : alignedSize;
|
||||||
|
|
||||||
VkMemoryAllocateFlagsInfo memoryAllocateFlagsInfo{
|
VkMemoryAllocateFlagsInfo memoryAllocateFlagsInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,
|
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,
|
||||||
@ -56,16 +66,17 @@ VkDeviceSize allocateFromMemoryRequirements(VkDevice device,
|
|||||||
VkMemoryAllocateInfo memoryAllocateInfo{
|
VkMemoryAllocateInfo memoryAllocateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||||
.pNext = &memoryAllocateFlagsInfo,
|
.pNext = &memoryAllocateFlagsInfo,
|
||||||
.allocationSize = stride * count,
|
.allocationSize = roundAlignment(stride * count, nonCoherentAtomSize),
|
||||||
.memoryTypeIndex = memoryTypeIndex,
|
.memoryTypeIndex = memoryTypeIndex,
|
||||||
};
|
};
|
||||||
VK_CHECK(vkAllocateMemory(device, &memoryAllocateInfo, nullptr, memory));
|
VK_CHECK(vkAllocateMemory(device, &memoryAllocateInfo, nullptr, memory));
|
||||||
|
|
||||||
return stride;
|
*outStride = stride;
|
||||||
|
return memoryAllocateInfo.allocationSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDeviceSize allocateFromMemoryRequirements2(VkDevice device,
|
VkDeviceSize allocateFromMemoryRequirements2(VkDevice device,
|
||||||
VkPhysicalDeviceProperties const & physicalDeviceProperties,
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
VkMemoryPropertyFlags memoryPropertyFlags,
|
VkMemoryPropertyFlags memoryPropertyFlags,
|
||||||
VkMemoryAllocateFlags memoryAllocateFlags,
|
VkMemoryAllocateFlags memoryAllocateFlags,
|
||||||
@ -96,10 +107,201 @@ VkDeviceSize allocateFromMemoryRequirements2(VkDevice device,
|
|||||||
VkMemoryAllocateInfo memoryAllocateInfo{
|
VkMemoryAllocateInfo memoryAllocateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||||
.pNext = &memoryAllocateFlagsInfo,
|
.pNext = &memoryAllocateFlagsInfo,
|
||||||
.allocationSize = roundAlignment(offset, physicalDeviceProperties.limits.nonCoherentAtomSize),
|
.allocationSize = roundAlignment(offset, nonCoherentAtomSize),
|
||||||
.memoryTypeIndex = memoryTypeIndex,
|
.memoryTypeIndex = memoryTypeIndex,
|
||||||
};
|
};
|
||||||
VK_CHECK(vkAllocateMemory(device, &memoryAllocateInfo, nullptr, memory));
|
VK_CHECK(vkAllocateMemory(device, &memoryAllocateInfo, nullptr, memory));
|
||||||
|
|
||||||
return memoryAllocateInfo.allocationSize;
|
return memoryAllocateInfo.allocationSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 * 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{};
|
||||||
|
VkBufferCreateInfo sourceBufferCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
|
.size = imageDataSize,
|
||||||
|
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateBuffer(device, &sourceBufferCreateInfo, nullptr, &sourceBuffer));
|
||||||
|
VkMemoryRequirements sourceBufferMemoryRequirements;
|
||||||
|
vkGetBufferMemoryRequirements(device, sourceBuffer, &sourceBufferMemoryRequirements);
|
||||||
|
VkMemoryPropertyFlags sourceBufferMemoryPropertyFlags{
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
||||||
|
};
|
||||||
|
VkMemoryAllocateFlags sourceBufferMemoryAllocateFlags{ };
|
||||||
|
VkDeviceMemory sourceBufferMemory;
|
||||||
|
VkDeviceSize sourceBufferStride;
|
||||||
|
allocateFromMemoryRequirements(device,
|
||||||
|
nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
sourceBufferMemoryRequirements,
|
||||||
|
sourceBufferMemoryPropertyFlags,
|
||||||
|
sourceBufferMemoryAllocateFlags,
|
||||||
|
1,
|
||||||
|
&sourceBufferMemory,
|
||||||
|
&sourceBufferStride);
|
||||||
|
VK_CHECK(vkBindBufferMemory(device, sourceBuffer, sourceBufferMemory, 0));
|
||||||
|
|
||||||
|
void * sourceMappedData;
|
||||||
|
VK_CHECK(vkMapMemory(device, sourceBufferMemory, 0, sourceBufferCreateInfo.size, 0, &sourceMappedData));
|
||||||
|
memcpy((void *)(((ptrdiff_t)sourceMappedData) + 0), imageData, imageDataSize);
|
||||||
|
vkUnmapMemory(device, sourceBufferMemory);
|
||||||
|
|
||||||
|
// transfer: command buffer
|
||||||
|
|
||||||
|
VkCommandBufferBeginInfo commandBufferBeginInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||||
|
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
|
||||||
|
};
|
||||||
|
VK_CHECK(vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo));
|
||||||
|
VkImageMemoryBarrier2 imageBarrier{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||||
|
.srcStageMask = VK_PIPELINE_STAGE_2_NONE,
|
||||||
|
.srcAccessMask = VK_ACCESS_2_NONE,
|
||||||
|
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
|
||||||
|
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
|
||||||
|
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
.image = image,
|
||||||
|
.subresourceRange = {
|
||||||
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
.levelCount = ddsFile->header.dwMipMapCount,
|
||||||
|
.layerCount = 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
VkDependencyInfo imageDependencyInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||||
|
.imageMemoryBarrierCount = 1,
|
||||||
|
.pImageMemoryBarriers = &imageBarrier
|
||||||
|
};
|
||||||
|
vkCmdPipelineBarrier2(commandBuffer, &imageDependencyInfo);
|
||||||
|
VkBufferImageCopy * copyRegions = NewM<VkBufferImageCopy>(ddsFile->header.dwMipMapCount);
|
||||||
|
for (uint32_t level = 0; level < ddsFile->header.dwMipMapCount; level++) {
|
||||||
|
copyRegions[level] = {
|
||||||
|
.bufferOffset = mipOffsets[level],
|
||||||
|
.imageSubresource{
|
||||||
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
.mipLevel = level,
|
||||||
|
.layerCount = 1
|
||||||
|
},
|
||||||
|
.imageExtent{
|
||||||
|
.width = max(1u, ddsFile->header.dwWidth >> level),
|
||||||
|
.height = max(1u, ddsFile->header.dwHeight >> level),
|
||||||
|
.depth = 1
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
vkCmdCopyBufferToImage(commandBuffer, sourceBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, ddsFile->header.dwMipMapCount, copyRegions);
|
||||||
|
free(mipOffsets);
|
||||||
|
free(copyRegions);
|
||||||
|
|
||||||
|
VkImageMemoryBarrier2 readBarrier{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||||
|
.srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
||||||
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
.newLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
|
||||||
|
.image = image,
|
||||||
|
.subresourceRange = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .levelCount = ddsFile->header.dwMipMapCount, .layerCount = 1 }
|
||||||
|
};
|
||||||
|
VkDependencyInfo readDependencyInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||||
|
.imageMemoryBarrierCount = 1,
|
||||||
|
.pImageMemoryBarriers = &readBarrier
|
||||||
|
};
|
||||||
|
vkCmdPipelineBarrier2(commandBuffer, &readDependencyInfo);
|
||||||
|
|
||||||
|
VK_CHECK(vkEndCommandBuffer(commandBuffer));
|
||||||
|
|
||||||
|
vkResetFences(device, 1, &fence);
|
||||||
|
VkSubmitInfo submitInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||||
|
.commandBufferCount = 1,
|
||||||
|
.pCommandBuffers = &commandBuffer
|
||||||
|
};
|
||||||
|
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, fence));
|
||||||
|
VK_CHECK(vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX));
|
||||||
|
|
||||||
|
vkDestroyBuffer(device, sourceBuffer, nullptr);
|
||||||
|
vkFreeMemory(device, sourceBufferMemory, nullptr);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user