Get stuff rendering
This commit is contained in:
parent
81e8b94a0f
commit
dbeae98d71
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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{};
|
||||
};
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -67,6 +67,9 @@ namespace orange
|
|||
{
|
||||
switch (e.type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
quit = true;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue