Add texture in demo
This commit is contained in:
parent
9cc206b33e
commit
4ede9f1cfe
|
|
@ -43,7 +43,10 @@ ACTION.Function = function ()
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(paths, {
|
table.insert(paths, {
|
||||||
Excludes = {},
|
Excludes = {
|
||||||
|
["DeviceFunctions.hpp"] = true,
|
||||||
|
["InstanceFunctions.hpp"] = true,
|
||||||
|
},
|
||||||
HeaderGuard = "NAZARA_GLOBAL_VULKANRENDERER_WRAPPER_HPP",
|
HeaderGuard = "NAZARA_GLOBAL_VULKANRENDERER_WRAPPER_HPP",
|
||||||
Name = "Vulkan wrapper",
|
Name = "Vulkan wrapper",
|
||||||
SearchDir = "../include/Nazara/VulkanRenderer/Wrapper",
|
SearchDir = "../include/Nazara/VulkanRenderer/Wrapper",
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,8 @@ int main()
|
||||||
Nz::RenderWindow window;
|
Nz::RenderWindow window;
|
||||||
|
|
||||||
Nz::MeshParams meshParams;
|
Nz::MeshParams meshParams;
|
||||||
meshParams.matrix = Nz::Matrix4f::Rotate(Nz::EulerAnglesf(0.f, 90.f, 180.f));
|
meshParams.matrix = Nz::Matrix4f::Rotate(Nz::EulerAnglesf(0.f, 90.f, 180.f)) * Nz::Matrix4f::Scale(Nz::Vector3f(0.002f));
|
||||||
meshParams.vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout_XYZ_Normal);
|
meshParams.vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout_XYZ_Normal_UV);
|
||||||
|
|
||||||
Nz::String windowTitle = "Vulkan Test";
|
Nz::String windowTitle = "Vulkan Test";
|
||||||
if (!window.Create(Nz::VideoMode(800, 600, 32), windowTitle))
|
if (!window.Create(Nz::VideoMode(800, 600, 32), windowTitle))
|
||||||
|
|
@ -96,7 +96,7 @@ int main()
|
||||||
return __LINE__;
|
return __LINE__;
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::MeshRef drfreak = Nz::Mesh::LoadFromFile("resources/drfreak.md2", meshParams);
|
Nz::MeshRef drfreak = Nz::Mesh::LoadFromFile("resources/Spaceship/spaceship.obj", meshParams);
|
||||||
|
|
||||||
if (!drfreak)
|
if (!drfreak)
|
||||||
{
|
{
|
||||||
|
|
@ -115,6 +115,153 @@ int main()
|
||||||
// Vertex buffer
|
// Vertex buffer
|
||||||
std::cout << "Vertex count: " << drfreakVB->GetVertexCount() << std::endl;
|
std::cout << "Vertex count: " << drfreakVB->GetVertexCount() << std::endl;
|
||||||
|
|
||||||
|
Nz::VkRenderWindow& vulkanWindow = *static_cast<Nz::VkRenderWindow*>(window.GetImpl());
|
||||||
|
Nz::VulkanDevice& vulkanDevice = vulkanWindow.GetDevice();
|
||||||
|
|
||||||
|
Nz::Vk::CommandPool cmdPool;
|
||||||
|
if (!cmdPool.Create(vulkanDevice, 0, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create rendering cmd pool");
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
Nz::Vk::QueueHandle graphicsQueue = vulkanDevice.GetQueue(0, 0);
|
||||||
|
|
||||||
|
// Texture
|
||||||
|
Nz::ImageRef drfreakImage = Nz::Image::LoadFromFile("resources/Spaceship/Texture/diffuse.png");
|
||||||
|
if (!drfreakImage || !drfreakImage->Convert(Nz::PixelFormatType_RGBA8))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to load image");
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImageCreateInfo imageInfo = {};
|
||||||
|
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
imageInfo.extent.width = static_cast<uint32_t>(drfreakImage->GetWidth());
|
||||||
|
imageInfo.extent.height = static_cast<uint32_t>(drfreakImage->GetHeight());
|
||||||
|
imageInfo.extent.depth = 1;
|
||||||
|
imageInfo.mipLevels = 1;
|
||||||
|
imageInfo.arrayLayers = 1;
|
||||||
|
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
imageInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
|
||||||
|
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
|
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
|
Nz::Vk::Image vkImage;
|
||||||
|
if (!vkImage.Create(vulkanDevice, imageInfo))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create vulkan image");
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkMemoryRequirements imageMemRequirement = vkImage.GetMemoryRequirements();
|
||||||
|
|
||||||
|
Nz::Vk::DeviceMemory imageMemory;
|
||||||
|
if (!imageMemory.Create(vulkanDevice, imageMemRequirement.size, imageMemRequirement.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create vulkan image memory");
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
vkImage.BindImageMemory(imageMemory);
|
||||||
|
|
||||||
|
// Update texture
|
||||||
|
{
|
||||||
|
Nz::Vk::Buffer stagingImageBuffer;
|
||||||
|
if (!stagingImageBuffer.Create(vulkanDevice, 0, drfreakImage->GetMemoryUsage(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create staging buffer");
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkMemoryPropertyFlags memoryProperties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
|
||||||
|
|
||||||
|
Nz::Vk::DeviceMemory stagingImageMemory;
|
||||||
|
|
||||||
|
VkMemoryRequirements memRequirement = stagingImageBuffer.GetMemoryRequirements();
|
||||||
|
if (!stagingImageMemory.Create(vulkanDevice, memRequirement.size, memRequirement.memoryTypeBits, memoryProperties))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to allocate vertex buffer memory");
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stagingImageBuffer.BindBufferMemory(stagingImageMemory))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to bind vertex buffer to its memory");
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stagingImageMemory.Map(0, memRequirement.size))
|
||||||
|
return __LINE__;
|
||||||
|
|
||||||
|
std::memcpy(stagingImageMemory.GetMappedPointer(), drfreakImage->GetPixels(), drfreakImage->GetMemoryUsage());
|
||||||
|
|
||||||
|
stagingImageMemory.FlushMemory();
|
||||||
|
stagingImageMemory.Unmap();
|
||||||
|
|
||||||
|
Nz::Vk::CommandBuffer copyCommand = cmdPool.AllocateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY);
|
||||||
|
copyCommand.Begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||||
|
copyCommand.SetImageLayout(vkImage, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
copyCommand.CopyBufferToImage(stagingImageBuffer, vkImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, drfreakImage->GetWidth(), drfreakImage->GetHeight());
|
||||||
|
copyCommand.SetImageLayout(vkImage, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
if (!copyCommand.End())
|
||||||
|
return __LINE__;
|
||||||
|
|
||||||
|
if (!graphicsQueue.Submit(copyCommand))
|
||||||
|
return __LINE__;
|
||||||
|
|
||||||
|
graphicsQueue.WaitIdle();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create image view
|
||||||
|
|
||||||
|
VkImageViewCreateInfo imageViewInfo = {};
|
||||||
|
imageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
imageViewInfo.components = {
|
||||||
|
VK_COMPONENT_SWIZZLE_R,
|
||||||
|
VK_COMPONENT_SWIZZLE_G,
|
||||||
|
VK_COMPONENT_SWIZZLE_B,
|
||||||
|
VK_COMPONENT_SWIZZLE_A
|
||||||
|
};
|
||||||
|
imageViewInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
|
||||||
|
imageViewInfo.image = vkImage;
|
||||||
|
imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
imageViewInfo.subresourceRange = {
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
|
Nz::Vk::ImageView imageView;
|
||||||
|
if (!imageView.Create(vulkanDevice, imageViewInfo))
|
||||||
|
return __LINE__;
|
||||||
|
|
||||||
|
// Sampler
|
||||||
|
|
||||||
|
VkSamplerCreateInfo samplerInfo = {};
|
||||||
|
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
|
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||||
|
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||||
|
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
samplerInfo.anisotropyEnable = VK_FALSE;
|
||||||
|
samplerInfo.maxAnisotropy = 16;
|
||||||
|
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||||
|
samplerInfo.unnormalizedCoordinates = VK_FALSE;
|
||||||
|
samplerInfo.compareEnable = VK_FALSE;
|
||||||
|
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||||
|
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
|
|
||||||
|
Nz::Vk::Sampler imageSampler;
|
||||||
|
if (!imageSampler.Create(vulkanDevice, samplerInfo))
|
||||||
|
return __LINE__;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
Nz::Matrix4f projectionMatrix;
|
Nz::Matrix4f projectionMatrix;
|
||||||
|
|
@ -131,33 +278,21 @@ int main()
|
||||||
Nz::UInt32 uniformSize = sizeof(ubo);
|
Nz::UInt32 uniformSize = sizeof(ubo);
|
||||||
|
|
||||||
Nz::RenderPipelineLayoutInfo pipelineLayoutInfo;
|
Nz::RenderPipelineLayoutInfo pipelineLayoutInfo;
|
||||||
auto& bindingInfo = pipelineLayoutInfo.bindings.emplace_back();
|
auto& uboBinding = pipelineLayoutInfo.bindings.emplace_back();
|
||||||
bindingInfo.index = 0;
|
uboBinding.index = 0;
|
||||||
bindingInfo.shaderStageFlags = Nz::ShaderStageType::Vertex;
|
uboBinding.shaderStageFlags = Nz::ShaderStageType::Vertex;
|
||||||
bindingInfo.type = Nz::ShaderBindingType::UniformBuffer;
|
uboBinding.type = Nz::ShaderBindingType::UniformBuffer;
|
||||||
|
|
||||||
|
auto& textureBinding = pipelineLayoutInfo.bindings.emplace_back();
|
||||||
|
textureBinding.index = 1;
|
||||||
|
textureBinding.shaderStageFlags = Nz::ShaderStageType::Fragment;
|
||||||
|
textureBinding.type = Nz::ShaderBindingType::Texture;
|
||||||
|
|
||||||
std::shared_ptr<Nz::RenderPipelineLayout> renderPipelineLayout = device->InstantiateRenderPipelineLayout(pipelineLayoutInfo);
|
std::shared_ptr<Nz::RenderPipelineLayout> renderPipelineLayout = device->InstantiateRenderPipelineLayout(pipelineLayoutInfo);
|
||||||
|
|
||||||
Nz::VulkanRenderPipelineLayout* vkPipelineLayout = static_cast<Nz::VulkanRenderPipelineLayout*>(renderPipelineLayout.get());
|
Nz::VulkanRenderPipelineLayout* vkPipelineLayout = static_cast<Nz::VulkanRenderPipelineLayout*>(renderPipelineLayout.get());
|
||||||
|
|
||||||
VkDescriptorSetLayout descriptorLayout = vkPipelineLayout->GetDescriptorSetLayout();
|
Nz::Vk::DescriptorSet descriptorSet = vkPipelineLayout->AllocateDescriptorSet();
|
||||||
VkPipelineLayout pipelineLayout = vkPipelineLayout->GetPipelineLayout();
|
|
||||||
|
|
||||||
VkDescriptorPoolSize poolSize;
|
|
||||||
poolSize.descriptorCount = 1;
|
|
||||||
poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
||||||
|
|
||||||
Nz::VkRenderWindow& vulkanWindow = *static_cast<Nz::VkRenderWindow*>(window.GetImpl());
|
|
||||||
Nz::VulkanDevice& vulkanDevice = vulkanWindow.GetDevice();
|
|
||||||
|
|
||||||
Nz::Vk::DescriptorPool descriptorPool;
|
|
||||||
if (!descriptorPool.Create(vulkanDevice, 1, poolSize, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT))
|
|
||||||
{
|
|
||||||
NazaraError("Failed to create descriptor pool");
|
|
||||||
return __LINE__;
|
|
||||||
}
|
|
||||||
|
|
||||||
Nz::Vk::DescriptorSet descriptorSet = descriptorPool.AllocateDescriptorSet(descriptorLayout);
|
|
||||||
|
|
||||||
std::unique_ptr<Nz::AbstractBuffer> uniformBuffer = device->InstantiateBuffer(Nz::BufferType_Uniform);
|
std::unique_ptr<Nz::AbstractBuffer> uniformBuffer = device->InstantiateBuffer(Nz::BufferType_Uniform);
|
||||||
if (!uniformBuffer->Initialize(uniformSize, Nz::BufferUsage_DeviceLocal))
|
if (!uniformBuffer->Initialize(uniformSize, Nz::BufferUsage_DeviceLocal))
|
||||||
|
|
@ -168,6 +303,7 @@ int main()
|
||||||
|
|
||||||
Nz::VulkanBuffer* uniformBufferImpl = static_cast<Nz::VulkanBuffer*>(uniformBuffer.get());
|
Nz::VulkanBuffer* uniformBufferImpl = static_cast<Nz::VulkanBuffer*>(uniformBuffer.get());
|
||||||
descriptorSet.WriteUniformDescriptor(0, uniformBufferImpl->GetBufferHandle(), 0, uniformSize);
|
descriptorSet.WriteUniformDescriptor(0, uniformBufferImpl->GetBufferHandle(), 0, uniformSize);
|
||||||
|
descriptorSet.WriteCombinedImageSamplerDescriptor(1, imageSampler, imageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
|
||||||
Nz::RenderPipelineInfo pipelineInfo;
|
Nz::RenderPipelineInfo pipelineInfo;
|
||||||
pipelineInfo.pipelineLayout = renderPipelineLayout;
|
pipelineInfo.pipelineLayout = renderPipelineLayout;
|
||||||
|
|
@ -185,19 +321,10 @@ int main()
|
||||||
Nz::VulkanRenderPipeline::CreateInfo pipelineCreateInfo = Nz::VulkanRenderPipeline::BuildCreateInfo(pipelineInfo);
|
Nz::VulkanRenderPipeline::CreateInfo pipelineCreateInfo = Nz::VulkanRenderPipeline::BuildCreateInfo(pipelineInfo);
|
||||||
pipelineCreateInfo.pipelineInfo.renderPass = vulkanWindow.GetRenderPass();
|
pipelineCreateInfo.pipelineInfo.renderPass = vulkanWindow.GetRenderPass();
|
||||||
|
|
||||||
Nz::Vk::CommandPool cmdPool;
|
|
||||||
if (!cmdPool.Create(vulkanDevice, 0, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT))
|
|
||||||
{
|
|
||||||
NazaraError("Failed to create rendering cmd pool");
|
|
||||||
return __LINE__;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::array<VkClearValue, 2> clearValues;
|
std::array<VkClearValue, 2> clearValues;
|
||||||
clearValues[0].color = {1.0f, 0.8f, 0.4f, 0.0f};
|
clearValues[0].color = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
clearValues[1].depthStencil = {1.f, 0};
|
clearValues[1].depthStencil = {1.f, 0};
|
||||||
|
|
||||||
Nz::Vk::QueueHandle graphicsQueue = vulkanDevice.GetQueue(0, 0);
|
|
||||||
|
|
||||||
Nz::UInt32 imageCount = vulkanWindow.GetFramebufferCount();
|
Nz::UInt32 imageCount = vulkanWindow.GetFramebufferCount();
|
||||||
std::vector<Nz::Vk::CommandBuffer> renderCmds = cmdPool.AllocateCommandBuffers(imageCount, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
|
std::vector<Nz::Vk::CommandBuffer> renderCmds = cmdPool.AllocateCommandBuffers(imageCount, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
|
||||||
|
|
||||||
|
|
@ -251,7 +378,7 @@ int main()
|
||||||
renderCmd.BeginRenderPass(render_pass_begin_info);
|
renderCmd.BeginRenderPass(render_pass_begin_info);
|
||||||
renderCmd.BindIndexBuffer(indexBufferImpl->GetBufferHandle(), 0, VK_INDEX_TYPE_UINT16);
|
renderCmd.BindIndexBuffer(indexBufferImpl->GetBufferHandle(), 0, VK_INDEX_TYPE_UINT16);
|
||||||
renderCmd.BindVertexBuffer(0, vertexBufferImpl->GetBufferHandle(), 0);
|
renderCmd.BindVertexBuffer(0, vertexBufferImpl->GetBufferHandle(), 0);
|
||||||
renderCmd.BindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, descriptorSet);
|
renderCmd.BindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, vkPipelineLayout->GetPipelineLayout(), 0, descriptorSet);
|
||||||
renderCmd.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, vkPipeline->Get(vulkanWindow.GetRenderPass()));
|
renderCmd.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, vkPipeline->Get(vulkanWindow.GetRenderPass()));
|
||||||
renderCmd.SetScissor(Nz::Recti{0, 0, int(windowSize.x), int(windowSize.y)});
|
renderCmd.SetScissor(Nz::Recti{0, 0, int(windowSize.x), int(windowSize.y)});
|
||||||
renderCmd.SetViewport({0.f, 0.f, float(windowSize.x), float(windowSize.y)}, 0.f, 1.f);
|
renderCmd.SetViewport({0.f, 0.f, float(windowSize.x), float(windowSize.y)}, 0.f, 1.f);
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,14 @@
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
#extension GL_ARB_shading_language_420pack : enable
|
#extension GL_ARB_shading_language_420pack : enable
|
||||||
|
|
||||||
|
layout(binding = 1) uniform sampler2D texSampler;
|
||||||
|
|
||||||
layout (location = 0) in vec3 inColor;
|
layout (location = 0) in vec3 inColor;
|
||||||
|
layout (location = 1) in vec2 outTexCoords;
|
||||||
|
|
||||||
layout (location = 0) out vec4 outFragColor;
|
layout (location = 0) out vec4 outFragColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outFragColor = vec4(inColor, 1.0);
|
outFragColor = texture(texSampler, outTexCoords);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
layout (location = 0) in vec3 inPos;
|
layout (location = 0) in vec3 inPos;
|
||||||
layout (location = 1) in vec3 inColor;
|
layout (location = 1) in vec3 inColor;
|
||||||
|
layout (location = 2) in vec2 inTexCoord;
|
||||||
|
|
||||||
layout (binding = 0) uniform UBO
|
layout (binding = 0) uniform UBO
|
||||||
{
|
{
|
||||||
|
|
@ -14,6 +15,7 @@ layout (binding = 0) uniform UBO
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
layout (location = 0) out vec3 outColor;
|
layout (location = 0) out vec3 outColor;
|
||||||
|
layout (location = 1) out vec2 outTexCoords;
|
||||||
|
|
||||||
out gl_PerVertex
|
out gl_PerVertex
|
||||||
{
|
{
|
||||||
|
|
@ -24,5 +26,6 @@ out gl_PerVertex
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outColor = inColor;
|
outColor = inColor;
|
||||||
|
outTexCoords = inTexCoord;
|
||||||
gl_Position = ubo.projectionMatrix * ubo.viewMatrix * ubo.modelMatrix * vec4(inPos, 1.0);
|
gl_Position = ubo.projectionMatrix * ubo.viewMatrix * ubo.modelMatrix * vec4(inPos, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -10,9 +10,11 @@
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
||||||
#include <Nazara/VulkanRenderer/Config.hpp>
|
#include <Nazara/VulkanRenderer/Config.hpp>
|
||||||
|
#include <Nazara/VulkanRenderer/Wrapper/Device.hpp>
|
||||||
|
#include <Nazara/VulkanRenderer/Wrapper/DescriptorPool.hpp>
|
||||||
|
#include <Nazara/VulkanRenderer/Wrapper/DescriptorSet.hpp>
|
||||||
#include <Nazara/VulkanRenderer/Wrapper/DescriptorSetLayout.hpp>
|
#include <Nazara/VulkanRenderer/Wrapper/DescriptorSetLayout.hpp>
|
||||||
#include <Nazara/VulkanRenderer/Wrapper/PipelineLayout.hpp>
|
#include <Nazara/VulkanRenderer/Wrapper/PipelineLayout.hpp>
|
||||||
#include <Nazara/VulkanRenderer/Wrapper/Device.hpp>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
|
|
@ -23,13 +25,21 @@ namespace Nz
|
||||||
VulkanRenderPipelineLayout() = default;
|
VulkanRenderPipelineLayout() = default;
|
||||||
~VulkanRenderPipelineLayout() = default;
|
~VulkanRenderPipelineLayout() = default;
|
||||||
|
|
||||||
|
Vk::DescriptorSet AllocateDescriptorSet();
|
||||||
|
|
||||||
bool Create(Vk::Device& device, RenderPipelineLayoutInfo layoutInfo);
|
bool Create(Vk::Device& device, RenderPipelineLayoutInfo layoutInfo);
|
||||||
|
|
||||||
inline const Vk::DescriptorSetLayout& GetDescriptorSetLayout() const;
|
inline const Vk::DescriptorSetLayout& GetDescriptorSetLayout() const;
|
||||||
inline const Vk::PipelineLayout& GetPipelineLayout() const;
|
inline const Vk::PipelineLayout& GetPipelineLayout() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct DescriptorPool
|
||||||
|
{
|
||||||
|
Vk::DescriptorPool descriptorPool;
|
||||||
|
};
|
||||||
|
|
||||||
MovablePtr<Vk::Device> m_device;
|
MovablePtr<Vk::Device> m_device;
|
||||||
|
std::vector<DescriptorPool> m_descriptorPools;
|
||||||
Vk::DescriptorSetLayout m_descriptorSetLayout;
|
Vk::DescriptorSetLayout m_descriptorSetLayout;
|
||||||
Vk::PipelineLayout m_pipelineLayout;
|
Vk::PipelineLayout m_pipelineLayout;
|
||||||
RenderPipelineLayoutInfo m_layoutInfo;
|
RenderPipelineLayoutInfo m_layoutInfo;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include <Nazara/VulkanRenderer/Wrapper/PipelineLayout.hpp>
|
#include <Nazara/VulkanRenderer/Wrapper/PipelineLayout.hpp>
|
||||||
#include <Nazara/VulkanRenderer/Wrapper/QueueHandle.hpp>
|
#include <Nazara/VulkanRenderer/Wrapper/QueueHandle.hpp>
|
||||||
#include <Nazara/VulkanRenderer/Wrapper/RenderPass.hpp>
|
#include <Nazara/VulkanRenderer/Wrapper/RenderPass.hpp>
|
||||||
|
#include <Nazara/VulkanRenderer/Wrapper/Sampler.hpp>
|
||||||
#include <Nazara/VulkanRenderer/Wrapper/Semaphore.hpp>
|
#include <Nazara/VulkanRenderer/Wrapper/Semaphore.hpp>
|
||||||
#include <Nazara/VulkanRenderer/Wrapper/ShaderModule.hpp>
|
#include <Nazara/VulkanRenderer/Wrapper/ShaderModule.hpp>
|
||||||
#include <Nazara/VulkanRenderer/Wrapper/Surface.hpp>
|
#include <Nazara/VulkanRenderer/Wrapper/Surface.hpp>
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ namespace Nz
|
||||||
inline void ClearDepthStencilImage(VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue& depthStencil, UInt32 rangeCount, const VkImageSubresourceRange* ranges);
|
inline void ClearDepthStencilImage(VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue& depthStencil, UInt32 rangeCount, const VkImageSubresourceRange* ranges);
|
||||||
|
|
||||||
inline void CopyBuffer(VkBuffer source, VkBuffer target, UInt32 size, UInt32 sourceOffset = 0, UInt32 targetOffset = 0);
|
inline void CopyBuffer(VkBuffer source, VkBuffer target, UInt32 size, UInt32 sourceOffset = 0, UInt32 targetOffset = 0);
|
||||||
|
inline void CopyBufferToImage(VkBuffer source, VkImage target, VkImageLayout targetLayout, UInt32 width, UInt32 height);
|
||||||
|
|
||||||
inline void Draw(UInt32 vertexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, UInt32 firstInstance = 0);
|
inline void Draw(UInt32 vertexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, UInt32 firstInstance = 0);
|
||||||
inline void DrawIndexed(UInt32 indexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, Int32 vertexOffset = 0, UInt32 firstInstance = 0);
|
inline void DrawIndexed(UInt32 indexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, Int32 vertexOffset = 0, UInt32 firstInstance = 0);
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,29 @@ namespace Nz
|
||||||
return m_pool->GetDevice()->vkCmdCopyBuffer(m_handle, source, target, 1, ®ion);
|
return m_pool->GetDevice()->vkCmdCopyBuffer(m_handle, source, target, 1, ®ion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void CommandBuffer::CopyBufferToImage(VkBuffer source, VkImage target, VkImageLayout targetLayout, UInt32 width, UInt32 height)
|
||||||
|
{
|
||||||
|
VkBufferImageCopy region = {
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{ // imageSubresource
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT, //< aspectMask
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
},
|
||||||
|
{ // imageOffset
|
||||||
|
0, 0, 0
|
||||||
|
},
|
||||||
|
{ // imageExtent
|
||||||
|
width, height, 1U
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return m_pool->GetDevice()->vkCmdCopyBufferToImage(m_handle, source, target, targetLayout, 1, ®ion);
|
||||||
|
}
|
||||||
|
|
||||||
inline void CommandBuffer::Draw(UInt32 vertexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
inline void CommandBuffer::Draw(UInt32 vertexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
||||||
{
|
{
|
||||||
return m_pool->GetDevice()->vkCmdDraw(m_handle, vertexCount, instanceCount, firstVertex, firstInstance);
|
return m_pool->GetDevice()->vkCmdDraw(m_handle, vertexCount, instanceCount, firstVertex, firstInstance);
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,13 @@ namespace Nz
|
||||||
|
|
||||||
inline bool IsValid() const;
|
inline bool IsValid() const;
|
||||||
|
|
||||||
|
inline void WriteCombinedImageSamplerDescriptor(UInt32 binding, VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout);
|
||||||
|
inline void WriteCombinedImageSamplerDescriptor(UInt32 binding, const VkDescriptorImageInfo& imageInfo);
|
||||||
|
inline void WriteCombinedImageSamplerDescriptor(UInt32 binding, UInt32 arrayElement, VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout);
|
||||||
|
inline void WriteCombinedImageSamplerDescriptor(UInt32 binding, UInt32 arrayElement, const VkDescriptorImageInfo& imageInfo);
|
||||||
|
inline void WriteCombinedImageSamplerDescriptors(UInt32 binding, UInt32 descriptorCount, const VkDescriptorImageInfo* imageInfo);
|
||||||
|
inline void WriteCombinedImageSamplerDescriptors(UInt32 binding, UInt32 arrayElement, UInt32 descriptorCount, const VkDescriptorImageInfo* imageInfo);
|
||||||
|
|
||||||
inline void WriteUniformDescriptor(UInt32 binding, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range);
|
inline void WriteUniformDescriptor(UInt32 binding, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range);
|
||||||
inline void WriteUniformDescriptor(UInt32 binding, const VkDescriptorBufferInfo& bufferInfo);
|
inline void WriteUniformDescriptor(UInt32 binding, const VkDescriptorBufferInfo& bufferInfo);
|
||||||
inline void WriteUniformDescriptor(UInt32 binding, UInt32 arrayElement, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range);
|
inline void WriteUniformDescriptor(UInt32 binding, UInt32 arrayElement, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range);
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,55 @@ namespace Nz
|
||||||
return m_handle != VK_NULL_HANDLE;
|
return m_handle != VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void DescriptorSet::WriteCombinedImageSamplerDescriptor(UInt32 binding, VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout)
|
||||||
|
{
|
||||||
|
return WriteCombinedImageSamplerDescriptor(binding, 0, sampler, imageView, imageLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void DescriptorSet::WriteCombinedImageSamplerDescriptor(UInt32 binding, const VkDescriptorImageInfo& imageInfo)
|
||||||
|
{
|
||||||
|
return WriteCombinedImageSamplerDescriptor(binding, 0, imageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void DescriptorSet::WriteCombinedImageSamplerDescriptor(UInt32 binding, UInt32 arrayElement, VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout)
|
||||||
|
{
|
||||||
|
VkDescriptorImageInfo imageInfo = {
|
||||||
|
sampler,
|
||||||
|
imageView,
|
||||||
|
imageLayout
|
||||||
|
};
|
||||||
|
|
||||||
|
return WriteCombinedImageSamplerDescriptors(binding, arrayElement, 1U, &imageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void DescriptorSet::WriteCombinedImageSamplerDescriptor(UInt32 binding, UInt32 arrayElement, const VkDescriptorImageInfo& imageInfo)
|
||||||
|
{
|
||||||
|
return WriteCombinedImageSamplerDescriptors(binding, arrayElement, 1U, &imageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void DescriptorSet::WriteCombinedImageSamplerDescriptors(UInt32 binding, UInt32 descriptorCount, const VkDescriptorImageInfo* imageInfo)
|
||||||
|
{
|
||||||
|
return WriteCombinedImageSamplerDescriptors(binding, 0U, descriptorCount, imageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void DescriptorSet::WriteCombinedImageSamplerDescriptors(UInt32 binding, UInt32 arrayElement, UInt32 descriptorCount, const VkDescriptorImageInfo* imageInfo)
|
||||||
|
{
|
||||||
|
VkWriteDescriptorSet writeDescriptorSet = {
|
||||||
|
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
nullptr,
|
||||||
|
m_handle,
|
||||||
|
binding,
|
||||||
|
arrayElement,
|
||||||
|
descriptorCount,
|
||||||
|
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||||
|
imageInfo,
|
||||||
|
nullptr,
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
|
||||||
|
return m_pool->GetDevice()->vkUpdateDescriptorSets(*m_pool->GetDevice(), 1U, &writeDescriptorSet, 0U, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
inline void DescriptorSet::WriteUniformDescriptor(UInt32 binding, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range)
|
inline void DescriptorSet::WriteUniformDescriptor(UInt32 binding, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range)
|
||||||
{
|
{
|
||||||
return WriteUniformDescriptor(binding, 0U, buffer, offset, range);
|
return WriteUniformDescriptor(binding, 0U, buffer, offset, range);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright (C) 2020 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Vulkan Renderer"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_VULKANRENDERER_VKSAMPLER_HPP
|
||||||
|
#define NAZARA_VULKANRENDERER_VKSAMPLER_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequisites.hpp>
|
||||||
|
#include <Nazara/VulkanRenderer/Wrapper/DeviceObject.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
namespace Vk
|
||||||
|
{
|
||||||
|
class Sampler : public DeviceObject<Sampler, VkSampler, VkSamplerCreateInfo>
|
||||||
|
{
|
||||||
|
friend DeviceObject;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Sampler() = default;
|
||||||
|
Sampler(const Sampler&) = delete;
|
||||||
|
Sampler(Sampler&&) = default;
|
||||||
|
~Sampler() = default;
|
||||||
|
|
||||||
|
Sampler& operator=(const Sampler&) = delete;
|
||||||
|
Sampler& operator=(Sampler&&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static inline VkResult CreateHelper(Device& device, const VkSamplerCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkSampler* handle);
|
||||||
|
static inline void DestroyHelper(Device& device, VkSampler handle, const VkAllocationCallbacks* allocator);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/VulkanRenderer/Wrapper/Sampler.inl>
|
||||||
|
|
||||||
|
#endif // NAZARA_VULKANRENDERER_VKSAMPLER_HPP
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright (C) 2020 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Vulkan Renderer"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/VulkanRenderer/Wrapper/Sampler.hpp>
|
||||||
|
#include <Nazara/VulkanRenderer/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
namespace Vk
|
||||||
|
{
|
||||||
|
inline VkResult Sampler::CreateHelper(Device& device, const VkSamplerCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkSampler* handle)
|
||||||
|
{
|
||||||
|
return device.vkCreateSampler(device, createInfo, allocator, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Sampler::DestroyHelper(Device& device, VkSampler handle, const VkAllocationCallbacks* allocator)
|
||||||
|
{
|
||||||
|
return device.vkDestroySampler(device, handle, allocator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/VulkanRenderer/DebugOff.hpp>
|
||||||
|
|
@ -12,6 +12,35 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
Vk::DescriptorSet VulkanRenderPipelineLayout::AllocateDescriptorSet()
|
||||||
|
{
|
||||||
|
// TODO: Watch descriptor set count for each pool
|
||||||
|
for (auto& pool : m_descriptorPools)
|
||||||
|
{
|
||||||
|
Vk::DescriptorSet descriptorSet = pool.descriptorPool.AllocateDescriptorSet(m_descriptorSetLayout);
|
||||||
|
if (descriptorSet)
|
||||||
|
return descriptorSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate a new descriptor pool
|
||||||
|
StackVector<VkDescriptorPoolSize> poolSizes = NazaraStackVector(VkDescriptorPoolSize, m_layoutInfo.bindings.size());
|
||||||
|
|
||||||
|
constexpr UInt32 MaxSet = 100;
|
||||||
|
|
||||||
|
for (const auto& bindingInfo : m_layoutInfo.bindings)
|
||||||
|
{
|
||||||
|
VkDescriptorPoolSize& poolSize = poolSizes.emplace_back();
|
||||||
|
poolSize.descriptorCount = MaxSet;
|
||||||
|
poolSize.type = ToVulkan(bindingInfo.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorPool pool;
|
||||||
|
if (!pool.descriptorPool.Create(*m_device, MaxSet, UInt32(poolSizes.size()), poolSizes.data(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return m_descriptorPools.emplace_back(std::move(pool)).descriptorPool.AllocateDescriptorSet(m_descriptorSetLayout);
|
||||||
|
}
|
||||||
|
|
||||||
bool VulkanRenderPipelineLayout::Create(Vk::Device& device, RenderPipelineLayoutInfo layoutInfo)
|
bool VulkanRenderPipelineLayout::Create(Vk::Device& device, RenderPipelineLayoutInfo layoutInfo)
|
||||||
{
|
{
|
||||||
m_device = &device;
|
m_device = &device;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue