This commit is contained in:
Joshua Ashton 2022-08-12 19:08:28 +00:00
parent 97008e92ca
commit 0b97e6eeec
11 changed files with 495 additions and 35 deletions

View File

@ -53,11 +53,19 @@ namespace orange
T& back() { return data[size - 1]; }
const T& back() const { return data[size - 1]; }
void Copy(void* dst)
{
memcpy(dst, data, sizeof(T) * size);
}
T* data;
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>
{
@ -69,7 +77,7 @@ namespace orange
struct Buffer : public BufferView
{
using BufferView::Span;
using BufferView::BufferView;
~Buffer() { delete[] data; }
};

View File

@ -28,8 +28,8 @@ namespace orange
new (Ptr<T>()) T(Forward(args)...);
}
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> T* Ptr() { 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> const T& Get() const { return *Ptr<T>(); }

View File

@ -166,6 +166,11 @@ namespace orange
return FindIdx(x) != InvalidIdx;
}
void Copy(void* dst)
{
memcpy(dst, Ptr(0), sizeof(T) * m_size);
}
T& operator [] (size_t idx) { 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 BufferView() { return BufferView{ reinterpret_cast<uint8_t *>(Ptr(0)), sizeof(T) * m_size}; }
private:
using Storage = AlignedStorage<sizeof(T), alignof(T)>;

View File

@ -1,6 +1,7 @@
#pragma once
#include <math.h>
#include <float.h>
namespace orange
{

View File

@ -8,16 +8,53 @@
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:
VkBuffer m_buffer;
VkDeviceAddress m_va;
GPUMemoryBuffer m_buffer = {};
VkDeviceSize m_offset = 0u;
};
template <typename T>
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
{
public:
@ -31,10 +68,11 @@ namespace orange
VkQueue Queue() const { return m_queue; }
VkCommandPool CommandPool() const { return m_commandPool; }
VulkanResult<VkFence> CreateFence(bool signalled);
VulkanResult<VkSemaphore> CreateSemaphore();
VulkanResult<VoidResult> BeginCommandBuffer(VkCommandBuffer buffer);
VulkanResult<VoidResult> EndCommandBuffer(VkCommandBuffer buffer);
VulkanResult<VkFence> CreateFence(bool signalled);
VulkanResult<VkSemaphore> CreateSemaphore();
VulkanResult<VoidResult> BeginCommandBuffer(VkCommandBuffer buffer);
VulkanResult<VoidResult> EndCommandBuffer(VkCommandBuffer buffer);
VulkanResult<GPUMemoryBuffer> CreateBuffer(VkDeviceSize size);
VulkanResult<VkShaderModule> CreateShader(Span<const uint32_t> code);
protected:
@ -42,12 +80,52 @@ namespace orange
RenderContext(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device,
VkQueue queue, VkCommandPool commandPool)
: 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:
VkInstance m_instance = VK_NULL_HANDLE;
VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE;
VkDevice m_device = VK_NULL_HANDLE;
VkQueue m_queue = VK_NULL_HANDLE;
VkCommandPool m_commandPool = VK_NULL_HANDLE;
VkMemoryTypes m_memoryTypes{};
};
}

View File

@ -11,8 +11,9 @@
#include <Orange/Render/Window.h>
#include <Orange/Render/RenderContext.h>
#include <Orange/Render/Swapchain.h>
#include <Orange/Render/VulkanHelpers.h>
#include <vs_Triangle.h>
#include <vs_Mesh.h>
#include <fs_DebugVertColor.h>
using namespace orange;
@ -35,19 +36,30 @@ enum class MeshVertexType
Skinned,
};
#ifndef offsetof2
#define offsetof2(type, member) size_t(uintptr_t(&((type*)0)->member))
#endif
struct StaticVertex
{
vec3 pos;
vec2 uv;
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
{
return pos == other.pos &&
uv == other.uv &&
normal == other.normal &&
tangent == other.tangent;
normal == other.normal;// &&
//tangent == other.tangent;
}
};
@ -60,7 +72,7 @@ struct SkinnedVertex : public StaticVertex
return pos == other.pos &&
uv == other.uv &&
normal == other.normal &&
tangent == other.tangent &&
//tangent == other.tangent &&
boneIndices == other.boneIndices &&
boneWeights == other.boneWeights;
}
@ -74,7 +86,7 @@ struct MeshVertexData
MeshVertexData(MeshVertexType type)
: vertexType(type)
{
switch(type)
switch(vertexType)
{
case MeshVertexType::Static:
vertices.Construct<Vector<StaticVertex>>();
@ -97,6 +109,27 @@ struct MeshVertexData
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;
Variant<Vector<StaticVertex>, Vector<SkinnedVertex>> vertices;
};
@ -134,16 +167,14 @@ Result<MeshData> ParseOBJ(StringView buffer)
stream::ConsumeSpace(obj, end);
if (auto r_float = stream::Parse<float>(obj, end))
vtx[i] = *r_float;
else
return Result<MeshData>::Error();
}
if (element == "v")
positions.EmplaceBack(vtx[0], vtx[1], vtx[2]);
else if (element == "vt")
normals.EmplaceBack(vtx[0], vtx[1], vtx[2]);
else if (element == "vn")
uvs.EmplaceBack(vtx[0], vtx[1]);
else if (element == "vn")
normals.EmplaceBack(vtx[0], vtx[1], vtx[2]);
}
else if (element == "g" || element == "o")
{
@ -230,17 +261,135 @@ int main(int argc, char** argv)
if (!r_swapchain)
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)
return 1;
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;
auto r_fs = r_renderContext->CreateShader(fs_DebugVertColor);
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[] =
{
{
@ -270,13 +419,20 @@ int main(int argc, char** argv)
.pDynamicStates = dynamicStates.Data(),
};
VkVertexInputBindingDescription inputBindingDescription =
{
.binding = 0,
.stride = sizeof(StaticVertex),
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
};
VkPipelineVertexInputStateCreateInfo vertexInputInfo =
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = 0u,
.pVertexBindingDescriptions = nullptr,
.vertexAttributeDescriptionCount = 0u,
.pVertexAttributeDescriptions = nullptr,
.vertexBindingDescriptionCount = 1u,
.pVertexBindingDescriptions = &inputBindingDescription,
.vertexAttributeDescriptionCount = Size(StaticVertex::Attributes),
.pVertexAttributeDescriptions = StaticVertex::Attributes,
};
VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo =
@ -298,6 +454,7 @@ int main(int argc, char** argv)
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.cullMode = VK_CULL_MODE_NONE, //VK_CULL_MODE_BACK_BIT,
.frontFace = VK_FRONT_FACE_CLOCKWISE,
.lineWidth = 1.0f,
};
VkPipelineMultisampleStateCreateInfo multisampleInfo =
@ -321,12 +478,14 @@ int main(int argc, char** argv)
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;
vkCreatePipelineLayout(r_renderContext->Device(), &pipelineLayoutInfo, nullptr, &pipelineLayout);
VkFormat format = r_swapchain->Format();
VkFormat format = FormatToSrgbFormat(r_swapchain->Format());
VkPipelineRenderingCreateInfo renderingInfo =
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
@ -359,6 +518,57 @@ int main(int argc, char** argv)
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())
{
VkCommandBuffer cmdBuf = r_swapchain->CommandBuffer();
@ -384,6 +594,29 @@ int main(int argc, char** argv)
vkCmdSetScissor(cmdBuf, 0, 1, &scissor);
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 =
{
@ -404,8 +637,27 @@ int main(int argc, char** argv)
.pColorAttachments = &attachmentInfo,
};
vkCmdBeginRendering(cmdBuf, &renderInfo);
vkCmdDraw(cmdBuf, 3, 1, 0, 0);
vkCmdDrawIndexed(cmdBuf, r_mesh->vertexData.VertexCount(), 1, 0, 0, 0);
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_swapchain->Present();

View File

@ -115,13 +115,50 @@ namespace orange
const char* deviceExtensions[] =
{
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 =
{
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = &descriptorIndexingFeatures,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &queueInfo,
.enabledExtensionCount = Size(deviceExtensions),

View File

@ -72,4 +72,44 @@ namespace orange
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);
}
}

View File

@ -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);
}

View File

@ -77,9 +77,24 @@ namespace orange
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 =
{
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.pNext = &formatListInfo,
.flags = VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR,
.surface = surface,
.minImageCount = ChooseImageCount(capabilities),
.imageFormat = r_format->format,
@ -171,6 +186,8 @@ namespace orange
void Swapchain::Present()
{
vkResetFences(m_ctx.Device(), 1, &m_inFlightFences[m_currentFrame]);
const VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo submitInfo =
{
@ -209,10 +226,9 @@ namespace orange
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);
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);
vkResetCommandBuffer(m_commandBuffers[m_currentFrame], 0u);
}
}

View File

@ -1,6 +1,7 @@
orange_shaders = glsl_generator.process([
'Render/Shaders/fs_DebugVertColor.frag',
'Render/Shaders/vs_Triangle.vert',
'Render/Shaders/vs_Mesh.vert',
])
orange_src = files([