work
This commit is contained in:
parent
97008e92ca
commit
0b97e6eeec
|
@ -53,11 +53,19 @@ namespace orange
|
||||||
T& back() { return data[size - 1]; }
|
T& back() { return data[size - 1]; }
|
||||||
const T& back() const { return data[size - 1]; }
|
const T& back() const { return data[size - 1]; }
|
||||||
|
|
||||||
|
void Copy(void* dst)
|
||||||
|
{
|
||||||
|
memcpy(dst, data, sizeof(T) * size);
|
||||||
|
}
|
||||||
|
|
||||||
T* data;
|
T* data;
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
using BufferView = Span<uint8_t>;
|
struct BufferView : public Span<uint8_t>
|
||||||
|
{
|
||||||
|
using Span<uint8_t>::Span;
|
||||||
|
};
|
||||||
|
|
||||||
struct StringView : public Span<const char>
|
struct StringView : public Span<const char>
|
||||||
{
|
{
|
||||||
|
@ -69,7 +77,7 @@ namespace orange
|
||||||
|
|
||||||
struct Buffer : public BufferView
|
struct Buffer : public BufferView
|
||||||
{
|
{
|
||||||
using BufferView::Span;
|
using BufferView::BufferView;
|
||||||
|
|
||||||
~Buffer() { delete[] data; }
|
~Buffer() { delete[] data; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,8 +28,8 @@ namespace orange
|
||||||
new (Ptr<T>()) T(Forward(args)...);
|
new (Ptr<T>()) T(Forward(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> T* Ptr() { return reinterpret_cast<T*>(data.data); }
|
template <typename T> T* Ptr() { return reinterpret_cast<T*> (data.data); }
|
||||||
template <typename T> const T* Ptr() const { return reinterpret_cast<T*>(data.data); }
|
template <typename T> const T* Ptr() const { return reinterpret_cast<const T*>(data.data); }
|
||||||
|
|
||||||
template <typename T> T& Get() { return *Ptr<T>(); }
|
template <typename T> T& Get() { return *Ptr<T>(); }
|
||||||
template <typename T> const T& Get() const { return *Ptr<T>(); }
|
template <typename T> const T& Get() const { return *Ptr<T>(); }
|
||||||
|
|
|
@ -166,6 +166,11 @@ namespace orange
|
||||||
return FindIdx(x) != InvalidIdx;
|
return FindIdx(x) != InvalidIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Copy(void* dst)
|
||||||
|
{
|
||||||
|
memcpy(dst, Ptr(0), sizeof(T) * m_size);
|
||||||
|
}
|
||||||
|
|
||||||
T& operator [] (size_t idx) { return *Ptr(idx); }
|
T& operator [] (size_t idx) { return *Ptr(idx); }
|
||||||
const T& operator [] (size_t idx) const { return *Ptr(idx); }
|
const T& operator [] (size_t idx) const { return *Ptr(idx); }
|
||||||
|
|
||||||
|
@ -183,6 +188,8 @@ namespace orange
|
||||||
|
|
||||||
operator Span<T>() { return Span<T>(*this); }
|
operator Span<T>() { return Span<T>(*this); }
|
||||||
|
|
||||||
|
operator BufferView() { return BufferView{ reinterpret_cast<uint8_t *>(Ptr(0)), sizeof(T) * m_size}; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Storage = AlignedStorage<sizeof(T), alignof(T)>;
|
using Storage = AlignedStorage<sizeof(T), alignof(T)>;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
namespace orange
|
namespace orange
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,16 +8,53 @@
|
||||||
|
|
||||||
namespace orange
|
namespace orange
|
||||||
{
|
{
|
||||||
class BufferPool
|
struct BufferSlice
|
||||||
{
|
{
|
||||||
|
VkBuffer buffer;
|
||||||
|
VkDeviceSize offset;
|
||||||
|
VkDeviceSize size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GPUMemoryBuffer
|
||||||
|
{
|
||||||
|
VkDeviceMemory memory;
|
||||||
|
VkBuffer buffer;
|
||||||
|
VkDeviceSize size;
|
||||||
|
void* ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BufferPooler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BufferPooler(GPUMemoryBuffer buffer)
|
||||||
|
: m_buffer{ buffer } {}
|
||||||
|
|
||||||
|
Result<BufferSlice> AllocSlice(VkDeviceSize size)
|
||||||
|
{
|
||||||
|
BufferSlice slice{ m_buffer.buffer, m_offset, size };
|
||||||
|
|
||||||
|
if (m_offset + size > m_buffer.size)
|
||||||
|
return Result<BufferSlice>::Error();
|
||||||
|
|
||||||
|
m_offset += size;
|
||||||
|
|
||||||
|
return Result<BufferSlice>::Success(slice);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
VkBuffer m_buffer;
|
GPUMemoryBuffer m_buffer = {};
|
||||||
VkDeviceAddress m_va;
|
VkDeviceSize m_offset = 0u;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using VulkanResult = Result<T, VkResult, VK_SUCCESS, VK_ERROR_UNKNOWN, VK_ERROR_UNKNOWN>;
|
using VulkanResult = Result<T, VkResult, VK_SUCCESS, VK_ERROR_UNKNOWN, VK_ERROR_UNKNOWN>;
|
||||||
|
|
||||||
|
struct VkMemoryTypes
|
||||||
|
{
|
||||||
|
uint32_t cpuTypeIdx = -1;
|
||||||
|
uint32_t gpuOnlyTypeIdx = -1;
|
||||||
|
uint32_t gpuHostVisibleTypeIdx = -1;
|
||||||
|
};
|
||||||
|
|
||||||
class RenderContext
|
class RenderContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -31,10 +68,11 @@ namespace orange
|
||||||
VkQueue Queue() const { return m_queue; }
|
VkQueue Queue() const { return m_queue; }
|
||||||
VkCommandPool CommandPool() const { return m_commandPool; }
|
VkCommandPool CommandPool() const { return m_commandPool; }
|
||||||
|
|
||||||
VulkanResult<VkFence> CreateFence(bool signalled);
|
VulkanResult<VkFence> CreateFence(bool signalled);
|
||||||
VulkanResult<VkSemaphore> CreateSemaphore();
|
VulkanResult<VkSemaphore> CreateSemaphore();
|
||||||
VulkanResult<VoidResult> BeginCommandBuffer(VkCommandBuffer buffer);
|
VulkanResult<VoidResult> BeginCommandBuffer(VkCommandBuffer buffer);
|
||||||
VulkanResult<VoidResult> EndCommandBuffer(VkCommandBuffer buffer);
|
VulkanResult<VoidResult> EndCommandBuffer(VkCommandBuffer buffer);
|
||||||
|
VulkanResult<GPUMemoryBuffer> CreateBuffer(VkDeviceSize size);
|
||||||
|
|
||||||
VulkanResult<VkShaderModule> CreateShader(Span<const uint32_t> code);
|
VulkanResult<VkShaderModule> CreateShader(Span<const uint32_t> code);
|
||||||
protected:
|
protected:
|
||||||
|
@ -42,12 +80,52 @@ namespace orange
|
||||||
RenderContext(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device,
|
RenderContext(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device,
|
||||||
VkQueue queue, VkCommandPool commandPool)
|
VkQueue queue, VkCommandPool commandPool)
|
||||||
: m_instance{ instance }, m_physicalDevice{ physicalDevice }, m_device{ device }
|
: m_instance{ instance }, m_physicalDevice{ physicalDevice }, m_device{ device }
|
||||||
, m_queue{ queue }, m_commandPool{ commandPool } {}
|
, m_queue{ queue }, m_commandPool{ commandPool }
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceMemoryProperties memoryProps;
|
||||||
|
vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &memoryProps);
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t* ptr;
|
||||||
|
VkMemoryPropertyFlags flags;
|
||||||
|
} memoryTypeMapping[] =
|
||||||
|
{
|
||||||
|
{ &m_memoryTypes.gpuHostVisibleTypeIdx,
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||||
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT },
|
||||||
|
|
||||||
|
{ &m_memoryTypes.gpuOnlyTypeIdx,
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT },
|
||||||
|
|
||||||
|
{ &m_memoryTypes.cpuTypeIdx,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||||
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& mapping : memoryTypeMapping)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < memoryProps.memoryTypeCount; i++)
|
||||||
|
{
|
||||||
|
if (memoryProps.memoryTypes[i].propertyFlags & mapping.flags)
|
||||||
|
{
|
||||||
|
*mapping.ptr = i;
|
||||||
|
|
||||||
|
if (memoryProps.memoryTypes[i].propertyFlags == mapping.flags)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
VkInstance m_instance = VK_NULL_HANDLE;
|
VkInstance m_instance = VK_NULL_HANDLE;
|
||||||
VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE;
|
||||||
VkDevice m_device = VK_NULL_HANDLE;
|
VkDevice m_device = VK_NULL_HANDLE;
|
||||||
VkQueue m_queue = VK_NULL_HANDLE;
|
VkQueue m_queue = VK_NULL_HANDLE;
|
||||||
VkCommandPool m_commandPool = VK_NULL_HANDLE;
|
VkCommandPool m_commandPool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
VkMemoryTypes m_memoryTypes{};
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -11,8 +11,9 @@
|
||||||
#include <Orange/Render/Window.h>
|
#include <Orange/Render/Window.h>
|
||||||
#include <Orange/Render/RenderContext.h>
|
#include <Orange/Render/RenderContext.h>
|
||||||
#include <Orange/Render/Swapchain.h>
|
#include <Orange/Render/Swapchain.h>
|
||||||
|
#include <Orange/Render/VulkanHelpers.h>
|
||||||
|
|
||||||
#include <vs_Triangle.h>
|
#include <vs_Mesh.h>
|
||||||
#include <fs_DebugVertColor.h>
|
#include <fs_DebugVertColor.h>
|
||||||
|
|
||||||
using namespace orange;
|
using namespace orange;
|
||||||
|
@ -35,19 +36,30 @@ enum class MeshVertexType
|
||||||
Skinned,
|
Skinned,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef offsetof2
|
||||||
|
#define offsetof2(type, member) size_t(uintptr_t(&((type*)0)->member))
|
||||||
|
#endif
|
||||||
|
|
||||||
struct StaticVertex
|
struct StaticVertex
|
||||||
{
|
{
|
||||||
vec3 pos;
|
vec3 pos;
|
||||||
vec2 uv;
|
vec2 uv;
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
vec3 tangent;
|
//vec3 tangent;
|
||||||
|
|
||||||
|
static constexpr VkVertexInputAttributeDescription Attributes[] =
|
||||||
|
{
|
||||||
|
{ .location = 0, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, pos)) },
|
||||||
|
{ .location = 1, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, uv)) },
|
||||||
|
{ .location = 2, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, normal)) },
|
||||||
|
};
|
||||||
|
|
||||||
bool operator == (const StaticVertex& other) const
|
bool operator == (const StaticVertex& other) const
|
||||||
{
|
{
|
||||||
return pos == other.pos &&
|
return pos == other.pos &&
|
||||||
uv == other.uv &&
|
uv == other.uv &&
|
||||||
normal == other.normal &&
|
normal == other.normal;// &&
|
||||||
tangent == other.tangent;
|
//tangent == other.tangent;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,7 +72,7 @@ struct SkinnedVertex : public StaticVertex
|
||||||
return pos == other.pos &&
|
return pos == other.pos &&
|
||||||
uv == other.uv &&
|
uv == other.uv &&
|
||||||
normal == other.normal &&
|
normal == other.normal &&
|
||||||
tangent == other.tangent &&
|
//tangent == other.tangent &&
|
||||||
boneIndices == other.boneIndices &&
|
boneIndices == other.boneIndices &&
|
||||||
boneWeights == other.boneWeights;
|
boneWeights == other.boneWeights;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +86,7 @@ struct MeshVertexData
|
||||||
MeshVertexData(MeshVertexType type)
|
MeshVertexData(MeshVertexType type)
|
||||||
: vertexType(type)
|
: vertexType(type)
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(vertexType)
|
||||||
{
|
{
|
||||||
case MeshVertexType::Static:
|
case MeshVertexType::Static:
|
||||||
vertices.Construct<Vector<StaticVertex>>();
|
vertices.Construct<Vector<StaticVertex>>();
|
||||||
|
@ -97,6 +109,27 @@ struct MeshVertexData
|
||||||
return vertices.Get<Vector<SkinnedVertex>>();
|
return vertices.Get<Vector<SkinnedVertex>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BufferView View()
|
||||||
|
{
|
||||||
|
switch(vertexType)
|
||||||
|
{
|
||||||
|
case MeshVertexType::Static:
|
||||||
|
return GetStaticVertices();
|
||||||
|
break;
|
||||||
|
case MeshVertexType::Skinned:
|
||||||
|
return GetSkinnedVertices();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return BufferView{ nullptr, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t VertexCount() const
|
||||||
|
{
|
||||||
|
// Type doesn't matter here, just want to grab m_size.
|
||||||
|
return uint32_t(vertices.Get<Vector<uint8_t>>().Size());
|
||||||
|
}
|
||||||
|
|
||||||
MeshVertexType vertexType;
|
MeshVertexType vertexType;
|
||||||
Variant<Vector<StaticVertex>, Vector<SkinnedVertex>> vertices;
|
Variant<Vector<StaticVertex>, Vector<SkinnedVertex>> vertices;
|
||||||
};
|
};
|
||||||
|
@ -134,16 +167,14 @@ Result<MeshData> ParseOBJ(StringView buffer)
|
||||||
stream::ConsumeSpace(obj, end);
|
stream::ConsumeSpace(obj, end);
|
||||||
if (auto r_float = stream::Parse<float>(obj, end))
|
if (auto r_float = stream::Parse<float>(obj, end))
|
||||||
vtx[i] = *r_float;
|
vtx[i] = *r_float;
|
||||||
else
|
|
||||||
return Result<MeshData>::Error();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element == "v")
|
if (element == "v")
|
||||||
positions.EmplaceBack(vtx[0], vtx[1], vtx[2]);
|
positions.EmplaceBack(vtx[0], vtx[1], vtx[2]);
|
||||||
else if (element == "vt")
|
else if (element == "vt")
|
||||||
normals.EmplaceBack(vtx[0], vtx[1], vtx[2]);
|
|
||||||
else if (element == "vn")
|
|
||||||
uvs.EmplaceBack(vtx[0], vtx[1]);
|
uvs.EmplaceBack(vtx[0], vtx[1]);
|
||||||
|
else if (element == "vn")
|
||||||
|
normals.EmplaceBack(vtx[0], vtx[1], vtx[2]);
|
||||||
}
|
}
|
||||||
else if (element == "g" || element == "o")
|
else if (element == "g" || element == "o")
|
||||||
{
|
{
|
||||||
|
@ -230,17 +261,135 @@ int main(int argc, char** argv)
|
||||||
if (!r_swapchain)
|
if (!r_swapchain)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/chair.obj");
|
//auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/chair.obj");
|
||||||
|
auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/cube.obj");
|
||||||
if (!r_objData)
|
if (!r_objData)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
auto r_mesh = ParseOBJ(*r_objData);
|
auto r_mesh = ParseOBJ(*r_objData);
|
||||||
|
|
||||||
auto r_vs = r_renderContext->CreateShader(vs_Triangle);
|
auto r_vs = r_renderContext->CreateShader(vs_Mesh);
|
||||||
if (!r_vs) return 1;
|
if (!r_vs) return 1;
|
||||||
auto r_fs = r_renderContext->CreateShader(fs_DebugVertColor);
|
auto r_fs = r_renderContext->CreateShader(fs_DebugVertColor);
|
||||||
if (!r_fs) return 1;
|
if (!r_fs) return 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
VkSamplerCreateInfo samplerInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||||
|
.magFilter = VK_FILTER_LINEAR,
|
||||||
|
.minFilter = VK_FILTER_LINEAR,
|
||||||
|
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR,
|
||||||
|
.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
.mipLodBias = 0.0f,
|
||||||
|
.anisotropyEnable = VK_TRUE,
|
||||||
|
.maxAnisotropy = 16.0f,
|
||||||
|
.minLod = -FLT_MAX,
|
||||||
|
.maxLod = FLT_MAX,
|
||||||
|
};
|
||||||
|
VkSampler sampler = VK_NULL_HANDLE;
|
||||||
|
vkCreateSampler(r_renderContext->Device(), &samplerInfo, nullptr, &sampler);
|
||||||
|
|
||||||
|
constexpr uint32_t MaxBindlessResources = 32768;
|
||||||
|
VkDescriptorPoolSize bindlessPoolSizes[] =
|
||||||
|
{
|
||||||
|
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MaxBindlessResources }
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorPoolCreateInfo poolInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||||
|
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
|
||||||
|
.maxSets = MaxBindlessResources * Size(bindlessPoolSizes),
|
||||||
|
.poolSizeCount = uint32_t(Size(bindlessPoolSizes)),
|
||||||
|
.pPoolSizes = bindlessPoolSizes,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
|
||||||
|
vkCreateDescriptorPool(r_renderContext->Device(), &poolInfo, nullptr, &descriptorPool);
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutBinding layoutBindings[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.binding = 0,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
|
.descriptorCount = MaxBindlessResources,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_ALL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.binding = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
||||||
|
.descriptorCount = MaxBindlessResources,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_ALL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.binding = 2,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
|
.pImmutableSamplers = &sampler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.binding = 3,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.descriptorCount = MaxBindlessResources,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr VkDescriptorBindingFlags bindingFlags[] =
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT,
|
||||||
|
};
|
||||||
|
|
||||||
|
Assert(Size(bindingFlags) == Size(layoutBindings));
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutBindingFlagsCreateInfo layoutBindingFlagsInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT,
|
||||||
|
.bindingCount = Size(bindingFlags),
|
||||||
|
.pBindingFlags = bindingFlags,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutCreateInfo layoutInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||||
|
.pNext = &layoutBindingFlagsInfo,
|
||||||
|
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT,
|
||||||
|
.bindingCount = Size(layoutBindings),
|
||||||
|
.pBindings = layoutBindings,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
|
||||||
|
vkCreateDescriptorSetLayout(r_renderContext->Device(), &layoutInfo, nullptr, &descriptorSetLayout);
|
||||||
|
|
||||||
|
VkDescriptorSetVariableDescriptorCountAllocateInfoEXT descriptorCountAllocInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT,
|
||||||
|
.descriptorSetCount = 1,
|
||||||
|
.pDescriptorCounts = &MaxBindlessResources,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||||
|
.pNext = &descriptorCountAllocInfo,
|
||||||
|
.descriptorPool = descriptorPool,
|
||||||
|
.descriptorSetCount = 1,
|
||||||
|
.pSetLayouts = &descriptorSetLayout,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
|
||||||
|
vkAllocateDescriptorSets(r_renderContext->Device(), &descriptorSetAllocInfo, &descriptorSet);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo stages[] =
|
VkPipelineShaderStageCreateInfo stages[] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -270,13 +419,20 @@ int main(int argc, char** argv)
|
||||||
.pDynamicStates = dynamicStates.Data(),
|
.pDynamicStates = dynamicStates.Data(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VkVertexInputBindingDescription inputBindingDescription =
|
||||||
|
{
|
||||||
|
.binding = 0,
|
||||||
|
.stride = sizeof(StaticVertex),
|
||||||
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
||||||
|
};
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputInfo =
|
VkPipelineVertexInputStateCreateInfo vertexInputInfo =
|
||||||
{
|
{
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||||
.vertexBindingDescriptionCount = 0u,
|
.vertexBindingDescriptionCount = 1u,
|
||||||
.pVertexBindingDescriptions = nullptr,
|
.pVertexBindingDescriptions = &inputBindingDescription,
|
||||||
.vertexAttributeDescriptionCount = 0u,
|
.vertexAttributeDescriptionCount = Size(StaticVertex::Attributes),
|
||||||
.pVertexAttributeDescriptions = nullptr,
|
.pVertexAttributeDescriptions = StaticVertex::Attributes,
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo =
|
VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo =
|
||||||
|
@ -298,6 +454,7 @@ int main(int argc, char** argv)
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||||
.cullMode = VK_CULL_MODE_NONE, //VK_CULL_MODE_BACK_BIT,
|
.cullMode = VK_CULL_MODE_NONE, //VK_CULL_MODE_BACK_BIT,
|
||||||
.frontFace = VK_FRONT_FACE_CLOCKWISE,
|
.frontFace = VK_FRONT_FACE_CLOCKWISE,
|
||||||
|
.lineWidth = 1.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPipelineMultisampleStateCreateInfo multisampleInfo =
|
VkPipelineMultisampleStateCreateInfo multisampleInfo =
|
||||||
|
@ -321,12 +478,14 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo =
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo =
|
||||||
{
|
{
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
|
.setLayoutCount = 1,
|
||||||
|
.pSetLayouts = &descriptorSetLayout
|
||||||
};
|
};
|
||||||
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
|
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
|
||||||
vkCreatePipelineLayout(r_renderContext->Device(), &pipelineLayoutInfo, nullptr, &pipelineLayout);
|
vkCreatePipelineLayout(r_renderContext->Device(), &pipelineLayoutInfo, nullptr, &pipelineLayout);
|
||||||
|
|
||||||
VkFormat format = r_swapchain->Format();
|
VkFormat format = FormatToSrgbFormat(r_swapchain->Format());
|
||||||
VkPipelineRenderingCreateInfo renderingInfo =
|
VkPipelineRenderingCreateInfo renderingInfo =
|
||||||
{
|
{
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
||||||
|
@ -359,6 +518,57 @@ int main(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto r_buffer = r_renderContext->CreateBuffer(256 * 1024 * 1024);
|
||||||
|
if (!r_buffer)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
VkBufferViewCreateInfo bufferViewInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
|
||||||
|
.buffer = r_buffer->buffer,
|
||||||
|
.format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
.offset = 0,
|
||||||
|
.range = r_buffer->size,
|
||||||
|
};
|
||||||
|
VkBufferView bufferView = VK_NULL_HANDLE;
|
||||||
|
vkCreateBufferView(r_renderContext->Device(), &bufferViewInfo, nullptr, &bufferView);
|
||||||
|
|
||||||
|
VkDescriptorBufferInfo bufferInfo =
|
||||||
|
{
|
||||||
|
.buffer = r_buffer->buffer,
|
||||||
|
.offset = 0,
|
||||||
|
.range = r_buffer->size,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkWriteDescriptorSet writeDescriptorSet[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.dstSet = descriptorSet,
|
||||||
|
.dstBinding = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
|
.pBufferInfo = &bufferInfo,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.dstSet = descriptorSet,
|
||||||
|
.dstBinding = 1,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
||||||
|
.pTexelBufferView = &bufferView,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
vkUpdateDescriptorSets(r_renderContext->Device(), Size(writeDescriptorSet), writeDescriptorSet, 0, nullptr);
|
||||||
|
|
||||||
|
auto pooler = BufferPooler{ *r_buffer };
|
||||||
|
auto meshData = r_mesh->vertexData.View();
|
||||||
|
auto vertexSlice = *pooler.AllocSlice(meshData.size);
|
||||||
|
auto indexSlice = *pooler.AllocSlice(r_mesh->indices.Size() * sizeof(uint16_t));
|
||||||
|
|
||||||
|
meshData.Copy ((uint8_t*)(r_buffer->ptr) + vertexSlice.offset);
|
||||||
|
r_mesh->indices.Copy((uint8_t*)(r_buffer->ptr) + indexSlice.offset);
|
||||||
|
|
||||||
while (r_window->Update())
|
while (r_window->Update())
|
||||||
{
|
{
|
||||||
VkCommandBuffer cmdBuf = r_swapchain->CommandBuffer();
|
VkCommandBuffer cmdBuf = r_swapchain->CommandBuffer();
|
||||||
|
@ -384,6 +594,29 @@ int main(int argc, char** argv)
|
||||||
vkCmdSetScissor(cmdBuf, 0, 1, &scissor);
|
vkCmdSetScissor(cmdBuf, 0, 1, &scissor);
|
||||||
|
|
||||||
vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||||
|
vkCmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
|
||||||
|
|
||||||
|
vkCmdBindVertexBuffers2(cmdBuf, 0, 1, &vertexSlice.buffer, &vertexSlice.offset, &vertexSlice.size, nullptr);
|
||||||
|
vkCmdBindIndexBuffer(cmdBuf, r_buffer->buffer, indexSlice.offset, VK_INDEX_TYPE_UINT16);
|
||||||
|
|
||||||
|
const VkImageMemoryBarrier undefinedToColorBarrier =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||||
|
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
|
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
|
.image = r_swapchain->Image(),
|
||||||
|
.subresourceRange = FirstMipSubresourceRange,
|
||||||
|
};
|
||||||
|
|
||||||
|
vkCmdPipelineBarrier(
|
||||||
|
cmdBuf,
|
||||||
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||||
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
0,
|
||||||
|
0, nullptr,
|
||||||
|
0, nullptr,
|
||||||
|
1, &undefinedToColorBarrier);
|
||||||
|
|
||||||
const VkRenderingAttachmentInfoKHR attachmentInfo =
|
const VkRenderingAttachmentInfoKHR attachmentInfo =
|
||||||
{
|
{
|
||||||
|
@ -404,8 +637,27 @@ int main(int argc, char** argv)
|
||||||
.pColorAttachments = &attachmentInfo,
|
.pColorAttachments = &attachmentInfo,
|
||||||
};
|
};
|
||||||
vkCmdBeginRendering(cmdBuf, &renderInfo);
|
vkCmdBeginRendering(cmdBuf, &renderInfo);
|
||||||
vkCmdDraw(cmdBuf, 3, 1, 0, 0);
|
vkCmdDrawIndexed(cmdBuf, r_mesh->vertexData.VertexCount(), 1, 0, 0, 0);
|
||||||
vkCmdEndRendering(cmdBuf);
|
vkCmdEndRendering(cmdBuf);
|
||||||
|
|
||||||
|
const VkImageMemoryBarrier colorToPresentBarrier =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||||
|
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
|
.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
|
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||||
|
.image = r_swapchain->Image(),
|
||||||
|
.subresourceRange = FirstMipSubresourceRange,
|
||||||
|
};
|
||||||
|
|
||||||
|
vkCmdPipelineBarrier(
|
||||||
|
cmdBuf,
|
||||||
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||||
|
0,
|
||||||
|
0, nullptr,
|
||||||
|
0, nullptr,
|
||||||
|
1, &colorToPresentBarrier);
|
||||||
}
|
}
|
||||||
r_renderContext->EndCommandBuffer(cmdBuf);
|
r_renderContext->EndCommandBuffer(cmdBuf);
|
||||||
r_swapchain->Present();
|
r_swapchain->Present();
|
||||||
|
|
|
@ -115,13 +115,50 @@ namespace orange
|
||||||
const char* deviceExtensions[] =
|
const char* deviceExtensions[] =
|
||||||
{
|
{
|
||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||||
|
VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME,
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures features{};
|
VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES,
|
||||||
|
.dynamicRendering = VK_TRUE,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
|
||||||
|
.pNext = &dynamicRenderingFeatures,
|
||||||
|
.shaderInputAttachmentArrayDynamicIndexing = VK_FALSE,
|
||||||
|
.shaderUniformTexelBufferArrayDynamicIndexing = VK_TRUE,
|
||||||
|
.shaderStorageTexelBufferArrayDynamicIndexing = VK_TRUE,
|
||||||
|
.shaderUniformBufferArrayNonUniformIndexing = VK_TRUE,
|
||||||
|
.shaderSampledImageArrayNonUniformIndexing = VK_TRUE,
|
||||||
|
.shaderStorageBufferArrayNonUniformIndexing = VK_TRUE,
|
||||||
|
.shaderStorageImageArrayNonUniformIndexing = VK_TRUE,
|
||||||
|
.shaderInputAttachmentArrayNonUniformIndexing = VK_FALSE,
|
||||||
|
.shaderUniformTexelBufferArrayNonUniformIndexing = VK_TRUE,
|
||||||
|
.shaderStorageTexelBufferArrayNonUniformIndexing = VK_TRUE,
|
||||||
|
.descriptorBindingUniformBufferUpdateAfterBind = VK_TRUE,
|
||||||
|
.descriptorBindingSampledImageUpdateAfterBind = VK_TRUE,
|
||||||
|
.descriptorBindingStorageImageUpdateAfterBind = VK_TRUE,
|
||||||
|
.descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE,
|
||||||
|
.descriptorBindingUniformTexelBufferUpdateAfterBind = VK_TRUE,
|
||||||
|
.descriptorBindingStorageTexelBufferUpdateAfterBind = VK_TRUE,
|
||||||
|
.descriptorBindingUpdateUnusedWhilePending = VK_TRUE,
|
||||||
|
.descriptorBindingPartiallyBound = VK_TRUE,
|
||||||
|
.descriptorBindingVariableDescriptorCount = VK_TRUE,
|
||||||
|
.runtimeDescriptorArray = VK_TRUE,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPhysicalDeviceFeatures features
|
||||||
|
{
|
||||||
|
.samplerAnisotropy = VK_TRUE,
|
||||||
|
};
|
||||||
|
|
||||||
VkDeviceCreateInfo deviceInfo =
|
VkDeviceCreateInfo deviceInfo =
|
||||||
{
|
{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
||||||
|
.pNext = &descriptorIndexingFeatures,
|
||||||
.queueCreateInfoCount = 1,
|
.queueCreateInfoCount = 1,
|
||||||
.pQueueCreateInfos = &queueInfo,
|
.pQueueCreateInfos = &queueInfo,
|
||||||
.enabledExtensionCount = Size(deviceExtensions),
|
.enabledExtensionCount = Size(deviceExtensions),
|
||||||
|
|
|
@ -72,4 +72,44 @@ namespace orange
|
||||||
|
|
||||||
return VulkanResult<VkShaderModule>::Success(module);
|
return VulkanResult<VkShaderModule>::Success(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VulkanResult<GPUMemoryBuffer> RenderContext::CreateBuffer(VkDeviceSize size)
|
||||||
|
{
|
||||||
|
VkMemoryAllocateInfo memoryInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||||
|
.allocationSize = size,
|
||||||
|
.memoryTypeIndex = m_memoryTypes.gpuHostVisibleTypeIdx,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDeviceMemory memory;
|
||||||
|
VkResult res = VK_SUCCESS;
|
||||||
|
if ((res = vkAllocateMemory(m_device, &memoryInfo, nullptr, &memory)) != VK_SUCCESS)
|
||||||
|
return VulkanResult<GPUMemoryBuffer>::Error(res);
|
||||||
|
|
||||||
|
void* data = nullptr;
|
||||||
|
if ((res = vkMapMemory(m_device, memory, 0, size, 0, &data)) != VK_SUCCESS)
|
||||||
|
return VulkanResult<GPUMemoryBuffer>::Error(res);
|
||||||
|
|
||||||
|
VkBufferCreateInfo bufferInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
|
.size = size,
|
||||||
|
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||||
|
VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
|
||||||
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
|
||||||
|
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
|
||||||
|
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkBuffer buffer = VK_NULL_HANDLE;
|
||||||
|
if ((res = vkCreateBuffer(m_device, &bufferInfo, nullptr, &buffer)) != VK_SUCCESS)
|
||||||
|
return VulkanResult<GPUMemoryBuffer>::Error(res);
|
||||||
|
|
||||||
|
if ((res = vkBindBufferMemory(m_device, buffer, memory, 0)) != VK_SUCCESS)
|
||||||
|
return VulkanResult<GPUMemoryBuffer>::Error(res);
|
||||||
|
|
||||||
|
return VulkanResult<GPUMemoryBuffer>::Success(memory, buffer, size, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 inPos;
|
||||||
|
layout(location = 1) in vec2 inUV;
|
||||||
|
layout(location = 2) in vec3 inNormal;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
vec3 colors[3] = vec3[]
|
||||||
|
(
|
||||||
|
vec3(1.0, 0.0, 0.0),
|
||||||
|
vec3(0.0, 1.0, 0.0),
|
||||||
|
vec3(0.0, 0.0, 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(inPos, 1.0);
|
||||||
|
outColor = vec4(colors[gl_VertexIndex], 1.0);
|
||||||
|
}
|
|
@ -77,9 +77,24 @@ namespace orange
|
||||||
|
|
||||||
const VkExtent2D extent = ChooseSwapExtent(capabilities);
|
const VkExtent2D extent = ChooseSwapExtent(capabilities);
|
||||||
|
|
||||||
|
VkFormat viewFormats[2] =
|
||||||
|
{
|
||||||
|
r_format->format,
|
||||||
|
FormatToSrgbFormat(r_format->format),
|
||||||
|
};
|
||||||
|
|
||||||
|
VkImageFormatListCreateInfo formatListInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
|
||||||
|
.viewFormatCount = Size(viewFormats),
|
||||||
|
.pViewFormats = viewFormats,
|
||||||
|
};
|
||||||
|
|
||||||
VkSwapchainCreateInfoKHR swapchainInfo =
|
VkSwapchainCreateInfoKHR swapchainInfo =
|
||||||
{
|
{
|
||||||
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
||||||
|
.pNext = &formatListInfo,
|
||||||
|
.flags = VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR,
|
||||||
.surface = surface,
|
.surface = surface,
|
||||||
.minImageCount = ChooseImageCount(capabilities),
|
.minImageCount = ChooseImageCount(capabilities),
|
||||||
.imageFormat = r_format->format,
|
.imageFormat = r_format->format,
|
||||||
|
@ -171,6 +186,8 @@ namespace orange
|
||||||
|
|
||||||
void Swapchain::Present()
|
void Swapchain::Present()
|
||||||
{
|
{
|
||||||
|
vkResetFences(m_ctx.Device(), 1, &m_inFlightFences[m_currentFrame]);
|
||||||
|
|
||||||
const VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
const VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
VkSubmitInfo submitInfo =
|
VkSubmitInfo submitInfo =
|
||||||
{
|
{
|
||||||
|
@ -209,10 +226,9 @@ namespace orange
|
||||||
|
|
||||||
m_currentFrame = (m_currentFrame + 1) % DefaultFramesInFlight;
|
m_currentFrame = (m_currentFrame + 1) % DefaultFramesInFlight;
|
||||||
|
|
||||||
vkResetCommandBuffer(m_commandBuffers[m_currentFrame], 0u);
|
|
||||||
|
|
||||||
vkWaitForFences(m_ctx.Device(), 1, &m_inFlightFences[m_currentFrame], VK_TRUE, UINT64_MAX);
|
vkWaitForFences(m_ctx.Device(), 1, &m_inFlightFences[m_currentFrame], VK_TRUE, UINT64_MAX);
|
||||||
vkResetFences(m_ctx.Device(), 1, &m_inFlightFences[m_currentFrame]);
|
|
||||||
vkAcquireNextImageKHR(m_ctx.Device(), m_swapchain, ~0u, m_imageAvailableSemaphores[m_currentFrame], VK_NULL_HANDLE, &m_currentImage);
|
vkAcquireNextImageKHR(m_ctx.Device(), m_swapchain, ~0u, m_imageAvailableSemaphores[m_currentFrame], VK_NULL_HANDLE, &m_currentImage);
|
||||||
|
|
||||||
|
vkResetCommandBuffer(m_commandBuffers[m_currentFrame], 0u);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
orange_shaders = glsl_generator.process([
|
orange_shaders = glsl_generator.process([
|
||||||
'Render/Shaders/fs_DebugVertColor.frag',
|
'Render/Shaders/fs_DebugVertColor.frag',
|
||||||
'Render/Shaders/vs_Triangle.vert',
|
'Render/Shaders/vs_Triangle.vert',
|
||||||
|
'Render/Shaders/vs_Mesh.vert',
|
||||||
])
|
])
|
||||||
|
|
||||||
orange_src = files([
|
orange_src = files([
|
||||||
|
|
Loading…
Reference in New Issue