mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Attempt to add depth buffer
This commit is contained in:
parent
3df5cfbc02
commit
9e7c6e923d
@ -31,8 +31,8 @@ namespace engine {
|
|||||||
const gfx::DescriptorSetLayout* setZeroLayout;
|
const gfx::DescriptorSetLayout* setZeroLayout;
|
||||||
const gfx::DescriptorSet* setZero;
|
const gfx::DescriptorSet* setZero;
|
||||||
struct SetZeroBuffer {
|
struct SetZeroBuffer {
|
||||||
|
glm::mat4 view;
|
||||||
glm::mat4 proj;
|
glm::mat4 proj;
|
||||||
glm::vec2 myValue;
|
|
||||||
};
|
};
|
||||||
gfx::DescriptorBuffer* setZeroBuffer;
|
gfx::DescriptorBuffer* setZeroBuffer;
|
||||||
};
|
};
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
layout( push_constant ) uniform Constants {
|
layout( push_constant ) uniform Constants {
|
||||||
mat4 model;
|
mat4 model;
|
||||||
mat4 view;
|
|
||||||
} constants;
|
} constants;
|
||||||
|
|
||||||
layout(set = 0, binding = 0) uniform SetZeroBuffer {
|
layout(set = 0, binding = 0) uniform SetZeroBuffer {
|
||||||
|
mat4 view;
|
||||||
mat4 proj;
|
mat4 proj;
|
||||||
vec2 myValue;
|
|
||||||
} setZeroBuffer;
|
} setZeroBuffer;
|
||||||
|
|
||||||
layout(location = 0) in vec3 inPosition;
|
layout(location = 0) in vec3 inPosition;
|
||||||
@ -16,7 +15,7 @@ layout(location = 2) in vec2 inUV;
|
|||||||
layout(location = 0) out vec2 fragUV;
|
layout(location = 0) out vec2 fragUV;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
mat4 myView = constants.view;
|
mat4 myView = setZeroBuffer.view;
|
||||||
myView[3] = vec4(0.0, 0.0, 0.0, 1.0);
|
myView[3] = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
vec4 pos = setZeroBuffer.proj * myView * constants.model * vec4(inPosition, 1.0);
|
vec4 pos = setZeroBuffer.proj * myView * constants.model * vec4(inPosition, 1.0);
|
||||||
gl_Position = pos;
|
gl_Position = pos;
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
layout( push_constant ) uniform Constants {
|
layout( push_constant ) uniform Constants {
|
||||||
mat4 model;
|
mat4 model;
|
||||||
mat4 view;
|
|
||||||
} constants;
|
} constants;
|
||||||
|
|
||||||
layout(set = 0, binding = 0) uniform SetZeroBuffer {
|
layout(set = 0, binding = 0) uniform SetZeroBuffer {
|
||||||
|
mat4 view;
|
||||||
mat4 proj;
|
mat4 proj;
|
||||||
vec2 myValue;
|
|
||||||
} setZeroBuffer;
|
} setZeroBuffer;
|
||||||
|
|
||||||
layout(location = 0) in vec3 inPosition;
|
layout(location = 0) in vec3 inPosition;
|
||||||
@ -20,12 +19,12 @@ layout(location = 2) out vec2 fragUV;
|
|||||||
layout(location = 3) out vec3 fragLightPos;
|
layout(location = 3) out vec3 fragLightPos;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = setZeroBuffer.proj * constants.view * constants.model * vec4(inPosition, 1.0);
|
gl_Position = setZeroBuffer.proj * setZeroBuffer.view * constants.model * vec4(inPosition, 1.0);
|
||||||
|
|
||||||
fragPos = vec3(constants.view * constants.model * vec4(inPosition, 1.0));
|
fragPos = vec3(setZeroBuffer.view * constants.model * vec4(inPosition, 1.0));
|
||||||
fragNorm = mat3(transpose(inverse(constants.view * constants.model))) * inNorm;
|
fragNorm = mat3(transpose(inverse(setZeroBuffer.view * constants.model))) * inNorm;
|
||||||
fragUV = inUV;
|
fragUV = inUV;
|
||||||
|
|
||||||
vec3 lightPos = vec3(2000.0, 2000.0, -2000.0);
|
vec3 lightPos = vec3(2000.0, 2000.0, -2000.0);
|
||||||
fragLightPos = vec3(constants.view * vec4(lightPos, 1.0));
|
fragLightPos = vec3(setZeroBuffer.view * vec4(lightPos, 1.0));
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,8 @@ namespace engine {
|
|||||||
renderData.setZeroLayout = gfx()->createDescriptorSetLayout();
|
renderData.setZeroLayout = gfx()->createDescriptorSetLayout();
|
||||||
renderData.setZero = gfx()->allocateDescriptorSet(renderData.setZeroLayout);
|
renderData.setZero = gfx()->allocateDescriptorSet(renderData.setZeroLayout);
|
||||||
RenderData::SetZeroBuffer initialData{
|
RenderData::SetZeroBuffer initialData{
|
||||||
|
.view = glm::mat4{1.0f},
|
||||||
.proj = glm::perspectiveZO(glm::radians(70.0f), 1024.0f / 768.0f, 0.1f, 1000.0f),
|
.proj = glm::perspectiveZO(glm::radians(70.0f), 1024.0f / 768.0f, 0.1f, 1000.0f),
|
||||||
.myValue = { 0.0f, 1.0f }
|
|
||||||
};
|
};
|
||||||
renderData.setZeroBuffer = gfx()->createDescriptorBuffer(sizeof(RenderData::SetZeroBuffer), &initialData);
|
renderData.setZeroBuffer = gfx()->createDescriptorBuffer(sizeof(RenderData::SetZeroBuffer), &initialData);
|
||||||
gfx()->updateDescriptor(renderData.setZero, 0, renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer));
|
gfx()->updateDescriptor(renderData.setZero, 0, renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer));
|
||||||
|
@ -613,6 +613,7 @@ namespace engine {
|
|||||||
pimpl->allocator = createAllocator(pimpl->instance.instance, pimpl->device.device, pimpl->device.physicalDevice);
|
pimpl->allocator = createAllocator(pimpl->instance.instance, pimpl->device.device, pimpl->device.physicalDevice);
|
||||||
|
|
||||||
pimpl->swapchainInfo.device = pimpl->device.device;
|
pimpl->swapchainInfo.device = pimpl->device.device;
|
||||||
|
pimpl->swapchainInfo.allocator = pimpl->allocator;
|
||||||
pimpl->swapchainInfo.physicalDevice = pimpl->device.physicalDevice;
|
pimpl->swapchainInfo.physicalDevice = pimpl->device.physicalDevice;
|
||||||
pimpl->swapchainInfo.surface = pimpl->surface;
|
pimpl->swapchainInfo.surface = pimpl->surface;
|
||||||
pimpl->swapchainInfo.window = pimpl->window;
|
pimpl->swapchainInfo.window = pimpl->window;
|
||||||
|
@ -47,11 +47,10 @@ namespace engine {
|
|||||||
const glm::mat4 projMatrix = glm::perspectiveZO(verticalFovRadians, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar);
|
const glm::mat4 projMatrix = glm::perspectiveZO(verticalFovRadians, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar);
|
||||||
|
|
||||||
/* update SET 0 */
|
/* update SET 0 */
|
||||||
RenderData::SetZeroBuffer uniform{};
|
RenderData::SetZeroBuffer uniform{
|
||||||
uniform.proj = projMatrix;
|
.view = viewMatrix,
|
||||||
uniform.myValue.x = 1.0f;
|
.proj = projMatrix
|
||||||
m_value = glm::mod(m_value + ts, 1.0f);
|
};
|
||||||
uniform.myValue.y = m_value;
|
|
||||||
m_gfx->writeDescriptorBuffer(renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer), &uniform);
|
m_gfx->writeDescriptorBuffer(renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer), &uniform);
|
||||||
|
|
||||||
/* render all renderable entities */
|
/* render all renderable entities */
|
||||||
@ -69,11 +68,9 @@ namespace engine {
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
glm::mat4 model;
|
glm::mat4 model;
|
||||||
glm::mat4 view;
|
|
||||||
} pushConsts{};
|
} pushConsts{};
|
||||||
|
|
||||||
pushConsts.model = t->worldMatrix;
|
pushConsts.model = t->worldMatrix;
|
||||||
pushConsts.view = viewMatrix;
|
|
||||||
|
|
||||||
m_gfx->cmdBindPipeline(renderData.drawBuffer, r->material->getShader()->getPipeline());
|
m_gfx->cmdBindPipeline(renderData.drawBuffer, r->material->getShader()->getPipeline());
|
||||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, r->material->getShader()->getPipeline(), renderData.setZero, 0);
|
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, r->material->getShader()->getPipeline(), renderData.setZero, 0);
|
||||||
|
@ -5,10 +5,21 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "log.hpp"
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
|
|
||||||
|
static bool checkQueueFamilySupportsPresent(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t familyIndex)
|
||||||
|
{
|
||||||
|
VkBool32 supportsPresent;
|
||||||
|
VkResult res;
|
||||||
|
res = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, static_cast<uint32_t>(familyIndex), surface, &supportsPresent);
|
||||||
|
if (res != VK_SUCCESS) throw std::runtime_error("Failed to check for queue family present support!");
|
||||||
|
return supportsPresent;
|
||||||
|
}
|
||||||
|
|
||||||
/* chooses a device, creates it, gets its function pointers, and creates command pools */
|
/* chooses a device, creates it, gets its function pointers, and creates command pools */
|
||||||
Device createDevice(VkInstance instance, DeviceRequirements requirements, VkSurfaceKHR surface)
|
Device createDevice(VkInstance instance, DeviceRequirements requirements, VkSurfaceKHR surface)
|
||||||
{
|
{
|
||||||
@ -209,22 +220,33 @@ namespace engine {
|
|||||||
for (size_t i = 0; i < queueFamilies.size(); i++) {
|
for (size_t i = 0; i < queueFamilies.size(); i++) {
|
||||||
VkQueueFamilyProperties p = queueFamilies[i];
|
VkQueueFamilyProperties p = queueFamilies[i];
|
||||||
|
|
||||||
if (p.queueCount < 2) continue; // need one queue for presenting and one-or-more for rendering
|
if (p.queueCount < 2) continue; // ideally have one queue for presenting and at least one other for rendering
|
||||||
|
|
||||||
if (p.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
if (p.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||||
VkBool32 supportsPresent;
|
if (checkQueueFamilySupportsPresent(d.physicalDevice, surface, i)) {
|
||||||
res = vkGetPhysicalDeviceSurfaceSupportKHR(d.physicalDevice, static_cast<uint32_t>(i), surface, &supportsPresent);
|
|
||||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to check for queue family present support!");
|
|
||||||
if (supportsPresent) {
|
|
||||||
graphicsFamily = static_cast<uint32_t>(i);
|
graphicsFamily = static_cast<uint32_t>(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (graphicsFamily == UINT32_MAX) throw std::runtime_error("Unable to find a graphics/present queue family!");
|
if (graphicsFamily == UINT32_MAX) {
|
||||||
|
for (size_t i = 0; i < queueFamilies.size(); i++) {
|
||||||
|
VkQueueFamilyProperties p = queueFamilies[i];
|
||||||
|
if (p.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||||
|
if (checkQueueFamilySupportsPresent(d.physicalDevice, surface, i)) {
|
||||||
|
graphicsFamily = static_cast<uint32_t>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (graphicsFamily == UINT32_MAX) {
|
||||||
|
throw std::runtime_error("Failed to find a graphics/present family!");
|
||||||
|
}
|
||||||
|
LOG_WARN("Failed to find ideal graphics/present queue family! Falling back to family #{}.", graphicsFamily);
|
||||||
|
}
|
||||||
|
|
||||||
// find a transfer queue family (image layout transitions, buffer upload)
|
// find a transfer queue family (image layout transitions, buffer upload)
|
||||||
uint32_t transferFamily = UINT32_MAX;
|
uint32_t transferFamily = UINT32_MAX;
|
||||||
|
// prefer a dedicated transfer queue family
|
||||||
for (size_t i = 0; i < queueFamilies.size(); i++) {
|
for (size_t i = 0; i < queueFamilies.size(); i++) {
|
||||||
VkQueueFamilyProperties p = queueFamilies[i];
|
VkQueueFamilyProperties p = queueFamilies[i];
|
||||||
if (((p.queueFlags & VK_QUEUE_TRANSFER_BIT) != 0) &&
|
if (((p.queueFlags & VK_QUEUE_TRANSFER_BIT) != 0) &&
|
||||||
@ -234,7 +256,10 @@ namespace engine {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (transferFamily == UINT32_MAX) throw std::runtime_error("Unable to find a transfer queue family!");
|
if (transferFamily == UINT32_MAX) {
|
||||||
|
transferFamily = graphicsFamily;
|
||||||
|
LOG_WARN("Failed to find a dedicated transfer queue family! Falling back to graphics family.");
|
||||||
|
}
|
||||||
|
|
||||||
// queue priorities
|
// queue priorities
|
||||||
std::vector<float> graphicsQueuePriorities(queueFamilies[graphicsFamily].queueCount);
|
std::vector<float> graphicsQueuePriorities(queueFamilies[graphicsFamily].queueCount);
|
||||||
@ -242,24 +267,26 @@ namespace engine {
|
|||||||
std::vector<float> transferQueuePriorities(queueFamilies[transferFamily].queueCount);
|
std::vector<float> transferQueuePriorities(queueFamilies[transferFamily].queueCount);
|
||||||
std::fill(transferQueuePriorities.begin(), transferQueuePriorities.end(), 1.0f);
|
std::fill(transferQueuePriorities.begin(), transferQueuePriorities.end(), 1.0f);
|
||||||
|
|
||||||
std::array<VkDeviceQueueCreateInfo, 2> queueCreateInfos{
|
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos{};
|
||||||
VkDeviceQueueCreateInfo{
|
queueCreateInfos.push_back(VkDeviceQueueCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.queueFamilyIndex = graphicsFamily,
|
.queueFamilyIndex = graphicsFamily,
|
||||||
.queueCount = queueFamilies[graphicsFamily].queueCount,
|
.queueCount = queueFamilies[graphicsFamily].queueCount,
|
||||||
.pQueuePriorities = graphicsQueuePriorities.data(),
|
.pQueuePriorities = graphicsQueuePriorities.data()
|
||||||
},
|
});
|
||||||
VkDeviceQueueCreateInfo{
|
|
||||||
|
if (transferFamily != graphicsFamily) {
|
||||||
|
queueCreateInfos.push_back(VkDeviceQueueCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.queueFamilyIndex = transferFamily,
|
.queueFamilyIndex = transferFamily,
|
||||||
.queueCount = queueFamilies[transferFamily].queueCount,
|
.queueCount = queueFamilies[transferFamily].queueCount,
|
||||||
.pQueuePriorities = transferQueuePriorities.data(),
|
.pQueuePriorities = transferQueuePriorities.data()
|
||||||
}
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
/* create device now */
|
/* create device now */
|
||||||
VkDeviceCreateInfo deviceCreateInfo{
|
VkDeviceCreateInfo deviceCreateInfo{
|
||||||
@ -282,14 +309,49 @@ namespace engine {
|
|||||||
|
|
||||||
volkLoadDevice(d.device);
|
volkLoadDevice(d.device);
|
||||||
|
|
||||||
vkGetDeviceQueue(d.device, graphicsFamily, 0, &d.queues.presentQueue);
|
|
||||||
d.queues.drawQueues.resize(queueFamilies[graphicsFamily].queueCount - 1);
|
if (transferFamily != graphicsFamily) {
|
||||||
for (uint32_t i = 0; i < d.queues.drawQueues.size(); i++) {
|
vkGetDeviceQueue(d.device, graphicsFamily, 0, &d.queues.presentQueue);
|
||||||
vkGetDeviceQueue(d.device, graphicsFamily, i + 1, &d.queues.drawQueues[i]);
|
if (queueFamilies[graphicsFamily].queueCount >= 2) {
|
||||||
}
|
d.queues.drawQueues.resize(queueFamilies[graphicsFamily].queueCount - 1);
|
||||||
d.queues.transferQueues.resize(queueFamilies[transferFamily].queueCount);
|
for (uint32_t i = 0; i < d.queues.drawQueues.size(); i++) {
|
||||||
for (uint32_t i = 0; i < d.queues.transferQueues.size(); i++) {
|
vkGetDeviceQueue(d.device, graphicsFamily, i + 1, &d.queues.drawQueues[i]);
|
||||||
vkGetDeviceQueue(d.device, transferFamily, i, &d.queues.transferQueues[i]);
|
}
|
||||||
|
} else {
|
||||||
|
d.queues.drawQueues.resize(1);
|
||||||
|
d.queues.drawQueues[0] = d.queues.presentQueue;
|
||||||
|
}
|
||||||
|
d.queues.transferQueues.resize(queueFamilies[transferFamily].queueCount);
|
||||||
|
for (uint32_t i = 0; i < d.queues.transferQueues.size(); i++) {
|
||||||
|
vkGetDeviceQueue(d.device, transferFamily, i, &d.queues.transferQueues[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// same graphics family for graphics/present and transfer
|
||||||
|
uint32_t queueCount = queueFamilies[graphicsFamily].queueCount;
|
||||||
|
vkGetDeviceQueue(d.device, graphicsFamily, 0, &d.queues.presentQueue);
|
||||||
|
if (queueCount >= 2) {
|
||||||
|
d.queues.transferQueues.resize(1);
|
||||||
|
vkGetDeviceQueue(d.device, graphicsFamily, 1, &d.queues.transferQueues[0]);
|
||||||
|
// use the remaining queues for drawing
|
||||||
|
if (queueCount >= 3) {
|
||||||
|
d.queues.drawQueues.resize(queueCount - 2);
|
||||||
|
for (uint32_t i = 0; i < queueCount - 2; i++) {
|
||||||
|
vkGetDeviceQueue(d.device, graphicsFamily, i + 2, &d.queues.drawQueues[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 2 queues available
|
||||||
|
// present and drawing share a queue
|
||||||
|
// transfer gets its own queue
|
||||||
|
d.queues.drawQueues.resize(1);
|
||||||
|
d.queues.drawQueues[0] = d.queues.presentQueue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// only 1 queue available :(
|
||||||
|
d.queues.transferQueues.resize(1);
|
||||||
|
d.queues.transferQueues[0] = d.queues.presentQueue;
|
||||||
|
d.queues.drawQueues.resize(1);
|
||||||
|
d.queues.drawQueues[0] = d.queues.presentQueue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.queues.presentAndDrawQueueFamily = graphicsFamily;
|
d.queues.presentAndDrawQueueFamily = graphicsFamily;
|
||||||
|
@ -14,6 +14,7 @@ namespace engine {
|
|||||||
void createSwapchain(Swapchain* sc, const SwapchainInfo& info)
|
void createSwapchain(Swapchain* sc, const SwapchainInfo& info)
|
||||||
{
|
{
|
||||||
sc->device = info.device;
|
sc->device = info.device;
|
||||||
|
sc->allocator = info.allocator;
|
||||||
|
|
||||||
LOG_INFO("Recreating swapchain!\n");
|
LOG_INFO("Recreating swapchain!\n");
|
||||||
|
|
||||||
@ -129,6 +130,61 @@ namespace engine {
|
|||||||
vkDestroySwapchainKHR(info.device, scInfo.oldSwapchain, nullptr);
|
vkDestroySwapchainKHR(info.device, scInfo.oldSwapchain, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ /* create the depth buffer */
|
||||||
|
|
||||||
|
sc->depthStencil.format = VK_FORMAT_D32_SFLOAT;
|
||||||
|
|
||||||
|
if (sc->depthStencil.image != VK_NULL_HANDLE) {
|
||||||
|
vkDestroyImageView(info.device, sc->depthStencil.view, nullptr);
|
||||||
|
vmaDestroyImage(sc->allocator, sc->depthStencil.image, sc->depthStencil.allocation);
|
||||||
|
}
|
||||||
|
VkImageCreateInfo imageInfo{};
|
||||||
|
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
imageInfo.pNext = nullptr;
|
||||||
|
imageInfo.flags = 0;
|
||||||
|
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
imageInfo.format = sc->depthStencil.format;
|
||||||
|
imageInfo.extent.width = sc->extent.width;
|
||||||
|
imageInfo.extent.height = sc->extent.height;
|
||||||
|
imageInfo.mipLevels = 1;
|
||||||
|
imageInfo.arrayLayers = 1;
|
||||||
|
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
|
imageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||||
|
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
imageInfo.queueFamilyIndexCount = 0; // ignored
|
||||||
|
imageInfo.pQueueFamilyIndices = nullptr; // ignored
|
||||||
|
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
|
VmaAllocationCreateInfo allocInfo{};
|
||||||
|
allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
||||||
|
allocInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
|
||||||
|
allocInfo.priority = 1.0f;
|
||||||
|
|
||||||
|
res = vmaCreateImage(sc->allocator, &imageInfo, &allocInfo, &sc->depthStencil.image, &sc->depthStencil.allocation, nullptr);
|
||||||
|
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create depth buffer image! Code: " + std::to_string(res));
|
||||||
|
|
||||||
|
VkImageViewCreateInfo viewInfo{};
|
||||||
|
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
viewInfo.pNext = nullptr;
|
||||||
|
viewInfo.flags = 0;
|
||||||
|
viewInfo.image = sc->depthStencil.image;
|
||||||
|
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
viewInfo.format = sc->depthStencil.format;
|
||||||
|
viewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
viewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
viewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
viewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
|
viewInfo.subresourceRange.baseMipLevel = 0;
|
||||||
|
viewInfo.subresourceRange.levelCount = 1;
|
||||||
|
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
|
viewInfo.subresourceRange.layerCount = 1;
|
||||||
|
res = vkCreateImageView(info.device, &viewInfo, nullptr, &sc->depthStencil.view);
|
||||||
|
assert(res == VK_SUCCESS);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* create the render pass */
|
/* create the render pass */
|
||||||
if (sc->renderpass != VK_NULL_HANDLE) {
|
if (sc->renderpass != VK_NULL_HANDLE) {
|
||||||
vkDestroyRenderPass(sc->device, sc->renderpass, nullptr);
|
vkDestroyRenderPass(sc->device, sc->renderpass, nullptr);
|
||||||
@ -144,10 +200,26 @@ namespace engine {
|
|||||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
||||||
};
|
};
|
||||||
|
VkAttachmentDescription depthStencilAttachment{
|
||||||
|
.flags = 0,
|
||||||
|
.format = sc->depthStencil.format,
|
||||||
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||||
|
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
|
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, // the depth buffer is not used after the fragment shader
|
||||||
|
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, // ignored
|
||||||
|
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, // ignored
|
||||||
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
||||||
|
};
|
||||||
|
std::array<VkAttachmentDescription, 2> attachments { colorAttachment, depthStencilAttachment };
|
||||||
VkAttachmentReference colorAttachmentRef{
|
VkAttachmentReference colorAttachmentRef{
|
||||||
.attachment = 0,
|
.attachment = 0,
|
||||||
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||||
};
|
};
|
||||||
|
VkAttachmentReference depthStencilAttachmentRef{
|
||||||
|
.attachment = 1,
|
||||||
|
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
||||||
|
};
|
||||||
VkSubpassDescription subpass{
|
VkSubpassDescription subpass{
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
@ -156,25 +228,25 @@ namespace engine {
|
|||||||
.colorAttachmentCount = 1,
|
.colorAttachmentCount = 1,
|
||||||
.pColorAttachments = &colorAttachmentRef,
|
.pColorAttachments = &colorAttachmentRef,
|
||||||
.pResolveAttachments = nullptr,
|
.pResolveAttachments = nullptr,
|
||||||
.pDepthStencilAttachment = nullptr,
|
.pDepthStencilAttachment = &depthStencilAttachmentRef,
|
||||||
.preserveAttachmentCount = 0,
|
.preserveAttachmentCount = 0,
|
||||||
.pPreserveAttachments = nullptr,
|
.pPreserveAttachments = nullptr,
|
||||||
};
|
};
|
||||||
VkSubpassDependency dependency{
|
VkSubpassDependency dependency{
|
||||||
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
||||||
.dstSubpass = 0,
|
.dstSubpass = 0,
|
||||||
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||||
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||||
.srcAccessMask = 0,
|
.srcAccessMask = 0,
|
||||||
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
.dependencyFlags = 0
|
.dependencyFlags = 0
|
||||||
};
|
};
|
||||||
VkRenderPassCreateInfo renderPassInfo{
|
VkRenderPassCreateInfo renderPassInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.attachmentCount = 1,
|
.attachmentCount = attachments.size(),
|
||||||
.pAttachments = &colorAttachment,
|
.pAttachments = attachments.data(),
|
||||||
.subpassCount = 1,
|
.subpassCount = 1,
|
||||||
.pSubpasses = &subpass,
|
.pSubpasses = &subpass,
|
||||||
.dependencyCount = 1,
|
.dependencyCount = 1,
|
||||||
@ -194,9 +266,9 @@ namespace engine {
|
|||||||
/* create image view and framebuffer for each image */
|
/* create image view and framebuffer for each image */
|
||||||
sc->images.resize(swapchainImageCount);
|
sc->images.resize(swapchainImageCount);
|
||||||
for (uint32_t i = 0; i < swapchainImageCount; i++) {
|
for (uint32_t i = 0; i < swapchainImageCount; i++) {
|
||||||
auto& [image, view, framebuffer] = sc->images.at(i);
|
auto& [image, imageView, framebuffer] = sc->images.at(i);
|
||||||
|
|
||||||
if (view != VK_NULL_HANDLE) vkDestroyImageView(sc->device, view, nullptr);
|
if (imageView != VK_NULL_HANDLE) vkDestroyImageView(sc->device, imageView, nullptr);
|
||||||
if (framebuffer != VK_NULL_HANDLE) vkDestroyFramebuffer(sc->device, framebuffer, nullptr);
|
if (framebuffer != VK_NULL_HANDLE) vkDestroyFramebuffer(sc->device, framebuffer, nullptr);
|
||||||
|
|
||||||
image = swapchainImages[i];
|
image = swapchainImages[i];
|
||||||
@ -218,16 +290,20 @@ namespace engine {
|
|||||||
viewInfo.subresourceRange.levelCount = 1;
|
viewInfo.subresourceRange.levelCount = 1;
|
||||||
viewInfo.subresourceRange.baseArrayLayer = 0;
|
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
viewInfo.subresourceRange.layerCount = 1;
|
viewInfo.subresourceRange.layerCount = 1;
|
||||||
VkResult res = vkCreateImageView(sc->device, &viewInfo, nullptr, &view);
|
VkResult res = vkCreateImageView(sc->device, &viewInfo, nullptr, &imageView);
|
||||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create image view from swapchain image!");
|
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create image view from swapchain image!");
|
||||||
|
|
||||||
|
std::array<VkImageView, 2> attachments {
|
||||||
|
imageView, sc->depthStencil.view
|
||||||
|
};
|
||||||
|
|
||||||
VkFramebufferCreateInfo fbInfo{};
|
VkFramebufferCreateInfo fbInfo{};
|
||||||
fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
fbInfo.pNext = nullptr;
|
fbInfo.pNext = nullptr;
|
||||||
fbInfo.flags = 0;
|
fbInfo.flags = 0;
|
||||||
fbInfo.renderPass = sc->renderpass;
|
fbInfo.renderPass = sc->renderpass;
|
||||||
fbInfo.attachmentCount = 1;
|
fbInfo.attachmentCount = attachments.size();
|
||||||
fbInfo.pAttachments = &view;
|
fbInfo.pAttachments = attachments.data();
|
||||||
fbInfo.width = sc->extent.width;
|
fbInfo.width = sc->extent.width;
|
||||||
fbInfo.height = sc->extent.height;
|
fbInfo.height = sc->extent.height;
|
||||||
fbInfo.layers = 1;
|
fbInfo.layers = 1;
|
||||||
@ -246,7 +322,9 @@ namespace engine {
|
|||||||
vkDestroyImageView(sc.device, view, nullptr);
|
vkDestroyImageView(sc.device, view, nullptr);
|
||||||
}
|
}
|
||||||
vkDestroyRenderPass(sc.device, sc.renderpass, nullptr);
|
vkDestroyRenderPass(sc.device, sc.renderpass, nullptr);
|
||||||
|
vkDestroyImageView(sc.device, sc.depthStencil.view, nullptr);
|
||||||
|
vmaDestroyImage(sc.allocator, sc.depthStencil.image, sc.depthStencil.allocation);
|
||||||
vkDestroySwapchainKHR(sc.device, sc.swapchain, nullptr);
|
vkDestroySwapchainKHR(sc.device, sc.swapchain, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,32 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <SDL2/SDL_vulkan.h>
|
#include <SDL2/SDL_vulkan.h>
|
||||||
|
|
||||||
#include <volk.h>
|
#include <volk.h>
|
||||||
|
|
||||||
|
#include <vk_mem_alloc.h>
|
||||||
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
|
|
||||||
struct Swapchain {
|
struct Swapchain {
|
||||||
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
|
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
|
||||||
VkDevice device = VK_NULL_HANDLE; // the associated device
|
VkDevice device = VK_NULL_HANDLE; // the associated device
|
||||||
|
VmaAllocator allocator = VK_NULL_HANDLE; // the associated allocator
|
||||||
VkSurfaceFormatKHR surfaceFormat{};
|
VkSurfaceFormatKHR surfaceFormat{};
|
||||||
VkSurfaceCapabilitiesKHR surfaceCapabilities{};
|
VkSurfaceCapabilitiesKHR surfaceCapabilities{};
|
||||||
VkPresentModeKHR presentMode{};
|
VkPresentModeKHR presentMode{};
|
||||||
VkExtent2D extent{};
|
VkExtent2D extent{};
|
||||||
VkRenderPass renderpass = VK_NULL_HANDLE;
|
VkRenderPass renderpass = VK_NULL_HANDLE;
|
||||||
std::vector<std::tuple<VkImage, VkImageView, VkFramebuffer>> images{};
|
std::vector<std::tuple<VkImage, VkImageView, VkFramebuffer>> images{};
|
||||||
|
struct DepthStencil {
|
||||||
|
VkImage image = VK_NULL_HANDLE;
|
||||||
|
VmaAllocation allocation = VK_NULL_HANDLE;
|
||||||
|
VkImageView view = VK_NULL_HANDLE;
|
||||||
|
VkFormat format{};
|
||||||
|
} depthStencil{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SwapchainInfo {
|
struct SwapchainInfo {
|
||||||
@ -24,6 +34,7 @@ namespace engine {
|
|||||||
VkPhysicalDevice physicalDevice;
|
VkPhysicalDevice physicalDevice;
|
||||||
VkSurfaceKHR surface;
|
VkSurfaceKHR surface;
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
|
VmaAllocator allocator;
|
||||||
bool vsync;
|
bool vsync;
|
||||||
bool waitForPresent;
|
bool waitForPresent;
|
||||||
};
|
};
|
||||||
|
@ -107,7 +107,7 @@ void playGame(bool enableFrameLimiter)
|
|||||||
/* cube */
|
/* cube */
|
||||||
{
|
{
|
||||||
uint32_t cube = myScene->createEntity("cube");
|
uint32_t cube = myScene->createEntity("cube");
|
||||||
myScene->getComponent<engine::TransformComponent>(cube)->position = glm::vec3{ -0.5f, -0.5f, -0.5f };
|
myScene->getComponent<engine::TransformComponent>(cube)->position = glm::vec3{ -0.5f, -0.5f + 5.0f, -0.5f };
|
||||||
auto cubeRenderable = myScene->addComponent<engine::RenderableComponent>(cube);
|
auto cubeRenderable = myScene->addComponent<engine::RenderableComponent>(cube);
|
||||||
cubeRenderable->material = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.standard"));
|
cubeRenderable->material = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.standard"));
|
||||||
cubeRenderable->mesh = genCuboidMesh(app.gfx(), 1.0f, 1.0f, 1.0f, 1);
|
cubeRenderable->mesh = genCuboidMesh(app.gfx(), 1.0f, 1.0f, 1.0f, 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user