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 );
}
template <typename T, typename U = T>
[[nodiscard]] constexpr T Align(T what, U to)
{
return (what + to - 1) & ~(to - 1);
}
// Transformations
template <typename InputIt, typename OutputIt, typename UnaryOperation>

View File

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

View File

@ -20,7 +20,7 @@ namespace orange
return count;
}
static constexpr VkImageSubresourceRange FirstMipSubresourceRange =
static constexpr VkImageSubresourceRange FirstColorMipSubresourceRange =
{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
@ -29,6 +29,15 @@ namespace orange
.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)
{
switch (format)
@ -59,4 +68,11 @@ namespace orange
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)
return 1;
//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/chair.obj");
//auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/cube.obj");
if (!r_objData)
return 1;
@ -489,13 +489,15 @@ int main(int argc, char** argv)
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
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 =
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
.viewMask = 0u,
.colorAttachmentCount = 1u,
.pColorAttachmentFormats = &format,
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
.viewMask = 0u,
.colorAttachmentCount = 1u,
.pColorAttachmentFormats = &colorFormat,
.depthAttachmentFormat = depthFormat
};
VkGraphicsPipelineCreateInfo pipelineInfo =
@ -546,14 +548,28 @@ int main(int argc, char** argv)
UniformData uniformData
{
.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 vertexSlice = *pooler.AllocSlice(meshData.size);
auto indexSlice = *pooler.AllocSlice(r_mesh->indices.Size() * sizeof(uint16_t));
auto uniformSlice = *pooler.AllocSlice(sizeof(UniformData));
auto vertexSlice = *pooler.AllocSlice(meshData.size, 16);
auto indexSlice = *pooler.AllocSlice(r_mesh->indices.Size() * sizeof(uint16_t), 16);
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 =
{
@ -601,7 +617,7 @@ int main(int argc, char** argv)
.extent = r_swapchain->Extent(),
};
vkCmdSetViewport(cmdBuf, 0, 1, &viewport);
vkCmdSetViewport(cmdBuf, 0, 1, &viewport);
vkCmdSetScissor(cmdBuf, 0, 1, &scissor);
vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
@ -617,7 +633,7 @@ int main(int argc, char** argv)
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.image = r_swapchain->Image(),
.subresourceRange = FirstMipSubresourceRange,
.subresourceRange = FirstColorMipSubresourceRange,
};
vkCmdPipelineBarrier(
@ -629,14 +645,45 @@ int main(int argc, char** argv)
0, nullptr,
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,
.imageView = r_swapchain->ImageView(),
.imageView = depthImageView,
.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 } } },
.clearValue = { .color = { .float32 = { 1.0f, 1.0f, 1.0f, 1.0f } } },
};
const VkRenderingInfo renderInfo =
@ -644,8 +691,9 @@ int main(int argc, char** argv)
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
.renderArea = { {}, r_swapchain->Extent() },
.layerCount = 1,
.colorAttachmentCount = 1,
.pColorAttachments = &attachmentInfo,
.colorAttachmentCount = Size(colorAttachmentInfos),
.pColorAttachments = colorAttachmentInfos,
.pDepthAttachment = &depthAttachmentInfo,
};
vkCmdBeginRendering(cmdBuf, &renderInfo);
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,
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.image = r_swapchain->Image(),
.subresourceRange = FirstMipSubresourceRange,
.subresourceRange = FirstColorMipSubresourceRange,
};
vkCmdPipelineBarrier(

View File

@ -82,7 +82,7 @@ namespace orange
.memoryTypeIndex = m_memoryTypes.gpuHostVisibleTypeIdx,
};
VkDeviceMemory memory;
VkDeviceMemory memory = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS;
if ((res = vkAllocateMemory(m_device, &memoryInfo, nullptr, &memory)) != VK_SUCCESS)
return VulkanResult<GPUMemoryBuffer>::Error(res);
@ -112,4 +112,34 @@ namespace orange
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()
{
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;
}
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)
{
VkSurfaceCapabilitiesKHR capabilities;
@ -133,7 +127,7 @@ namespace orange
.image = swapchainImages[i],
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = FormatToSrgbFormat(r_format->format),
.subresourceRange = FirstMipSubresourceRange,
.subresourceRange = FirstColorMipSubresourceRange,
};
if (vkCreateImageView(context.Device(), &imageViewInfo, nullptr, &swapchainImageViews[i]) != VK_SUCCESS)

View File

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