collada: draw scene textures
This commit is contained in:
parent
e9c0c9627c
commit
b7c25fc41f
@ -1,8 +1,4 @@
|
|||||||
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
|
data/scenes/shadow_test/images/0_leaf_white.dds
|
||||||
checker.idx
|
|
||||||
checker.vtx
|
|
||||||
sprite.data
|
|
||||||
|
|||||||
@ -24,6 +24,16 @@ namespace collada::scene {
|
|||||||
XMFLOAT4 diffuse;
|
XMFLOAT4 diffuse;
|
||||||
XMFLOAT4 specular;
|
XMFLOAT4 specular;
|
||||||
};
|
};
|
||||||
|
struct MaterialImage {
|
||||||
|
int emission;
|
||||||
|
int ambient;
|
||||||
|
int diffuse;
|
||||||
|
int specular;
|
||||||
|
};
|
||||||
|
struct MaterialColorImage {
|
||||||
|
MaterialColor color;
|
||||||
|
MaterialImage image;
|
||||||
|
};
|
||||||
struct PushConstant {
|
struct PushConstant {
|
||||||
int nodeIndex;
|
int nodeIndex;
|
||||||
int materialIndex;
|
int materialIndex;
|
||||||
@ -34,7 +44,8 @@ namespace collada::scene {
|
|||||||
static constexpr uint32_t perFrameDescriptorCount = 2;
|
static constexpr uint32_t perFrameDescriptorCount = 2;
|
||||||
static constexpr uint32_t constantDescriptorCount = 1;
|
static constexpr uint32_t constantDescriptorCount = 1;
|
||||||
static constexpr uint32_t uniformBufferDescriptorCount = maxFrames * perFrameDescriptorCount + constantDescriptorCount;
|
static constexpr uint32_t uniformBufferDescriptorCount = maxFrames * perFrameDescriptorCount + constantDescriptorCount;
|
||||||
static constexpr uint32_t descriptorCount = uniformBufferDescriptorCount + 2;
|
// +3: linear sampler, shadow sampled image, scene sampled image (array)
|
||||||
|
static constexpr uint32_t bindingCount = uniformBufferDescriptorCount + 3;
|
||||||
|
|
||||||
// externally initialized, opaque handle
|
// externally initialized, opaque handle
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
@ -79,7 +90,7 @@ namespace collada::scene {
|
|||||||
struct {
|
struct {
|
||||||
Scene scene; // global(?)
|
Scene scene; // global(?)
|
||||||
Node * nodes; // per-scene
|
Node * nodes; // per-scene
|
||||||
MaterialColor * materialColors; // per-scene
|
MaterialColorImage * materialColorImages; // per-scene
|
||||||
} shaderData;
|
} shaderData;
|
||||||
struct {
|
struct {
|
||||||
VkDeviceMemory memory;
|
VkDeviceMemory memory;
|
||||||
@ -97,10 +108,10 @@ namespace collada::scene {
|
|||||||
void * nodesMapped;
|
void * nodesMapped;
|
||||||
} frame[maxFrames];
|
} frame[maxFrames];
|
||||||
struct { // must match constantDescriptorCount
|
struct { // must match constantDescriptorCount
|
||||||
VkBuffer materialColorsBuffer;
|
VkBuffer materialColorImagesBuffer;
|
||||||
VkDeviceAddress materialColorsOffset;
|
VkDeviceAddress materialColorImagesOffset;
|
||||||
VkDeviceAddress materialColorsSize;
|
VkDeviceAddress materialColorImagesSize;
|
||||||
void * materialColorsMapped;
|
void * materialColorImagesMapped;
|
||||||
} constant;
|
} constant;
|
||||||
} shaderDataDevice;
|
} shaderDataDevice;
|
||||||
|
|
||||||
@ -143,7 +154,7 @@ namespace collada::scene {
|
|||||||
void create_pipelines(collada::types::descriptor const * const descriptor);
|
void create_pipelines(collada::types::descriptor const * const descriptor);
|
||||||
|
|
||||||
void create_uniform_buffers(collada::types::descriptor const * const descriptor);
|
void create_uniform_buffers(collada::types::descriptor const * const descriptor);
|
||||||
void create_descriptor_sets();
|
void create_descriptor_sets(collada::types::descriptor const * const descriptor);
|
||||||
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);
|
void load_images(collada::types::descriptor const * const descriptor);
|
||||||
|
|||||||
@ -35,22 +35,35 @@ struct Scene
|
|||||||
float4 LightPosition; // view space
|
float4 LightPosition; // view space
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MaterialColor
|
struct MaterialImage {
|
||||||
{
|
int Emission;
|
||||||
|
int Ambient;
|
||||||
|
int Diffuse;
|
||||||
|
int Specular;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MaterialColor {
|
||||||
float4 Emission;
|
float4 Emission;
|
||||||
float4 Ambient;
|
float4 Ambient;
|
||||||
float4 Diffuse;
|
float4 Diffuse;
|
||||||
float4 Specular;
|
float4 Specular;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MaterialColorImage
|
||||||
|
{
|
||||||
|
MaterialColor Color;
|
||||||
|
MaterialImage Image;
|
||||||
|
};
|
||||||
|
|
||||||
// set 0: per-frame
|
// set 0: per-frame
|
||||||
[[vk::binding(0, 0)]] ConstantBuffer<Scene> Scene;
|
[[vk::binding(0, 0)]] ConstantBuffer<Scene> Scene;
|
||||||
[[vk::binding(1, 0)]] StructuredBuffer<Node> Nodes;
|
[[vk::binding(1, 0)]] StructuredBuffer<Node> Nodes;
|
||||||
|
|
||||||
// set 1: constant
|
// set 1: constant
|
||||||
[[vk::binding(0, 1)]] StructuredBuffer<MaterialColor> MaterialColors;
|
[[vk::binding(0, 1)]] StructuredBuffer<MaterialColorImage> MaterialColorImages;
|
||||||
[[vk::binding(1, 1)]] SamplerState LinearSampler;
|
[[vk::binding(1, 1)]] SamplerState LinearSampler;
|
||||||
[[vk::binding(2, 1)]] Texture2D ShadowTexture;
|
[[vk::binding(2, 1)]] Texture2D ShadowTexture;
|
||||||
|
[[vk::binding(3, 1)]] Texture2D SceneTexture[];
|
||||||
|
|
||||||
struct PushConstant {
|
struct PushConstant {
|
||||||
int NodeIndex;
|
int NodeIndex;
|
||||||
@ -116,10 +129,25 @@ float ShadowPCF(float3 position, float bias)
|
|||||||
[shader("pixel")]
|
[shader("pixel")]
|
||||||
float4 PSMain(VSOutput input) : SV_TARGET
|
float4 PSMain(VSOutput input) : SV_TARGET
|
||||||
{
|
{
|
||||||
//float3 color = texture.Sample(samplers[0], input.Texture).bgr;
|
MaterialColorImage MCI = MaterialColorImages[constants.MaterialIndex];
|
||||||
float4 diffuseColor = MaterialColors[constants.MaterialIndex].Diffuse;
|
float4 diffuseColor;
|
||||||
float4 specularColor = MaterialColors[constants.MaterialIndex].Specular;
|
float4 specularColor;
|
||||||
float4 emissionColor = MaterialColors[constants.MaterialIndex].Emission;
|
float4 emissionColor;
|
||||||
|
if (MCI.Image.Diffuse >= 0) {
|
||||||
|
diffuseColor = SceneTexture[MCI.Image.Diffuse].Sample(LinearSampler, input.Texture).bgra;
|
||||||
|
} else {
|
||||||
|
diffuseColor = MCI.Color.Diffuse;
|
||||||
|
}
|
||||||
|
if (MCI.Image.Specular >= 0) {
|
||||||
|
specularColor = SceneTexture[MCI.Image.Specular].Sample(LinearSampler, input.Texture).bgra;
|
||||||
|
} else {
|
||||||
|
specularColor = MCI.Color.Specular;
|
||||||
|
}
|
||||||
|
if (MCI.Image.Emission >= 0) {
|
||||||
|
emissionColor = SceneTexture[MCI.Image.Emission].Sample(LinearSampler, input.Texture).bgra;
|
||||||
|
} else {
|
||||||
|
emissionColor = MCI.Color.Emission;
|
||||||
|
}
|
||||||
|
|
||||||
float3 N = normalize(input.Normal);
|
float3 N = normalize(input.Normal);
|
||||||
float3 L = normalize(input.LightDirection);
|
float3 L = normalize(input.LightDirection);
|
||||||
|
|||||||
@ -14,10 +14,10 @@ namespace collada::scene {
|
|||||||
vulkan.load_vertex_index_buffer(descriptor->position_normal_texture_buffer,
|
vulkan.load_vertex_index_buffer(descriptor->position_normal_texture_buffer,
|
||||||
descriptor->index_buffer);
|
descriptor->index_buffer);
|
||||||
vulkan.create_uniform_buffers(descriptor);
|
vulkan.create_uniform_buffers(descriptor);
|
||||||
vulkan.create_descriptor_sets();
|
vulkan.create_descriptor_sets(descriptor);
|
||||||
vulkan.write_descriptor_sets(descriptor);
|
|
||||||
vulkan.load_material_constants(descriptor);
|
vulkan.load_material_constants(descriptor);
|
||||||
vulkan.load_images(descriptor);
|
vulkan.load_images(descriptor);
|
||||||
|
vulkan.write_descriptor_sets(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);
|
||||||
|
|||||||
@ -204,7 +204,7 @@ namespace collada::scene {
|
|||||||
VkDeviceSize offsets[uniformBufferDescriptorCount];
|
VkDeviceSize offsets[uniformBufferDescriptorCount];
|
||||||
|
|
||||||
shaderData.nodes = NewM<Node>(descriptor->nodes_count);
|
shaderData.nodes = NewM<Node>(descriptor->nodes_count);
|
||||||
shaderData.materialColors = NewM<MaterialColor>(descriptor->materials_count);
|
shaderData.materialColorImages = NewM<MaterialColorImage>(descriptor->materials_count);
|
||||||
|
|
||||||
uint32_t memoryRequirementsIndex = 0;
|
uint32_t memoryRequirementsIndex = 0;
|
||||||
// per-frame
|
// per-frame
|
||||||
@ -232,14 +232,14 @@ namespace collada::scene {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// material color buffer
|
// material color buffer
|
||||||
VkBufferCreateInfo materialColorsBufferCreateInfo{
|
VkBufferCreateInfo materialColorImagesBufferCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
.size = (sizeof (MaterialColor)) * descriptor->materials_count,
|
.size = (sizeof (MaterialColorImage)) * descriptor->materials_count,
|
||||||
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
||||||
};
|
};
|
||||||
VK_CHECK(vkCreateBuffer(device, &materialColorsBufferCreateInfo, nullptr, &shaderDataDevice.constant.materialColorsBuffer));
|
VK_CHECK(vkCreateBuffer(device, &materialColorImagesBufferCreateInfo, nullptr, &shaderDataDevice.constant.materialColorImagesBuffer));
|
||||||
vkGetBufferMemoryRequirements(device, shaderDataDevice.constant.materialColorsBuffer, &memoryRequirements[memoryRequirementsIndex++]);
|
vkGetBufferMemoryRequirements(device, shaderDataDevice.constant.materialColorImagesBuffer, &memoryRequirements[memoryRequirementsIndex++]);
|
||||||
|
|
||||||
assert(memoryRequirementsIndex == uniformBufferDescriptorCount);
|
assert(memoryRequirementsIndex == uniformBufferDescriptorCount);
|
||||||
|
|
||||||
@ -273,10 +273,10 @@ namespace collada::scene {
|
|||||||
shaderDataDevice.frame[i].nodesMapped = (void *)(((size_t)shaderDataDevice.mappedData) + shaderDataDevice.frame[i].nodesOffset);
|
shaderDataDevice.frame[i].nodesMapped = (void *)(((size_t)shaderDataDevice.mappedData) + shaderDataDevice.frame[i].nodesOffset);
|
||||||
VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.frame[i].nodesBuffer, shaderDataDevice.memory, shaderDataDevice.frame[i].nodesOffset));
|
VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.frame[i].nodesBuffer, shaderDataDevice.memory, shaderDataDevice.frame[i].nodesOffset));
|
||||||
}
|
}
|
||||||
shaderDataDevice.constant.materialColorsOffset = offsets[offsetsIndex];
|
shaderDataDevice.constant.materialColorImagesOffset = offsets[offsetsIndex];
|
||||||
shaderDataDevice.constant.materialColorsSize = memoryRequirements[offsetsIndex++].size;
|
shaderDataDevice.constant.materialColorImagesSize = memoryRequirements[offsetsIndex++].size;
|
||||||
shaderDataDevice.constant.materialColorsMapped = (void *)(((size_t)shaderDataDevice.mappedData) + shaderDataDevice.constant.materialColorsOffset);
|
shaderDataDevice.constant.materialColorImagesMapped = (void *)(((size_t)shaderDataDevice.mappedData) + shaderDataDevice.constant.materialColorImagesOffset);
|
||||||
VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.constant.materialColorsBuffer, shaderDataDevice.memory, shaderDataDevice.constant.materialColorsOffset));
|
VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.constant.materialColorImagesBuffer, shaderDataDevice.memory, shaderDataDevice.constant.materialColorImagesOffset));
|
||||||
|
|
||||||
assert(offsetsIndex == uniformBufferDescriptorCount);
|
assert(offsetsIndex == uniformBufferDescriptorCount);
|
||||||
}
|
}
|
||||||
@ -285,7 +285,7 @@ namespace collada::scene {
|
|||||||
// descriptor sets
|
// descriptor sets
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void vulkan::create_descriptor_sets()
|
void vulkan::create_descriptor_sets(collada::types::descriptor const * const descriptor)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// pool
|
// pool
|
||||||
@ -294,11 +294,11 @@ namespace collada::scene {
|
|||||||
VkDescriptorPoolSize descriptorPoolSizes[descriptorPoolSizesCount]{
|
VkDescriptorPoolSize descriptorPoolSizes[descriptorPoolSizesCount]{
|
||||||
{
|
{
|
||||||
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
.descriptorCount = maxFrames + 1, // why +1?
|
.descriptorCount = maxFrames,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
.descriptorCount = maxFrames + 1, // +1 for materialColors
|
.descriptorCount = maxFrames + 1, // +1 for materialColorImages
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
@ -306,7 +306,7 @@ namespace collada::scene {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = (uint32_t)descriptor->images_count + 1, // +1 for shadow sampler
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{
|
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{
|
||||||
@ -362,7 +362,7 @@ namespace collada::scene {
|
|||||||
// uniform buffer descriptor set layout/allocation (set 1, constant)
|
// uniform buffer descriptor set layout/allocation (set 1, constant)
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
constexpr int bindingCount = 3;
|
constexpr int bindingCount = 4;
|
||||||
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[bindingCount]{
|
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[bindingCount]{
|
||||||
{
|
{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
@ -376,11 +376,17 @@ namespace collada::scene {
|
|||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
},
|
},
|
||||||
{
|
{ // shadow sampled image
|
||||||
.binding = 2,
|
.binding = 2,
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
|
},
|
||||||
|
{ // scene images
|
||||||
|
.binding = 3,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.descriptorCount = (uint32_t)descriptor->images_count,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -407,7 +413,7 @@ namespace collada::scene {
|
|||||||
|
|
||||||
void vulkan::write_descriptor_sets(collada::types::descriptor const * const descriptor)
|
void vulkan::write_descriptor_sets(collada::types::descriptor const * const descriptor)
|
||||||
{
|
{
|
||||||
VkWriteDescriptorSet writeDescriptorSets[descriptorCount];
|
VkWriteDescriptorSet writeDescriptorSets[bindingCount];
|
||||||
uint32_t writeIndex = 0;
|
uint32_t writeIndex = 0;
|
||||||
|
|
||||||
VkDescriptorBufferInfo sceneDescriptorBufferInfos[maxFrames];
|
VkDescriptorBufferInfo sceneDescriptorBufferInfos[maxFrames];
|
||||||
@ -442,10 +448,10 @@ namespace collada::scene {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorBufferInfo materialColorsDescriptorBufferInfo{
|
VkDescriptorBufferInfo materialColorImagesDescriptorBufferInfo{
|
||||||
.buffer = shaderDataDevice.constant.materialColorsBuffer,
|
.buffer = shaderDataDevice.constant.materialColorImagesBuffer,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.range = shaderDataDevice.constant.materialColorsSize,
|
.range = shaderDataDevice.constant.materialColorImagesSize,
|
||||||
};
|
};
|
||||||
writeDescriptorSets[writeIndex++] = {
|
writeDescriptorSets[writeIndex++] = {
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
@ -453,7 +459,7 @@ namespace collada::scene {
|
|||||||
.dstBinding = 0,
|
.dstBinding = 0,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
.pBufferInfo = &materialColorsDescriptorBufferInfo
|
.pBufferInfo = &materialColorImagesDescriptorBufferInfo
|
||||||
};
|
};
|
||||||
VkDescriptorImageInfo samplerDescriptorImageInfo = {
|
VkDescriptorImageInfo samplerDescriptorImageInfo = {
|
||||||
.sampler = linearSampler,
|
.sampler = linearSampler,
|
||||||
@ -479,9 +485,27 @@ namespace collada::scene {
|
|||||||
.pImageInfo = &sampledImageDescriptorImageInfo
|
.pImageInfo = &sampledImageDescriptorImageInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
assert(writeIndex == descriptorCount);
|
// scene images
|
||||||
|
VkDescriptorImageInfo * sceneDescriptorImageInfos = NewM<VkDescriptorImageInfo>(descriptor->images_count);
|
||||||
|
for (int i = 0; i < descriptor->images_count; i++) {
|
||||||
|
sceneDescriptorImageInfos[i] = {
|
||||||
|
.imageView = images[i].imageView,
|
||||||
|
.imageLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
writeDescriptorSets[writeIndex++] = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.dstSet = descriptorSet1,
|
||||||
|
.dstBinding = 3,
|
||||||
|
.descriptorCount = (uint32_t)descriptor->images_count,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.pImageInfo = sceneDescriptorImageInfos
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(writeIndex == bindingCount);
|
||||||
vkUpdateDescriptorSets(device, writeIndex, writeDescriptorSets, 0, nullptr);
|
vkUpdateDescriptorSets(device, writeIndex, writeDescriptorSets, 0, nullptr);
|
||||||
|
free(sceneDescriptorImageInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -490,33 +514,51 @@ namespace collada::scene {
|
|||||||
|
|
||||||
void vulkan::load_material_constants(collada::types::descriptor const * const descriptor)
|
void vulkan::load_material_constants(collada::types::descriptor const * const descriptor)
|
||||||
{
|
{
|
||||||
|
constexpr collada::types::color_or_texture_type TEXTURE = collada::types::color_or_texture_type::TEXTURE;
|
||||||
// store
|
// store
|
||||||
for (int i = 0; i < descriptor->materials_count; i++) {
|
for (int i = 0; i < descriptor->materials_count; i++) {
|
||||||
collada::types::effect const * const effect = descriptor->materials[i]->effect;
|
collada::types::effect const * const effect = descriptor->materials[i]->effect;
|
||||||
|
MaterialColorImage & mci = shaderData.materialColorImages[i];
|
||||||
switch (effect->type) {
|
switch (effect->type) {
|
||||||
case collada::types::effect_type::BLINN:
|
case collada::types::effect_type::BLINN:
|
||||||
shaderData.materialColors[i].emission = *(XMFLOAT4 *)(&effect->blinn.emission.color);
|
mci.color.emission = *(XMFLOAT4 *)(&effect->blinn.emission.color);
|
||||||
shaderData.materialColors[i].ambient = *(XMFLOAT4 *)(&effect->blinn.ambient.color);
|
mci.color.ambient = *(XMFLOAT4 *)(&effect->blinn.ambient.color);
|
||||||
shaderData.materialColors[i].diffuse = *(XMFLOAT4 *)(&effect->blinn.diffuse.color);
|
mci.color.diffuse = *(XMFLOAT4 *)(&effect->blinn.diffuse.color);
|
||||||
shaderData.materialColors[i].specular = *(XMFLOAT4 *)(&effect->blinn.specular.color);
|
mci.color.specular = *(XMFLOAT4 *)(&effect->blinn.specular.color);
|
||||||
|
mci.image.emission = (effect->blinn.emission.type == TEXTURE) ? effect->blinn.emission.texture.image_index : -1;
|
||||||
|
mci.image.ambient = (effect->blinn.ambient.type == TEXTURE) ? effect->blinn.ambient.texture.image_index : -1;
|
||||||
|
mci.image.diffuse = (effect->blinn.diffuse.type == TEXTURE) ? effect->blinn.diffuse.texture.image_index : -1;
|
||||||
|
mci.image.specular = (effect->blinn.specular.type == TEXTURE) ? effect->blinn.specular.texture.image_index : -1;
|
||||||
break;
|
break;
|
||||||
case collada::types::effect_type::LAMBERT:
|
case collada::types::effect_type::LAMBERT:
|
||||||
shaderData.materialColors[i].emission = *(XMFLOAT4 *)(&effect->lambert.emission.color);
|
mci.color.emission = *(XMFLOAT4 *)(&effect->lambert.emission.color);
|
||||||
shaderData.materialColors[i].ambient = *(XMFLOAT4 *)(&effect->lambert.ambient.color);
|
mci.color.ambient = *(XMFLOAT4 *)(&effect->lambert.ambient.color);
|
||||||
shaderData.materialColors[i].diffuse = *(XMFLOAT4 *)(&effect->lambert.diffuse.color);
|
mci.color.diffuse = *(XMFLOAT4 *)(&effect->lambert.diffuse.color);
|
||||||
shaderData.materialColors[i].specular = XMFLOAT4{0, 0, 0, 0};
|
mci.color.specular = XMFLOAT4{0, 0, 0, 0};
|
||||||
|
mci.image.emission = (effect->lambert.emission.type == TEXTURE) ? effect->lambert.emission.texture.image_index : -1;
|
||||||
|
mci.image.ambient = (effect->lambert.ambient.type == TEXTURE) ? effect->lambert.ambient.texture.image_index : -1;
|
||||||
|
mci.image.diffuse = (effect->lambert.diffuse.type == TEXTURE) ? effect->lambert.diffuse.texture.image_index : -1;
|
||||||
|
mci.image.specular = -1;
|
||||||
break;
|
break;
|
||||||
case collada::types::effect_type::PHONG:
|
case collada::types::effect_type::PHONG:
|
||||||
shaderData.materialColors[i].emission = *(XMFLOAT4 *)(&effect->phong.emission.color);
|
mci.color.emission = *(XMFLOAT4 *)(&effect->phong.emission.color);
|
||||||
shaderData.materialColors[i].ambient = *(XMFLOAT4 *)(&effect->phong.ambient.color);
|
mci.color.ambient = *(XMFLOAT4 *)(&effect->phong.ambient.color);
|
||||||
shaderData.materialColors[i].diffuse = *(XMFLOAT4 *)(&effect->phong.diffuse.color);
|
mci.color.diffuse = *(XMFLOAT4 *)(&effect->phong.diffuse.color);
|
||||||
shaderData.materialColors[i].specular = *(XMFLOAT4 *)(&effect->phong.specular.color);
|
mci.color.specular = *(XMFLOAT4 *)(&effect->phong.specular.color);
|
||||||
|
mci.image.emission = (effect->phong.emission.type == TEXTURE) ? effect->phong.emission.texture.image_index : -1;
|
||||||
|
mci.image.ambient = (effect->phong.ambient.type == TEXTURE) ? effect->phong.ambient.texture.image_index : -1;
|
||||||
|
mci.image.diffuse = (effect->phong.diffuse.type == TEXTURE) ? effect->phong.diffuse.texture.image_index : -1;
|
||||||
|
mci.image.specular = (effect->phong.specular.type == TEXTURE) ? effect->phong.specular.texture.image_index : -1;
|
||||||
break;
|
break;
|
||||||
case collada::types::effect_type::CONSTANT:
|
case collada::types::effect_type::CONSTANT:
|
||||||
shaderData.materialColors[i].emission = *(XMFLOAT4 *)(&effect->constant.color);
|
mci.color.emission = *(XMFLOAT4 *)(&effect->constant.color);
|
||||||
shaderData.materialColors[i].ambient = XMFLOAT4{0, 0, 0, 0};
|
mci.color.ambient = XMFLOAT4{0, 0, 0, 0};
|
||||||
shaderData.materialColors[i].diffuse = XMFLOAT4{0, 0, 0, 0};
|
mci.color.diffuse = XMFLOAT4{0, 0, 0, 0};
|
||||||
shaderData.materialColors[i].specular = XMFLOAT4{0, 0, 0, 0};
|
mci.color.specular = XMFLOAT4{0, 0, 0, 0};
|
||||||
|
mci.image.emission = -1;
|
||||||
|
mci.image.ambient = -1;
|
||||||
|
mci.image.diffuse = -1;
|
||||||
|
mci.image.specular = -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
@ -525,7 +567,7 @@ namespace collada::scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// copy
|
// copy
|
||||||
memcpy(shaderDataDevice.constant.materialColorsMapped, &shaderData.materialColors[0], (sizeof (MaterialColor)) * descriptor->materials_count);
|
memcpy(shaderDataDevice.constant.materialColorImagesMapped, &shaderData.materialColorImages[0], (sizeof (MaterialColorImage)) * descriptor->materials_count);
|
||||||
|
|
||||||
// flush
|
// flush
|
||||||
|
|
||||||
@ -533,8 +575,8 @@ namespace collada::scene {
|
|||||||
{
|
{
|
||||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||||
.memory = shaderDataDevice.memory,
|
.memory = shaderDataDevice.memory,
|
||||||
.offset = shaderDataDevice.constant.materialColorsOffset,
|
.offset = shaderDataDevice.constant.materialColorImagesOffset,
|
||||||
.size = shaderDataDevice.constant.materialColorsSize,
|
.size = shaderDataDevice.constant.materialColorImagesSize,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
alignMappedMemoryRanges(physicalDeviceProperties.limits.nonCoherentAtomSize,
|
alignMappedMemoryRanges(physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
@ -925,7 +967,7 @@ namespace collada::scene {
|
|||||||
free(images);
|
free(images);
|
||||||
|
|
||||||
free(shaderData.nodes);
|
free(shaderData.nodes);
|
||||||
free(shaderData.materialColors);
|
free(shaderData.materialColorImages);
|
||||||
|
|
||||||
vkDestroyBuffer(device, vertexIndex.buffer, nullptr);
|
vkDestroyBuffer(device, vertexIndex.buffer, nullptr);
|
||||||
vkFreeMemory(device, vertexIndex.memory, nullptr);
|
vkFreeMemory(device, vertexIndex.memory, nullptr);
|
||||||
@ -934,7 +976,7 @@ namespace collada::scene {
|
|||||||
vkDestroyBuffer(device, shaderDataDevice.frame[i].sceneBuffer, nullptr);
|
vkDestroyBuffer(device, shaderDataDevice.frame[i].sceneBuffer, nullptr);
|
||||||
vkDestroyBuffer(device, shaderDataDevice.frame[i].nodesBuffer, nullptr);
|
vkDestroyBuffer(device, shaderDataDevice.frame[i].nodesBuffer, nullptr);
|
||||||
}
|
}
|
||||||
vkDestroyBuffer(device, shaderDataDevice.constant.materialColorsBuffer, nullptr);
|
vkDestroyBuffer(device, shaderDataDevice.constant.materialColorImagesBuffer, nullptr);
|
||||||
vkFreeMemory(device, shaderDataDevice.memory, nullptr);
|
vkFreeMemory(device, shaderDataDevice.memory, nullptr);
|
||||||
|
|
||||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts[0], nullptr);
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts[0], nullptr);
|
||||||
|
|||||||
494
src/main.cpp
494
src/main.cpp
@ -39,11 +39,6 @@ VkImageView shadowDepthImageView{ VK_NULL_HANDLE };
|
|||||||
VkImageView shadowDepthImageViewDepth{ VK_NULL_HANDLE };
|
VkImageView shadowDepthImageViewDepth{ VK_NULL_HANDLE };
|
||||||
VkDeviceMemory shadowDepthMemory{ VK_NULL_HANDLE };
|
VkDeviceMemory shadowDepthMemory{ VK_NULL_HANDLE };
|
||||||
|
|
||||||
VkBuffer vertexIndexBuffer{ VK_NULL_HANDLE };
|
|
||||||
VkDeviceMemory vertexIndexBufferMemory{ VK_NULL_HANDLE };
|
|
||||||
VkDeviceSize vertexBufferSize{ 0 };
|
|
||||||
VkDeviceSize indexBufferSize{ 0 };
|
|
||||||
|
|
||||||
VkFence fences[maxFramesInFlight];
|
VkFence fences[maxFramesInFlight];
|
||||||
VkSemaphore presentSemaphores[maxFramesInFlight];
|
VkSemaphore presentSemaphores[maxFramesInFlight];
|
||||||
VkSemaphore * renderSemaphores{ nullptr };
|
VkSemaphore * renderSemaphores{ nullptr };
|
||||||
@ -51,30 +46,12 @@ VkSemaphore * renderSemaphores{ nullptr };
|
|||||||
VkCommandPool commandPool{ VK_NULL_HANDLE };
|
VkCommandPool commandPool{ VK_NULL_HANDLE };
|
||||||
VkCommandBuffer commandBuffers[maxFramesInFlight];
|
VkCommandBuffer commandBuffers[maxFramesInFlight];
|
||||||
|
|
||||||
enum {
|
|
||||||
MAIN_PIPELINE = 0,
|
|
||||||
OUTLINE_PIPELINE = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPipeline pipelines[2]{ VK_NULL_HANDLE, VK_NULL_HANDLE };
|
|
||||||
VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE };
|
|
||||||
|
|
||||||
VkImage textureImage{ VK_NULL_HANDLE };
|
|
||||||
VkImageView textureImageView{ VK_NULL_HANDLE };
|
|
||||||
VkDeviceMemory textureImageMemory{ VK_NULL_HANDLE };
|
|
||||||
VkSampler textureSamplers[3]{ VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE };
|
VkSampler textureSamplers[3]{ VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE };
|
||||||
|
|
||||||
VkDescriptorPool descriptorPool{ VK_NULL_HANDLE };
|
VkDescriptorPool descriptorPool{ VK_NULL_HANDLE };
|
||||||
VkDescriptorSetLayout uniformBufferDescriptorSetLayout{ VK_NULL_HANDLE };
|
|
||||||
VkDescriptorSet uniformBufferDescriptorSets[maxFramesInFlight];
|
|
||||||
VkDescriptorSetLayout textureDescriptorSetLayout{ VK_NULL_HANDLE };
|
|
||||||
VkDescriptorSet textureDescriptorSet{ VK_NULL_HANDLE };
|
|
||||||
|
|
||||||
XMINT2 windowSize{};
|
XMINT2 windowSize{};
|
||||||
|
|
||||||
ShaderData shaderData{};
|
|
||||||
ShaderDataDevice shaderDataDevice{};
|
|
||||||
|
|
||||||
void print_memoryPropertyFlags(VkMemoryPropertyFlags propertyFlags)
|
void print_memoryPropertyFlags(VkMemoryPropertyFlags propertyFlags)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -517,102 +494,6 @@ int main()
|
|||||||
};
|
};
|
||||||
VK_CHECK(vkCreateImageView(device, &imageViewCreateInfo, nullptr, &shadowDepthImageViewDepth));
|
VK_CHECK(vkCreateImageView(device, &imageViewCreateInfo, nullptr, &shadowDepthImageViewDepth));
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// mesh
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
{
|
|
||||||
uint32_t vertexSize;
|
|
||||||
void const * vertexStart = file::open("checker.vtx", &vertexSize);
|
|
||||||
uint32_t indexSize;
|
|
||||||
void const * indexStart = file::open("checker.idx", &indexSize);
|
|
||||||
vertexBufferSize = vertexSize;
|
|
||||||
indexBufferSize = indexSize;
|
|
||||||
|
|
||||||
VkDeviceSize bufferSize{ vertexSize + indexSize };
|
|
||||||
VkBufferCreateInfo vertexIndexBufferCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
||||||
.size = bufferSize,
|
|
||||||
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
|
||||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreateBuffer(device, &vertexIndexBufferCreateInfo, nullptr, &vertexIndexBuffer));
|
|
||||||
|
|
||||||
VkMemoryRequirements memoryRequirements;
|
|
||||||
vkGetBufferMemoryRequirements(device, vertexIndexBuffer, &memoryRequirements);
|
|
||||||
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
|
||||||
VkMemoryAllocateFlags memoryAllocateFlags{};
|
|
||||||
VkDeviceSize stride;
|
|
||||||
allocateFromMemoryRequirements(device,
|
|
||||||
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
|
||||||
physicalDeviceMemoryProperties,
|
|
||||||
memoryRequirements,
|
|
||||||
memoryPropertyFlags,
|
|
||||||
memoryAllocateFlags,
|
|
||||||
1,
|
|
||||||
&vertexIndexBufferMemory,
|
|
||||||
&stride);
|
|
||||||
VK_CHECK(vkBindBufferMemory(device, vertexIndexBuffer, vertexIndexBufferMemory, 0));
|
|
||||||
|
|
||||||
void * vertexIndexMappedData;
|
|
||||||
VK_CHECK(vkMapMemory(device, vertexIndexBufferMemory, 0, VK_WHOLE_SIZE, 0, &vertexIndexMappedData));
|
|
||||||
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + 0), vertexStart, vertexSize);
|
|
||||||
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + vertexSize), indexStart, indexSize);
|
|
||||||
|
|
||||||
VkMappedMemoryRange mappedMemoryRange{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
|
||||||
.memory = vertexIndexBufferMemory,
|
|
||||||
.offset = 0,
|
|
||||||
.size = VK_WHOLE_SIZE,
|
|
||||||
};
|
|
||||||
vkFlushMappedMemoryRanges(device, 1, &mappedMemoryRange);
|
|
||||||
|
|
||||||
vkUnmapMemory(device, vertexIndexBufferMemory);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// shader buffers
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < maxFramesInFlight; i++) {
|
|
||||||
VkBufferCreateInfo bufferCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
||||||
.size = (sizeof (ShaderData)),
|
|
||||||
.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
|
||||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
|
||||||
};
|
|
||||||
|
|
||||||
VK_CHECK(vkCreateBuffer(device, &bufferCreateInfo, nullptr, &shaderDataDevice.frame[i].buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
VkMemoryRequirements memoryRequirements;
|
|
||||||
vkGetBufferMemoryRequirements(device, shaderDataDevice.frame[0].buffer, &memoryRequirements);
|
|
||||||
|
|
||||||
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
|
||||||
VkMemoryAllocateFlags memoryAllocateFlags{ };
|
|
||||||
allocateFromMemoryRequirements(device,
|
|
||||||
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
|
||||||
physicalDeviceMemoryProperties,
|
|
||||||
memoryRequirements,
|
|
||||||
memoryPropertyFlags,
|
|
||||||
memoryAllocateFlags,
|
|
||||||
maxFramesInFlight,
|
|
||||||
&shaderDataDevice.memory,
|
|
||||||
&shaderDataDevice.stride);
|
|
||||||
|
|
||||||
VkDeviceSize offset{ 0 };
|
|
||||||
VkDeviceSize size{ VK_WHOLE_SIZE };
|
|
||||||
VkMemoryMapFlags flags{ 0 };
|
|
||||||
VK_CHECK(vkMapMemory(device, shaderDataDevice.memory, offset, size, flags, &shaderDataDevice.mappedData));
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < maxFramesInFlight; i++) {
|
|
||||||
VkDeviceSize offset{ shaderDataDevice.stride * i };
|
|
||||||
|
|
||||||
VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.frame[i].buffer, shaderDataDevice.memory, offset));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// synchronization objects
|
// synchronization objects
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -686,365 +567,6 @@ int main()
|
|||||||
};
|
};
|
||||||
VK_CHECK(vkCreateSampler(device, &samplerCreateInfo2, nullptr, &textureSamplers[2]));
|
VK_CHECK(vkCreateSampler(device, &samplerCreateInfo2, nullptr, &textureSamplers[2]));
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// descriptors
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// pool
|
|
||||||
//
|
|
||||||
|
|
||||||
VkDescriptorPoolSize descriptorPoolSizes[3]{
|
|
||||||
{
|
|
||||||
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
||||||
.descriptorCount = 3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
||||||
.descriptorCount = maxFramesInFlight,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
|
||||||
.maxSets = 3,
|
|
||||||
.poolSizeCount = 3,
|
|
||||||
.pPoolSizes = descriptorPoolSizes
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreateDescriptorPool(device, &descriptorPoolCreateInfo, nullptr, &descriptorPool));
|
|
||||||
|
|
||||||
//
|
|
||||||
// uniform buffer descriptor set layout/allocation
|
|
||||||
//
|
|
||||||
|
|
||||||
VkDescriptorSetLayoutBinding uniformBufferDescriptorSetLayoutBinding{
|
|
||||||
.binding = 0,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT
|
|
||||||
};
|
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo uniformBufferDescriptorSetLayoutCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
||||||
.bindingCount = 1,
|
|
||||||
.pBindings = &uniformBufferDescriptorSetLayoutBinding
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreateDescriptorSetLayout(device, &uniformBufferDescriptorSetLayoutCreateInfo, nullptr, &uniformBufferDescriptorSetLayout));
|
|
||||||
|
|
||||||
VkDescriptorSetLayout uniformBufferDescriptorSetLayouts[maxFramesInFlight];
|
|
||||||
for (uint32_t i = 0; i < maxFramesInFlight; i++) {
|
|
||||||
uniformBufferDescriptorSetLayouts[i] = uniformBufferDescriptorSetLayout;
|
|
||||||
};
|
|
||||||
|
|
||||||
VkDescriptorSetAllocateInfo uniformBufferDescriptorSetAllocateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
|
||||||
.descriptorPool = descriptorPool,
|
|
||||||
.descriptorSetCount = maxFramesInFlight,
|
|
||||||
.pSetLayouts = uniformBufferDescriptorSetLayouts
|
|
||||||
};
|
|
||||||
VK_CHECK(vkAllocateDescriptorSets(device, &uniformBufferDescriptorSetAllocateInfo, uniformBufferDescriptorSets));
|
|
||||||
|
|
||||||
//
|
|
||||||
// texture descriptor set layout/allocation
|
|
||||||
//
|
|
||||||
|
|
||||||
VkDescriptorSetLayoutBinding textureDescriptorSetLayoutBindings[2]{
|
|
||||||
{
|
|
||||||
.binding = 0,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
||||||
.descriptorCount = 3,
|
|
||||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.binding = 1,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo textureDescriptorSetLayoutCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
||||||
.bindingCount = 2,
|
|
||||||
.pBindings = textureDescriptorSetLayoutBindings
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreateDescriptorSetLayout(device, &textureDescriptorSetLayoutCreateInfo, nullptr, &textureDescriptorSetLayout));
|
|
||||||
|
|
||||||
VkDescriptorSetAllocateInfo textureDescriptorSetAllocateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
|
||||||
.descriptorPool = descriptorPool,
|
|
||||||
.descriptorSetCount = 1,
|
|
||||||
.pSetLayouts = &textureDescriptorSetLayout
|
|
||||||
};
|
|
||||||
VK_CHECK(vkAllocateDescriptorSets(device, &textureDescriptorSetAllocateInfo, &textureDescriptorSet));
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// descriptor set writes
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
constexpr int writeDescriptorSetsCount = 2 + maxFramesInFlight;
|
|
||||||
VkWriteDescriptorSet writeDescriptorSets[writeDescriptorSetsCount];
|
|
||||||
|
|
||||||
VkDescriptorImageInfo textureSamplerDescriptorImageInfos[3] = {
|
|
||||||
{
|
|
||||||
.sampler = textureSamplers[0],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.sampler = textureSamplers[1],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.sampler = textureSamplers[2],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
writeDescriptorSets[0] = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
||||||
.dstSet = textureDescriptorSet,
|
|
||||||
.dstBinding = 0,
|
|
||||||
.descriptorCount = 3,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
||||||
.pImageInfo = textureSamplerDescriptorImageInfos
|
|
||||||
};
|
|
||||||
VkDescriptorImageInfo textureImageDescriptorImageInfo = {
|
|
||||||
.imageView = textureImageView,
|
|
||||||
.imageLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL
|
|
||||||
};
|
|
||||||
writeDescriptorSets[1] = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
||||||
.dstSet = textureDescriptorSet,
|
|
||||||
.dstBinding = 1,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
||||||
.pImageInfo = &textureImageDescriptorImageInfo
|
|
||||||
};
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < maxFramesInFlight; i++) {
|
|
||||||
VkDescriptorBufferInfo descriptorBufferInfo {
|
|
||||||
.buffer = shaderDataDevice.frame[i].buffer,
|
|
||||||
.offset = 0,
|
|
||||||
.range = VK_WHOLE_SIZE,
|
|
||||||
};
|
|
||||||
|
|
||||||
writeDescriptorSets[2 + i] = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
||||||
.dstSet = uniformBufferDescriptorSets[i],
|
|
||||||
.dstBinding = 0,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
||||||
.pBufferInfo = &descriptorBufferInfo
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// update all three descriptor sets
|
|
||||||
vkUpdateDescriptorSets(device, writeDescriptorSetsCount, writeDescriptorSets, 0, nullptr);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// shaders
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
uint32_t triangleSize;
|
|
||||||
void const * triangleStart = file::open("shader/triangle.spv", &triangleSize);
|
|
||||||
|
|
||||||
VkShaderModuleCreateInfo shaderModuleCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
|
||||||
.codeSize = triangleSize,
|
|
||||||
.pCode = (uint32_t *)triangleStart
|
|
||||||
};
|
|
||||||
VkShaderModule shaderModule{};
|
|
||||||
VK_CHECK(vkCreateShaderModule(device, &shaderModuleCreateInfo, nullptr, &shaderModule));
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// pipeline
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
VkDescriptorSetLayout descriptorSetLayouts[2] = {
|
|
||||||
uniformBufferDescriptorSetLayout,
|
|
||||||
textureDescriptorSetLayout,
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPushConstantRange pushConstantRange{
|
|
||||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
||||||
.size = (sizeof (int32_t))
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
||||||
.setLayoutCount = 2,
|
|
||||||
.pSetLayouts = descriptorSetLayouts,
|
|
||||||
.pushConstantRangeCount = 1,
|
|
||||||
.pPushConstantRanges = &pushConstantRange
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
|
|
||||||
|
|
||||||
VkVertexInputBindingDescription vertexBindingDescriptions[1]{
|
|
||||||
{
|
|
||||||
.binding = 0,
|
|
||||||
.stride = ((3 + 3 + 2) * (sizeof (float))),
|
|
||||||
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
|
|
||||||
}
|
|
||||||
};
|
|
||||||
VkVertexInputAttributeDescription vertexAttributeDescriptions[3]{
|
|
||||||
{ .location = 0, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = 3 * 4 * 0 },
|
|
||||||
{ .location = 1, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = 3 * 4 * 1 },
|
|
||||||
{ .location = 2, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = 3 * 4 * 2 },
|
|
||||||
};
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputState{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
|
||||||
.vertexBindingDescriptionCount = 1,
|
|
||||||
.pVertexBindingDescriptions = vertexBindingDescriptions,
|
|
||||||
.vertexAttributeDescriptionCount = 3,
|
|
||||||
.pVertexAttributeDescriptions = vertexAttributeDescriptions,
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
|
||||||
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo shaderStages[2]{
|
|
||||||
{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
||||||
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
|
||||||
.module = shaderModule,
|
|
||||||
.pName = "VSMain"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
||||||
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
||||||
.module = shaderModule,
|
|
||||||
.pName = "PSMain"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo outlineShaderStages[2]{
|
|
||||||
{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
||||||
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
|
||||||
.module = shaderModule,
|
|
||||||
.pName = "VSOutlineMain"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
||||||
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
||||||
.module = shaderModule,
|
|
||||||
.pName = "PSOutlineMain"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPipelineViewportStateCreateInfo viewportState{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
|
||||||
.viewportCount = 1,
|
|
||||||
.scissorCount = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr uint32_t dynamicStateCount = 2;
|
|
||||||
VkDynamicState dynamicStates[dynamicStateCount]{
|
|
||||||
VK_DYNAMIC_STATE_VIEWPORT,
|
|
||||||
VK_DYNAMIC_STATE_SCISSOR,
|
|
||||||
};
|
|
||||||
VkPipelineDynamicStateCreateInfo dynamicState{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
|
||||||
.dynamicStateCount = dynamicStateCount,
|
|
||||||
.pDynamicStates = dynamicStates
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPipelineDepthStencilStateCreateInfo depthStencilState{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
|
||||||
.depthTestEnable = VK_TRUE,
|
|
||||||
.depthWriteEnable = VK_TRUE,
|
|
||||||
.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL,
|
|
||||||
.stencilTestEnable = VK_TRUE,
|
|
||||||
.front = {
|
|
||||||
.failOp = VK_STENCIL_OP_REPLACE,
|
|
||||||
.passOp = VK_STENCIL_OP_REPLACE,
|
|
||||||
.depthFailOp = VK_STENCIL_OP_REPLACE,
|
|
||||||
.compareOp = VK_COMPARE_OP_ALWAYS,
|
|
||||||
.compareMask = 0x01,
|
|
||||||
.writeMask = 0x01,
|
|
||||||
.reference = 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPipelineDepthStencilStateCreateInfo outlineDepthStencilState{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
|
||||||
.depthTestEnable = VK_TRUE,
|
|
||||||
.depthWriteEnable = VK_TRUE,
|
|
||||||
.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL,
|
|
||||||
.stencilTestEnable = VK_TRUE,
|
|
||||||
.front = {
|
|
||||||
.failOp = VK_STENCIL_OP_KEEP,
|
|
||||||
.passOp = VK_STENCIL_OP_REPLACE,
|
|
||||||
.depthFailOp = VK_STENCIL_OP_KEEP,
|
|
||||||
.compareOp = VK_COMPARE_OP_NOT_EQUAL,
|
|
||||||
.compareMask = 0x01,
|
|
||||||
.writeMask = 0x00,
|
|
||||||
.reference = 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPipelineRenderingCreateInfo renderingCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
|
||||||
.colorAttachmentCount = 1,
|
|
||||||
.pColorAttachmentFormats = &surfaceFormat.format,
|
|
||||||
.depthAttachmentFormat = depthFormat,
|
|
||||||
.stencilAttachmentFormat = depthFormat
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPipelineColorBlendAttachmentState blendAttachment{
|
|
||||||
.colorWriteMask = 0xF
|
|
||||||
};
|
|
||||||
VkPipelineColorBlendStateCreateInfo colorBlendState{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
|
||||||
.attachmentCount = 1,
|
|
||||||
.pAttachments = &blendAttachment
|
|
||||||
};
|
|
||||||
VkPipelineRasterizationStateCreateInfo rasterizationState{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
|
||||||
.cullMode = VK_CULL_MODE_BACK_BIT,
|
|
||||||
.frontFace = VK_FRONT_FACE_CLOCKWISE,
|
|
||||||
.lineWidth = 1.0f
|
|
||||||
};
|
|
||||||
VkPipelineMultisampleStateCreateInfo multisampleState{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
|
||||||
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT
|
|
||||||
};
|
|
||||||
|
|
||||||
VkGraphicsPipelineCreateInfo pipelineCreateInfos[2]{
|
|
||||||
{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
|
||||||
.pNext = &renderingCreateInfo,
|
|
||||||
.stageCount = 2,
|
|
||||||
.pStages = shaderStages,
|
|
||||||
.pVertexInputState = &vertexInputState,
|
|
||||||
.pInputAssemblyState = &inputAssemblyState,
|
|
||||||
.pViewportState = &viewportState,
|
|
||||||
.pRasterizationState = &rasterizationState,
|
|
||||||
.pMultisampleState = &multisampleState,
|
|
||||||
.pDepthStencilState = &depthStencilState,
|
|
||||||
.pColorBlendState = &colorBlendState,
|
|
||||||
.pDynamicState = &dynamicState,
|
|
||||||
.layout = pipelineLayout
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
|
||||||
.pNext = &renderingCreateInfo,
|
|
||||||
.stageCount = 2,
|
|
||||||
.pStages = outlineShaderStages,
|
|
||||||
.pVertexInputState = &vertexInputState,
|
|
||||||
.pInputAssemblyState = &inputAssemblyState,
|
|
||||||
.pViewportState = &viewportState,
|
|
||||||
.pRasterizationState = &rasterizationState,
|
|
||||||
.pMultisampleState = &multisampleState,
|
|
||||||
.pDepthStencilState = &outlineDepthStencilState,
|
|
||||||
.pColorBlendState = &colorBlendState,
|
|
||||||
.pDynamicState = &dynamicState,
|
|
||||||
.layout = pipelineLayout
|
|
||||||
}
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 2, pipelineCreateInfos, nullptr, pipelines));
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// initialize collada
|
// initialize collada
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -1457,11 +979,7 @@ int main()
|
|||||||
for (uint32_t i = 0; i < maxFramesInFlight; i++) {
|
for (uint32_t i = 0; i < maxFramesInFlight; i++) {
|
||||||
vkDestroyFence(device, fences[i], nullptr);
|
vkDestroyFence(device, fences[i], nullptr);
|
||||||
vkDestroySemaphore(device, presentSemaphores[i], nullptr);
|
vkDestroySemaphore(device, presentSemaphores[i], nullptr);
|
||||||
|
|
||||||
vkDestroyBuffer(device, shaderDataDevice.frame[i].buffer, nullptr);
|
|
||||||
}
|
}
|
||||||
vkUnmapMemory(device, shaderDataDevice.memory);
|
|
||||||
vkFreeMemory(device, shaderDataDevice.memory, nullptr);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < swapchainImageCount; i++) {
|
for (uint32_t i = 0; i < swapchainImageCount; i++) {
|
||||||
vkDestroySemaphore(device, renderSemaphores[i], nullptr);
|
vkDestroySemaphore(device, renderSemaphores[i], nullptr);
|
||||||
@ -1477,26 +995,14 @@ int main()
|
|||||||
vkDestroyImageView(device, shadowDepthImageView, nullptr);
|
vkDestroyImageView(device, shadowDepthImageView, nullptr);
|
||||||
vkDestroyImageView(device, shadowDepthImageViewDepth, nullptr);
|
vkDestroyImageView(device, shadowDepthImageViewDepth, nullptr);
|
||||||
|
|
||||||
vkDestroyBuffer(device, vertexIndexBuffer, nullptr);
|
|
||||||
vkFreeMemory(device, vertexIndexBufferMemory, nullptr);
|
|
||||||
|
|
||||||
vkDestroyImageView(device, textureImageView, nullptr);
|
|
||||||
vkDestroySampler(device, textureSamplers[0], nullptr);
|
vkDestroySampler(device, textureSamplers[0], nullptr);
|
||||||
vkDestroySampler(device, textureSamplers[1], nullptr);
|
vkDestroySampler(device, textureSamplers[1], nullptr);
|
||||||
vkDestroySampler(device, textureSamplers[2], nullptr);
|
vkDestroySampler(device, textureSamplers[2], nullptr);
|
||||||
vkDestroyImage(device, textureImage, nullptr);
|
|
||||||
vkFreeMemory(device, textureImageMemory, nullptr);
|
|
||||||
|
|
||||||
vkDestroyDescriptorSetLayout(device, uniformBufferDescriptorSetLayout, nullptr);
|
|
||||||
vkDestroyDescriptorSetLayout(device, textureDescriptorSetLayout, nullptr);
|
|
||||||
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
|
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
|
||||||
vkDestroyPipeline(device, pipelines[0], nullptr);
|
|
||||||
vkDestroyPipeline(device, pipelines[1], nullptr);
|
|
||||||
vkDestroySwapchainKHR(device, swapchain, nullptr);
|
vkDestroySwapchainKHR(device, swapchain, nullptr);
|
||||||
vkDestroySurfaceKHR(instance, surface, nullptr);
|
vkDestroySurfaceKHR(instance, surface, nullptr);
|
||||||
vkDestroyCommandPool(device, commandPool, nullptr);
|
vkDestroyCommandPool(device, commandPool, nullptr);
|
||||||
vkDestroyShaderModule(device, shaderModule, nullptr);
|
|
||||||
|
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user