Get stuff rendering

This commit is contained in:
Joshua Ashton 2022-08-13 06:18:10 +00:00
parent 81e8b94a0f
commit dbeae98d71
9 changed files with 263 additions and 36 deletions

View File

@ -0,0 +1,117 @@
#pragma once
#include <Orange/Core/Array.h>
#include <Orange/Core/Types.h>
#include <Orange/Core/Traits.h>
namespace orange
{
template <size_t BitCount>
struct Bitset {
static constexpr size_t DwordCount = Align(BitCount, 32) / 32;
constexpr Bitset()
: dwords{ } { }
constexpr bool get(size_t idx) const
{
uint32_t dword = 0u;
uint32_t bit = idx;
if constexpr (DwordCount > 1u) {
dword = idx / 32u;
bit = idx % 32u;
}
return dwords[dword] & (1u << bit);
}
constexpr void set(uint32_t idx, bool value)
{
uint32_t dword = 0u;
uint32_t bit = idx;
if constexpr (DwordCount > 1u) {
dword = idx / 32u;
bit = idx % 32u;
}
if (value)
dwords[dword] |= 1u << bit;
else
dwords[dword] &= ~(1u << bit);
}
constexpr bool exchange(uint32_t idx, bool value)
{
bool oldValue = get(idx);
set(idx, value);
return oldValue;
}
constexpr void flip(uint32_t idx)
{
uint32_t dword = 0u;
uint32_t bit = idx;
if constexpr (DwordCount > 1) {
dword = idx / 32u;
bit = idx % 32u;
}
dwords[dword] ^= 1u << bit;
}
constexpr void setAll()
{
if constexpr (BitCount % 32u == 0u)
{
for (size_t i = 0; i < DwordCount; i++)
dwords[i] = std::numeric_limits<uint32_t>::max();
}
else
{
for (size_t i = 0; i < DwordCount - 1u; i++)
dwords[i] = std::numeric_limits<uint32_t>::max();
dwords[DwordCount - 1] = (1u << (BitCount % 32u)) - 1u;
}
}
constexpr void clearAll()
{
for (size_t i = 0; i < DwordCount; i++)
dwords[i] = 0u;
}
constexpr bool any() const
{
for (size_t i = 0; i < DwordCount; i++)
{
if (dwords[i] != 0u)
return true;
}
return false;
}
constexpr bool operator [] (uint32_t idx) const
{
return get(idx);
}
Array<uint32_t, DwordCount> dwords;
};
}

View File

@ -150,6 +150,12 @@ namespace orange
return Min( Max( val, minVal ), maxVal ); return Min( Max( val, minVal ), maxVal );
} }
template <typename T, typename U = T>
[[nodiscard]] constexpr T Align(T what, U to)
{
return (what + to - 1) & ~(to - 1);
}
// Transformations // Transformations
template <typename InputIt, typename OutputIt, typename UnaryOperation> template <typename InputIt, typename OutputIt, typename UnaryOperation>

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <Orange/Core/Types.h> #include <Orange/Core/Types.h>
#include <Orange/Core/Traits.h>
#include <Orange/Core/Span.h> #include <Orange/Core/Span.h>
#include <Orange/Core/Result.h> #include <Orange/Core/Result.h>
@ -23,23 +24,29 @@ namespace orange
void* ptr; void* ptr;
}; };
class BufferPooler class MemoryPool
{ {
public: public:
BufferPooler(GPUMemoryBuffer buffer) MemoryPool(GPUMemoryBuffer buffer)
: m_buffer{ buffer } {} : m_buffer{ buffer } {}
Result<BufferSlice> AllocSlice(VkDeviceSize size) Result<BufferSlice> AllocSlice(VkDeviceSize size, VkDeviceSize alignment = 1u)
{ {
BufferSlice slice{ m_buffer.buffer, m_offset, size }; uint32_t offset = Align(m_offset, alignment);
BufferSlice slice{ m_buffer.buffer, offset, size };
if (m_offset + size > m_buffer.size) if (offset + size > m_buffer.size)
return Result<BufferSlice>::Error(); return Result<BufferSlice>::Error();
m_offset += size; m_offset = offset + size;
return Result<BufferSlice>::Success(slice); return Result<BufferSlice>::Success(slice);
} }
VkDeviceMemory Memory() const
{
return m_buffer.memory;
}
private: private:
GPUMemoryBuffer m_buffer = {}; GPUMemoryBuffer m_buffer = {};
VkDeviceSize m_offset = 0u; VkDeviceSize m_offset = 0u;
@ -73,8 +80,11 @@ namespace orange
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<GPUMemoryBuffer> CreateBuffer(VkDeviceSize size);
VulkanResult<VkImage> CreateImage(MemoryPool& pool, uint32_t width, uint32_t height, VkFormat format);
VulkanResult<VkShaderModule> CreateShader(Span<const uint32_t> code); VulkanResult<VkShaderModule> CreateShader(Span<const uint32_t> code);
const VkPhysicalDeviceProperties& Props() const { return m_props; }
protected: protected:
friend VulkanResult<RenderContext>; friend VulkanResult<RenderContext>;
RenderContext(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device, RenderContext(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device,
@ -118,6 +128,7 @@ namespace orange
} }
} }
vkGetPhysicalDeviceProperties(m_physicalDevice, &m_props);
} }
private: private:
VkInstance m_instance = VK_NULL_HANDLE; VkInstance m_instance = VK_NULL_HANDLE;
@ -126,6 +137,7 @@ namespace orange
VkQueue m_queue = VK_NULL_HANDLE; VkQueue m_queue = VK_NULL_HANDLE;
VkCommandPool m_commandPool = VK_NULL_HANDLE; VkCommandPool m_commandPool = VK_NULL_HANDLE;
VkPhysicalDeviceProperties m_props{};
VkMemoryTypes m_memoryTypes{}; VkMemoryTypes m_memoryTypes{};
}; };
} }

View File

@ -20,7 +20,7 @@ namespace orange
return count; return count;
} }
static constexpr VkImageSubresourceRange FirstMipSubresourceRange = static constexpr VkImageSubresourceRange FirstColorMipSubresourceRange =
{ {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0, .baseMipLevel = 0,
@ -29,6 +29,15 @@ namespace orange
.layerCount = 1, .layerCount = 1,
}; };
static constexpr VkImageSubresourceRange FirstDepthMipSubresourceRange =
{
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
};
constexpr VkFormat FormatToSrgbFormat(VkFormat format) constexpr VkFormat FormatToSrgbFormat(VkFormat format)
{ {
switch (format) switch (format)
@ -59,4 +68,11 @@ namespace orange
return Result<VkFormat>::Error(BasicErrorCode::NotFound); return Result<VkFormat>::Error(BasicErrorCode::NotFound);
} }
inline Result<VkFormat> FindDepthFormat(VkPhysicalDevice physicalDevice)
{
return FindSupportedFormat(physicalDevice, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT,
VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT);
}
} }

View File

@ -262,8 +262,8 @@ 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"); //auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/cube.obj");
if (!r_objData) if (!r_objData)
return 1; return 1;
@ -489,13 +489,15 @@ int main(int argc, char** argv)
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 = FormatToSrgbFormat(r_swapchain->Format()); VkFormat colorFormat = FormatToSrgbFormat(r_swapchain->Format());
VkFormat depthFormat = *FindDepthFormat(r_renderContext->PhysicalDevice());
VkPipelineRenderingCreateInfo renderingInfo = VkPipelineRenderingCreateInfo renderingInfo =
{ {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
.viewMask = 0u, .viewMask = 0u,
.colorAttachmentCount = 1u, .colorAttachmentCount = 1u,
.pColorAttachmentFormats = &format, .pColorAttachmentFormats = &colorFormat,
.depthAttachmentFormat = depthFormat
}; };
VkGraphicsPipelineCreateInfo pipelineInfo = VkGraphicsPipelineCreateInfo pipelineInfo =
@ -546,14 +548,28 @@ int main(int argc, char** argv)
UniformData uniformData UniformData uniformData
{ {
.projection = perspective(Degree(90.0f), 16.0f / 9.0f, 0.01f, 1024.0f), .projection = perspective(Degree(90.0f), 16.0f / 9.0f, 0.01f, 1024.0f),
.view = translate(vec3{0.0f, 0.0f, -4.0f}), .view = translate(vec3{0.0f, 0.0f, -80.0f}),
}; };
auto pooler = BufferPooler{ *r_buffer }; auto pooler = MemoryPool{ *r_buffer };
auto meshData = r_mesh->vertexData.View(); auto meshData = r_mesh->vertexData.View();
auto vertexSlice = *pooler.AllocSlice(meshData.size); auto vertexSlice = *pooler.AllocSlice(meshData.size, 16);
auto indexSlice = *pooler.AllocSlice(r_mesh->indices.Size() * sizeof(uint16_t)); auto indexSlice = *pooler.AllocSlice(r_mesh->indices.Size() * sizeof(uint16_t), 16);
auto uniformSlice = *pooler.AllocSlice(sizeof(UniformData)); auto uniformSlice = *pooler.AllocSlice(sizeof(UniformData), 16);
auto r_depthImage = r_renderContext->CreateImage(pooler, 1280, 720, depthFormat);
VkImageViewCreateInfo depthImageViewInfo =
{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = *r_depthImage,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = depthFormat,
.subresourceRange = FirstDepthMipSubresourceRange,
};
VkImageView depthImageView = VK_NULL_HANDLE;
if (vkCreateImageView(r_renderContext->Device(), &depthImageViewInfo, nullptr, &depthImageView) != VK_SUCCESS)
return 1;
VkDescriptorBufferInfo bufferInfo = VkDescriptorBufferInfo bufferInfo =
{ {
@ -601,7 +617,7 @@ int main(int argc, char** argv)
.extent = r_swapchain->Extent(), .extent = r_swapchain->Extent(),
}; };
vkCmdSetViewport(cmdBuf, 0, 1, &viewport); vkCmdSetViewport(cmdBuf, 0, 1, &viewport);
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);
@ -617,7 +633,7 @@ int main(int argc, char** argv)
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.image = r_swapchain->Image(), .image = r_swapchain->Image(),
.subresourceRange = FirstMipSubresourceRange, .subresourceRange = FirstColorMipSubresourceRange,
}; };
vkCmdPipelineBarrier( vkCmdPipelineBarrier(
@ -629,14 +645,45 @@ int main(int argc, char** argv)
0, nullptr, 0, nullptr,
1, &undefinedToColorBarrier); 1, &undefinedToColorBarrier);
const VkRenderingAttachmentInfoKHR attachmentInfo = const VkImageMemoryBarrier undefinedToDepthBarrier =
{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
.image = *r_depthImage,
.subresourceRange = FirstColorMipSubresourceRange,
};
vkCmdPipelineBarrier(
cmdBuf,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
0,
0, nullptr,
0, nullptr,
1, &undefinedToDepthBarrier);
const VkRenderingAttachmentInfoKHR colorAttachmentInfos[] =
{
{
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,
.imageView = r_swapchain->ImageView(),
.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.clearValue = { .color = { .float32 = { 1.0f, 0.5f, 0.0f, 1.0f } } },
},
};
const VkRenderingAttachmentInfoKHR depthAttachmentInfo =
{ {
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,
.imageView = r_swapchain->ImageView(), .imageView = depthImageView,
.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, .imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE, .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.clearValue = { .color = { .float32 = { 1.0f, 0.5f, 0.0f, 1.0f } } }, .clearValue = { .color = { .float32 = { 1.0f, 1.0f, 1.0f, 1.0f } } },
}; };
const VkRenderingInfo renderInfo = const VkRenderingInfo renderInfo =
@ -644,8 +691,9 @@ int main(int argc, char** argv)
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO, .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
.renderArea = { {}, r_swapchain->Extent() }, .renderArea = { {}, r_swapchain->Extent() },
.layerCount = 1, .layerCount = 1,
.colorAttachmentCount = 1, .colorAttachmentCount = Size(colorAttachmentInfos),
.pColorAttachments = &attachmentInfo, .pColorAttachments = colorAttachmentInfos,
.pDepthAttachment = &depthAttachmentInfo,
}; };
vkCmdBeginRendering(cmdBuf, &renderInfo); vkCmdBeginRendering(cmdBuf, &renderInfo);
vkCmdDrawIndexed(cmdBuf, r_mesh->indices.Size(), 1, 0, 0, 0); vkCmdDrawIndexed(cmdBuf, r_mesh->indices.Size(), 1, 0, 0, 0);
@ -658,7 +706,7 @@ int main(int argc, char** argv)
.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.image = r_swapchain->Image(), .image = r_swapchain->Image(),
.subresourceRange = FirstMipSubresourceRange, .subresourceRange = FirstColorMipSubresourceRange,
}; };
vkCmdPipelineBarrier( vkCmdPipelineBarrier(

View File

@ -82,7 +82,7 @@ namespace orange
.memoryTypeIndex = m_memoryTypes.gpuHostVisibleTypeIdx, .memoryTypeIndex = m_memoryTypes.gpuHostVisibleTypeIdx,
}; };
VkDeviceMemory memory; VkDeviceMemory memory = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS; VkResult res = VK_SUCCESS;
if ((res = vkAllocateMemory(m_device, &memoryInfo, nullptr, &memory)) != VK_SUCCESS) if ((res = vkAllocateMemory(m_device, &memoryInfo, nullptr, &memory)) != VK_SUCCESS)
return VulkanResult<GPUMemoryBuffer>::Error(res); return VulkanResult<GPUMemoryBuffer>::Error(res);
@ -112,4 +112,34 @@ namespace orange
return VulkanResult<GPUMemoryBuffer>::Success(memory, buffer, size, data); return VulkanResult<GPUMemoryBuffer>::Success(memory, buffer, size, data);
} }
VulkanResult<VkImage> RenderContext::CreateImage(MemoryPool& pool, uint32_t width, uint32_t height, VkFormat format)
{
VkImageCreateInfo imageInfo =
{
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.imageType = VK_IMAGE_TYPE_2D,
.format = format,
.extent = VkExtent3D{ width, height, 1u },
.mipLevels = 1u,
.arrayLayers = 1u,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
};
VkImage image = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS;
if ((res = vkCreateImage(m_device, &imageInfo, nullptr, &image)) != VK_SUCCESS)
return VulkanResult<VkImage>::Error(res);
VkMemoryRequirements imageMemRequirements;
vkGetImageMemoryRequirements(m_device, image, &imageMemRequirements);
auto imageSlice = *pool.AllocSlice(imageMemRequirements.size, imageMemRequirements.alignment);
if ((res = vkBindImageMemory(m_device, image, pool.Memory(), imageSlice.offset)) != VK_SUCCESS)
return VulkanResult<VkImage>::Error(res);
return VulkanResult<VkImage>::Success(image);
}
} }

View File

@ -21,5 +21,6 @@ vec3 k_colors[3] = vec3[]
void main() void main()
{ {
gl_Position = u_data.projection * u_data.view * vec4(i_pos, 1.0); gl_Position = u_data.projection * u_data.view * vec4(i_pos, 1.0);
o_color = vec4(k_colors[gl_VertexIndex % 3], 1.0); //o_color = vec4(k_colors[gl_VertexIndex % 3], 1.0);
o_color = vec4(i_uv, 0.0f, 1.0);
} }

View File

@ -66,12 +66,6 @@ namespace orange
return imageCount; return imageCount;
} }
static Result<VkFormat> FindDepthFormat(VkPhysicalDevice physicalDevice)
{
return FindSupportedFormat(physicalDevice, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT);
}
Result<Swapchain> Swapchain::Create(RenderContext& context, VkSurfaceKHR surface) Result<Swapchain> Swapchain::Create(RenderContext& context, VkSurfaceKHR surface)
{ {
VkSurfaceCapabilitiesKHR capabilities; VkSurfaceCapabilitiesKHR capabilities;
@ -133,7 +127,7 @@ namespace orange
.image = swapchainImages[i], .image = swapchainImages[i],
.viewType = VK_IMAGE_VIEW_TYPE_2D, .viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = FormatToSrgbFormat(r_format->format), .format = FormatToSrgbFormat(r_format->format),
.subresourceRange = FirstMipSubresourceRange, .subresourceRange = FirstColorMipSubresourceRange,
}; };
if (vkCreateImageView(context.Device(), &imageViewInfo, nullptr, &swapchainImageViews[i]) != VK_SUCCESS) if (vkCreateImageView(context.Device(), &imageViewInfo, nullptr, &swapchainImageViews[i]) != VK_SUCCESS)

View File

@ -67,6 +67,9 @@ namespace orange
{ {
switch (e.type) switch (e.type)
{ {
case SDL_KEYDOWN:
case SDL_KEYUP:
break;
case SDL_QUIT: case SDL_QUIT:
quit = true; quit = true;
break; break;