This commit is contained in:
bailwillharr 2023-03-15 23:11:24 +00:00
parent 75174fea2c
commit cd617e8619
13 changed files with 300 additions and 161 deletions

View File

@ -31,10 +31,16 @@ 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;
}; };
gfx::DescriptorBuffer* setZeroBuffer; gfx::DescriptorBuffer* setZeroBuffer;
/* uniforms for per-frame data */
const gfx::DescriptorSetLayout* setOneLayout;
const gfx::DescriptorSet* setOne;
struct SetOneBuffer {
glm::mat4 view;
};
gfx::DescriptorBuffer* setOneBuffer;
}; };
class Application { class Application {

View File

@ -5,17 +5,20 @@ layout( push_constant ) uniform Constants {
} constants; } constants;
layout(set = 0, binding = 0) uniform SetZeroBuffer { layout(set = 0, binding = 0) uniform SetZeroBuffer {
mat4 view;
mat4 proj; mat4 proj;
} setZeroBuffer; } setZeroBuffer;
layout(set = 1, binding = 0) uniform SetOneBuffer {
mat4 view;
} setOneBuffer;
layout(location = 0) in vec3 inPosition; layout(location = 0) in vec3 inPosition;
layout(location = 2) in vec2 inUV; layout(location = 2) in vec2 inUV;
layout(location = 0) out vec2 fragUV; layout(location = 0) out vec2 fragUV;
void main() { void main() {
mat4 myView = setZeroBuffer.view; mat4 myView = setOneBuffer.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;

View File

@ -5,10 +5,13 @@ layout( push_constant ) uniform Constants {
} constants; } constants;
layout(set = 0, binding = 0) uniform SetZeroBuffer { layout(set = 0, binding = 0) uniform SetZeroBuffer {
mat4 view;
mat4 proj; mat4 proj;
} setZeroBuffer; } setZeroBuffer;
layout(set = 1, binding = 0) uniform SetOneBuffer {
mat4 view;
} setOneBuffer;
layout(location = 0) in vec3 inPosition; layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNorm; layout(location = 1) in vec3 inNorm;
layout(location = 2) in vec2 inUV; layout(location = 2) in vec2 inUV;
@ -19,12 +22,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 * setZeroBuffer.view * constants.model * vec4(inPosition, 1.0); gl_Position = setZeroBuffer.proj * setOneBuffer.view * constants.model * vec4(inPosition, 1.0);
fragPos = vec3(setZeroBuffer.view * constants.model * vec4(inPosition, 1.0)); fragPos = vec3(setOneBuffer.view * constants.model * vec4(inPosition, 1.0));
fragNorm = mat3(transpose(inverse(setZeroBuffer.view * constants.model))) * inNorm; fragNorm = mat3(transpose(inverse(setOneBuffer.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(setZeroBuffer.view * vec4(lightPos, 1.0)); fragLightPos = vec3(setOneBuffer.view * vec4(lightPos, 1.0));
} }

View File

@ -75,15 +75,23 @@ namespace engine {
// initialise the render data // initialise the render data
renderData.gfxdev = std::make_unique<GFXDevice>(appName, appVersion, m_window->getHandle(), graphicsSettings); renderData.gfxdev = std::make_unique<GFXDevice>(appName, appVersion, m_window->getHandle(), graphicsSettings);
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 initialSetZeroData{
.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),
}; };
renderData.setZeroBuffer = gfx()->createDescriptorBuffer(sizeof(RenderData::SetZeroBuffer), &initialData); renderData.setZeroBuffer = gfx()->createDescriptorBuffer(sizeof(RenderData::SetZeroBuffer), &initialSetZeroData);
gfx()->updateDescriptor(renderData.setZero, 0, renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer)); gfx()->updateDescriptor(renderData.setZero, 0, renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer));
renderData.setOneLayout = gfx()->createDescriptorSetLayout();
renderData.setOne = gfx()->allocateDescriptorSet(renderData.setOneLayout);
RenderData::SetOneBuffer initialSetOneData{
.view = glm::mat4{ 1.0f },
};
renderData.setOneBuffer = gfx()->createDescriptorBuffer(sizeof(RenderData::SetOneBuffer), &initialSetOneData);
gfx()->updateDescriptor(renderData.setOne, 0, renderData.setOneBuffer, 0, sizeof(RenderData::SetOneBuffer));
// default resources // default resources
{ {
resources::Shader::VertexParams vertParams{}; resources::Shader::VertexParams vertParams{};
@ -99,7 +107,7 @@ namespace engine {
); );
getResourceManager<resources::Shader>()->addPersistent("builtin.standard", std::move(texturedShader)); getResourceManager<resources::Shader>()->addPersistent("builtin.standard", std::move(texturedShader));
} }
{ if (0) {
resources::Shader::VertexParams vertParams{}; resources::Shader::VertexParams vertParams{};
vertParams.hasNormal = true; vertParams.hasNormal = true;
vertParams.hasUV0 = true; vertParams.hasUV0 = true;
@ -127,6 +135,8 @@ namespace engine {
Application::~Application() Application::~Application()
{ {
gfx()->destroyDescriptorBuffer(renderData.setOneBuffer);
gfx()->destroyDescriptorSetLayout(renderData.setOneLayout);
gfx()->destroyDescriptorBuffer(renderData.setZeroBuffer); gfx()->destroyDescriptorBuffer(renderData.setZeroBuffer);
gfx()->destroyDescriptorSetLayout(renderData.setZeroLayout); gfx()->destroyDescriptorSetLayout(renderData.setZeroLayout);
} }

View File

@ -1,5 +1,14 @@
// The implementation of the graphics layer using Vulkan 1.3. // The implementation of the graphics layer using Vulkan 1.3.
/* IMPORTANT INFORMATION
*
* When allocating memory with VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, always set a memory priority.
* This feature uses the device extension VK_EXT_memory_priority. Depth buffers have a priority of 0.9f.
* Other, non-essential allocations will have a priority of 0.5f.
*
*
*/
#include <assert.h> #include <assert.h>
#include <unordered_set> #include <unordered_set>
#include <array> #include <array>
@ -84,6 +93,7 @@ namespace engine {
FrameData frameData{}; FrameData frameData{};
uint32_t currentFrameIndex = 0; // corresponds to the frameData uint32_t currentFrameIndex = 0; // corresponds to the frameData
uint32_t imageIndex = 0; // for swapchain present uint32_t imageIndex = 0; // for swapchain present
std::vector<VkSemaphore> copySemaphores{};
}; };
struct gfx::DescriptorSetLayout { struct gfx::DescriptorSetLayout {
@ -97,6 +107,7 @@ namespace engine {
struct gfx::DescriptorBuffer { struct gfx::DescriptorBuffer {
gfx::Buffer stagingBuffer{}; gfx::Buffer stagingBuffer{};
std::array<gfx::Buffer, FRAMES_IN_FLIGHT> gpuBuffers; std::array<gfx::Buffer, FRAMES_IN_FLIGHT> gpuBuffers;
std::array<VkSemaphore, FRAMES_IN_FLIGHT> copySemaphores;
}; };
// enum converters // enum converters
@ -268,58 +279,6 @@ namespace engine {
vmaDestroyImage(allocator, target.colorImage, target.colorImageAllocation); vmaDestroyImage(allocator, target.colorImage, target.colorImageAllocation);
} }
static DepthBuffer createDepthBuffer(VkDevice device, VmaAllocator allocator, VkExtent2D extent, VkSampleCountFlagBits msaaSamples)
{
DepthBuffer db{};
[[maybe_unused]] VkResult res;
VkImageCreateInfo imageInfo{};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.extent.width = extent.width;
imageInfo.extent.height = extent.height;
imageInfo.extent.depth = 1;
imageInfo.mipLevels = 1;
imageInfo.arrayLayers = 1;
imageInfo.format = VK_FORMAT_D32_SFLOAT;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageInfo.samples = msaaSamples;
imageInfo.flags = 0;
VmaAllocationCreateInfo allocInfo{};
allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
allocInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
allocInfo.priority = 1.0f;
res = vmaCreateImage(allocator, &imageInfo, &allocInfo, &db.image, &db.allocation, nullptr);
assert(res == VK_SUCCESS);
VkImageViewCreateInfo imageViewInfo{};
imageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewInfo.image = db.image;
imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageViewInfo.format = VK_FORMAT_D32_SFLOAT;
imageViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
imageViewInfo.subresourceRange.baseMipLevel = 0;
imageViewInfo.subresourceRange.levelCount = 1;
imageViewInfo.subresourceRange.baseArrayLayer = 0;
imageViewInfo.subresourceRange.layerCount = 1;
res = vkCreateImageView(device, &imageViewInfo, nullptr, &db.view);
assert(res == VK_SUCCESS);
return db;
}
static void destroyDepthBuffer(DepthBuffer db, VkDevice device, VmaAllocator allocator)
{
vkDestroyImageView(device, db.view, nullptr);
vmaDestroyImage(allocator, db.image, db.allocation);
}
static VkSampleCountFlagBits getMaxSampleCount(VkPhysicalDevice physicalDevice, gfx::MSAALevel maxLevel) static VkSampleCountFlagBits getMaxSampleCount(VkPhysicalDevice physicalDevice, gfx::MSAALevel maxLevel)
{ {
VkSampleCountFlags max = vkinternal::getSampleCountFlags(maxLevel); VkSampleCountFlags max = vkinternal::getSampleCountFlags(maxLevel);
@ -601,9 +560,10 @@ namespace engine {
}; };
DeviceRequirements deviceRequirements{}; DeviceRequirements deviceRequirements{};
deviceRequirements.requiredExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; deviceRequirements.requiredExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME };
deviceRequirements.requiredFeatures.samplerAnisotropy = VK_TRUE; deviceRequirements.requiredFeatures.samplerAnisotropy = VK_TRUE;
deviceRequirements.requiredFeatures.fillModeNonSolid = VK_TRUE; deviceRequirements.requiredFeatures.fillModeNonSolid = VK_TRUE;
deviceRequirements.memoryPriorityFeature = VK_TRUE;
deviceRequirements.formats.push_back( deviceRequirements.formats.push_back(
FormatRequirements{ FormatRequirements{
.format = VK_FORMAT_R8G8B8A8_SRGB, .format = VK_FORMAT_R8G8B8A8_SRGB,
@ -770,6 +730,8 @@ namespace engine {
{ {
VkResult res; VkResult res;
gfx::DrawBuffer* drawBuffer = new gfx::DrawBuffer;
const uint32_t currentFrameIndex = pimpl->FRAMECOUNT % FRAMES_IN_FLIGHT; const uint32_t currentFrameIndex = pimpl->FRAMECOUNT % FRAMES_IN_FLIGHT;
const FrameData frameData = pimpl->frameData[currentFrameIndex]; const FrameData frameData = pimpl->frameData[currentFrameIndex];
@ -779,13 +741,80 @@ namespace engine {
res = vkResetFences(pimpl->device.device, 1, &frameData.renderFence); res = vkResetFences(pimpl->device.device, 1, &frameData.renderFence);
VKCHECK(res); VKCHECK(res);
if (pimpl->device.queues.transferQueues.size() < 2) throw std::runtime_error("Need at least 2 transfer queues!");
/* first empty the descriptor buffer write queue */ /* first empty the descriptor buffer write queue */
auto& writeQueue = pimpl->descriptorBufferWriteQueues[currentFrameIndex]; auto& writeQueue = pimpl->descriptorBufferWriteQueues[currentFrameIndex];
//if (writeQueue.empty() == false) vkQueueWaitIdle(pimpl->device.queues.drawQueues[0]); //if (writeQueue.empty() == false) vkQueueWaitIdle(pimpl->device.queues.drawQueues[0]);
for (gfx::DescriptorBuffer* buffer : writeQueue) { for (gfx::DescriptorBuffer* buffer : writeQueue) {
copyBuffer(pimpl->device.device, pimpl->transferCommandPool, pimpl->device.queues.transferQueues[0], buffer->stagingBuffer.buffer, buffer->gpuBuffers[currentFrameIndex].buffer, buffer->stagingBuffer.size);
// record the command buffer
VkCommandBufferAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandPool = pimpl->transferCommandPool;
allocInfo.commandBufferCount = 1;
VkCommandBuffer commandBuffer;
res = vkAllocateCommandBuffers(pimpl->device.device, &allocInfo, &commandBuffer);
assert(res == VK_SUCCESS);
VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
res = vkBeginCommandBuffer(commandBuffer, &beginInfo);
assert(res == VK_SUCCESS);
VkBufferCopy copyRegion{};
copyRegion.srcOffset = 0;
copyRegion.dstOffset = 0;
copyRegion.size = buffer->stagingBuffer.size;
vkCmdCopyBuffer(commandBuffer, buffer->stagingBuffer.buffer, buffer->gpuBuffers[currentFrameIndex].buffer, 1, &copyRegion);
/* barrier to perform ownership transfer from transferQueue to drawQueue */
VkBufferMemoryBarrier bufferMemoryBarrier{};
bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
bufferMemoryBarrier.pNext = nullptr;
bufferMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
bufferMemoryBarrier.dstAccessMask = 0;
bufferMemoryBarrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
bufferMemoryBarrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
bufferMemoryBarrier.buffer = buffer->gpuBuffers[currentFrameIndex].buffer;
bufferMemoryBarrier.offset = 0;
bufferMemoryBarrier.size = buffer->stagingBuffer.size;
vkCmdPipelineBarrier(
commandBuffer,
VK_PIPELINE_STAGE_TRANSFER_BIT, // srcStageMask
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, // dstStageMask
0,
0,
nullptr,
1,
&bufferMemoryBarrier,
0,
nullptr
);
res = vkEndCommandBuffer(commandBuffer);
assert(res == VK_SUCCESS);
// submit
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &buffer->copySemaphores[currentFrameIndex];
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = &frameData.renderSemaphore;
res = vkQueueSubmit(pimpl->device.queues.transferQueues[1], 1, &submitInfo, VK_NULL_HANDLE);
assert(res == VK_SUCCESS);
drawBuffer->copySemaphores.push_back(buffer->copySemaphores[currentFrameIndex]);
} }
writeQueue.clear();
uint32_t swapchainImageIndex; uint32_t swapchainImageIndex;
@ -819,6 +848,34 @@ namespace engine {
{ // RECORDING { // RECORDING
for (gfx::DescriptorBuffer* buffer : writeQueue) {
/* barrier to perform ownership transfer from transferQueue to drawQueue (ACQUIRE) */
VkBufferMemoryBarrier bufferMemoryBarrier{};
bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
bufferMemoryBarrier.pNext = nullptr;
bufferMemoryBarrier.srcAccessMask = 0;
bufferMemoryBarrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT;
bufferMemoryBarrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
bufferMemoryBarrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
bufferMemoryBarrier.buffer = buffer->gpuBuffers[currentFrameIndex].buffer;
bufferMemoryBarrier.offset = 0;
bufferMemoryBarrier.size = buffer->stagingBuffer.size;
vkCmdPipelineBarrier(
frameData.drawBuf,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // srcStageMask
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, // dstStageMask
0,
0,
nullptr,
1,
&bufferMemoryBarrier,
0,
nullptr
);
}
writeQueue.clear();
std::array<VkClearValue, 2> clearValues{}; // Using same value for all components enables compression according to NVIDIA Best Practices std::array<VkClearValue, 2> clearValues{}; // Using same value for all components enables compression according to NVIDIA Best Practices
clearValues[0].color.float32[0] = 1.0f; clearValues[0].color.float32[0] = 1.0f;
clearValues[0].color.float32[1] = 1.0f; clearValues[0].color.float32[1] = 1.0f;
@ -854,7 +911,6 @@ namespace engine {
} }
// hand command buffer over to caller // hand command buffer over to caller
gfx::DrawBuffer* drawBuffer = new gfx::DrawBuffer;
drawBuffer->frameData = frameData; drawBuffer->frameData = frameData;
drawBuffer->currentFrameIndex = currentFrameIndex; drawBuffer->currentFrameIndex = currentFrameIndex;
drawBuffer->imageIndex = swapchainImageIndex; drawBuffer->imageIndex = swapchainImageIndex;
@ -877,14 +933,20 @@ namespace engine {
// SUBMIT // SUBMIT
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; std::vector<VkPipelineStageFlags> waitDstStageMasks{};
for (size_t i = 0; i < drawBuffer->copySemaphores.size(); i++) {
waitDstStageMasks.push_back(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT);
}
drawBuffer->copySemaphores.push_back(drawBuffer->frameData.presentSemaphore);
waitDstStageMasks.push_back(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
VkSubmitInfo submitInfo{ VkSubmitInfo submitInfo{
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = nullptr, .pNext = nullptr,
.waitSemaphoreCount = 1, .waitSemaphoreCount = (uint32_t)drawBuffer->copySemaphores.size(),
.pWaitSemaphores = &drawBuffer->frameData.presentSemaphore, .pWaitSemaphores = drawBuffer->copySemaphores.data(),
.pWaitDstStageMask = &waitStage, .pWaitDstStageMask = waitDstStageMasks.data(),
.commandBufferCount = 1, .commandBufferCount = 1,
.pCommandBuffers = &drawBuffer->frameData.drawBuf, .pCommandBuffers = &drawBuffer->frameData.drawBuf,
.signalSemaphoreCount = 1, .signalSemaphoreCount = 1,
@ -1280,6 +1342,12 @@ namespace engine {
/* create the device-local set of buffers */ /* create the device-local set of buffers */
for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) { for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) {
VkSemaphoreCreateInfo semInfo{};
semInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
semInfo.pNext = nullptr;
semInfo.flags = 0;
VKCHECK(vkCreateSemaphore(pimpl->device.device, &semInfo, nullptr, &out->copySemaphores[i]));
out->gpuBuffers[i].size = out->stagingBuffer.size; out->gpuBuffers[i].size = out->stagingBuffer.size;
out->gpuBuffers[i].type = gfx::BufferType::UNIFORM; out->gpuBuffers[i].type = gfx::BufferType::UNIFORM;
out->gpuBuffers[i].hostVisible = false; out->gpuBuffers[i].hostVisible = false;
@ -1309,6 +1377,7 @@ namespace engine {
{ {
for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) { for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) {
vmaDestroyBuffer(pimpl->allocator, descriptorBuffer->gpuBuffers[i].buffer, descriptorBuffer->gpuBuffers[i].allocation); vmaDestroyBuffer(pimpl->allocator, descriptorBuffer->gpuBuffers[i].buffer, descriptorBuffer->gpuBuffers[i].allocation);
vkDestroySemaphore(pimpl->device.device, descriptorBuffer->copySemaphores[i], nullptr);
} }
vmaDestroyBuffer(pimpl->allocator, descriptorBuffer->stagingBuffer.buffer, descriptorBuffer->stagingBuffer.allocation); vmaDestroyBuffer(pimpl->allocator, descriptorBuffer->stagingBuffer.buffer, descriptorBuffer->stagingBuffer.allocation);

View File

@ -45,6 +45,7 @@ namespace engine::resources {
info.alphaBlending = alphaBlending; info.alphaBlending = alphaBlending;
info.backfaceCulling = cullBackFace; info.backfaceCulling = cullBackFace;
info.descriptorSetLayouts.push_back(renderData->setZeroLayout); info.descriptorSetLayouts.push_back(renderData->setZeroLayout);
info.descriptorSetLayouts.push_back(renderData->setOneLayout);
m_pipeline = m_gfx->createPipeline(info); m_pipeline = m_gfx->createPipeline(info);

View File

@ -42,43 +42,69 @@ namespace engine {
uint32_t w, h; uint32_t w, h;
m_gfx->getViewportSize(&w, &h); m_gfx->getViewportSize(&w, &h);
m_viewportAspectRatio = (float)w / (float)h; m_viewportAspectRatio = (float)w / (float)h;
}
const float verticalFovRadians = glm::radians(m_camera.verticalFovDegrees); const float verticalFovRadians = glm::radians(m_camera.verticalFovDegrees);
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 setZeroBuffer{
.view = viewMatrix,
.proj = projMatrix .proj = projMatrix
}; };
m_gfx->writeDescriptorBuffer(renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer), &uniform); m_gfx->writeDescriptorBuffer(renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer), &setZeroBuffer);
}
RenderData::SetOneBuffer setOneBuffer{
.view = viewMatrix
};
//m_gfx->writeDescriptorBuffer(renderData.setOneBuffer, 0, sizeof(RenderData::SetOneBuffer), &setOneBuffer);
/* render all renderable entities */ /* render all renderable entities */
struct PushConstants {
glm::mat4 model;
};
struct DrawCallData {
const gfx::Buffer* vb;
const gfx::Buffer* ib;
uint32_t indexCount;
PushConstants pushConsts;
};
std::unordered_map <const gfx::Pipeline*, std::vector<DrawCallData>> pipelineDrawCalls{};
for (uint32_t entity : m_entities) { for (uint32_t entity : m_entities) {
auto r = m_scene->getComponent<RenderableComponent>(entity); auto r = m_scene->getComponent<RenderableComponent>(entity);
assert(r != nullptr);
assert(r->material != nullptr);
assert(r->mesh != nullptr);
if (r->shown == false) continue; if (r->shown == false) continue;
auto t = m_scene->getComponent<TransformComponent>(entity); auto t = m_scene->getComponent<TransformComponent>(entity);
assert(t != nullptr);
assert(r->material != nullptr); const gfx::Pipeline* pipeline = r->material->getShader()->getPipeline();
assert(r->mesh != nullptr); DrawCallData data{};
//assert(r->material->m_texture != nullptr); data.vb = r->mesh->getVB();
data.ib = r->mesh->getIB();
data.indexCount = r->mesh->getCount();
data.pushConsts.model = t->worldMatrix;
struct { pipelineDrawCalls[pipeline].push_back(data);
glm::mat4 model;
} pushConsts{};
pushConsts.model = t->worldMatrix; }
m_gfx->cmdBindPipeline(renderData.drawBuffer, r->material->getShader()->getPipeline()); /* these descriptor set bindings should persist across pipeline changes */
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, r->material->getShader()->getPipeline(), renderData.setZero, 0); const gfx::Pipeline* firstPipeline = pipelineDrawCalls.begin()->first;
m_gfx->cmdPushConstants(renderData.drawBuffer, r->material->getShader()->getPipeline(), 0, sizeof(pushConsts), &pushConsts); m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, firstPipeline, renderData.setZero, 0);
m_gfx->cmdBindVertexBuffer(renderData.drawBuffer, 0, r->mesh->getVB()); m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, firstPipeline, renderData.setOne, 1);
m_gfx->cmdBindIndexBuffer(renderData.drawBuffer, r->mesh->getIB());
m_gfx->cmdDrawIndexed(renderData.drawBuffer, r->mesh->getCount(), 1, 0, 0, 0);
for (const auto& [pipeline, drawCalls] : pipelineDrawCalls) {
m_gfx->cmdBindPipeline(renderData.drawBuffer, pipeline);
for (const auto& drawCall : drawCalls) {
m_gfx->cmdPushConstants(renderData.drawBuffer, pipeline, 0, sizeof(PushConstants), &drawCall.pushConsts);
m_gfx->cmdBindVertexBuffer(renderData.drawBuffer, 0, drawCall.vb);
m_gfx->cmdBindIndexBuffer(renderData.drawBuffer, drawCall.ib);
m_gfx->cmdDrawIndexed(renderData.drawBuffer, drawCall.indexCount, 1, 0, 0, 0);
}
} }
} }

View File

@ -72,119 +72,126 @@ namespace engine {
} }
/* check features */ /* check features */
VkPhysicalDeviceFeatures devFeatures; VkPhysicalDeviceMemoryPriorityFeaturesEXT memoryPriorityFeatures{};
vkGetPhysicalDeviceFeatures(physDev, &devFeatures); memoryPriorityFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT;
VkPhysicalDeviceFeatures2 devFeatures{};
devFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
devFeatures.pNext = &memoryPriorityFeatures;
vkGetPhysicalDeviceFeatures2(physDev, &devFeatures);
{ {
if (requirements.requiredFeatures.robustBufferAccess) if (requirements.requiredFeatures.robustBufferAccess)
if (devFeatures.robustBufferAccess == VK_FALSE) continue; if (devFeatures.features.robustBufferAccess == VK_FALSE) continue;
if (requirements.requiredFeatures.fullDrawIndexUint32) if (requirements.requiredFeatures.fullDrawIndexUint32)
if (devFeatures.fullDrawIndexUint32 == VK_FALSE) continue; if (devFeatures.features.fullDrawIndexUint32 == VK_FALSE) continue;
if (requirements.requiredFeatures.imageCubeArray == VK_TRUE) if (requirements.requiredFeatures.imageCubeArray == VK_TRUE)
if (devFeatures.imageCubeArray == VK_FALSE) continue; if (devFeatures.features.imageCubeArray == VK_FALSE) continue;
if (requirements.requiredFeatures.independentBlend == VK_TRUE) if (requirements.requiredFeatures.independentBlend == VK_TRUE)
if (devFeatures.independentBlend == VK_FALSE) continue; if (devFeatures.features.independentBlend == VK_FALSE) continue;
if (requirements.requiredFeatures.geometryShader == VK_TRUE) if (requirements.requiredFeatures.geometryShader == VK_TRUE)
if (devFeatures.geometryShader == VK_FALSE) continue; if (devFeatures.features.geometryShader == VK_FALSE) continue;
if (requirements.requiredFeatures.tessellationShader == VK_TRUE) if (requirements.requiredFeatures.tessellationShader == VK_TRUE)
if (devFeatures.tessellationShader == VK_FALSE) continue; if (devFeatures.features.tessellationShader == VK_FALSE) continue;
if (requirements.requiredFeatures.sampleRateShading == VK_TRUE) if (requirements.requiredFeatures.sampleRateShading == VK_TRUE)
if (devFeatures.sampleRateShading == VK_FALSE) continue; if (devFeatures.features.sampleRateShading == VK_FALSE) continue;
if (requirements.requiredFeatures.dualSrcBlend == VK_TRUE) if (requirements.requiredFeatures.dualSrcBlend == VK_TRUE)
if (devFeatures.dualSrcBlend == VK_FALSE) continue; if (devFeatures.features.dualSrcBlend == VK_FALSE) continue;
if (requirements.requiredFeatures.logicOp == VK_TRUE) if (requirements.requiredFeatures.logicOp == VK_TRUE)
if (devFeatures.logicOp == VK_FALSE) continue; if (devFeatures.features.logicOp == VK_FALSE) continue;
if (requirements.requiredFeatures.multiDrawIndirect == VK_TRUE) if (requirements.requiredFeatures.multiDrawIndirect == VK_TRUE)
if (devFeatures.multiDrawIndirect == VK_FALSE) continue; if (devFeatures.features.multiDrawIndirect == VK_FALSE) continue;
if (requirements.requiredFeatures.drawIndirectFirstInstance == VK_TRUE) if (requirements.requiredFeatures.drawIndirectFirstInstance == VK_TRUE)
if (devFeatures.drawIndirectFirstInstance == VK_FALSE) continue; if (devFeatures.features.drawIndirectFirstInstance == VK_FALSE) continue;
if (requirements.requiredFeatures.depthClamp == VK_TRUE) if (requirements.requiredFeatures.depthClamp == VK_TRUE)
if (devFeatures.depthClamp == VK_FALSE) continue; if (devFeatures.features.depthClamp == VK_FALSE) continue;
if (requirements.requiredFeatures.depthBiasClamp == VK_TRUE) if (requirements.requiredFeatures.depthBiasClamp == VK_TRUE)
if (devFeatures.depthBiasClamp == VK_FALSE) continue; if (devFeatures.features.depthBiasClamp == VK_FALSE) continue;
if (requirements.requiredFeatures.fillModeNonSolid == VK_TRUE) if (requirements.requiredFeatures.fillModeNonSolid == VK_TRUE)
if (devFeatures.fillModeNonSolid == VK_FALSE) continue; if (devFeatures.features.fillModeNonSolid == VK_FALSE) continue;
if (requirements.requiredFeatures.depthBounds == VK_TRUE) if (requirements.requiredFeatures.depthBounds == VK_TRUE)
if (devFeatures.depthBounds == VK_FALSE) continue; if (devFeatures.features.depthBounds == VK_FALSE) continue;
if (requirements.requiredFeatures.wideLines == VK_TRUE) if (requirements.requiredFeatures.wideLines == VK_TRUE)
if (devFeatures.wideLines == VK_FALSE) continue; if (devFeatures.features.wideLines == VK_FALSE) continue;
if (requirements.requiredFeatures.largePoints == VK_TRUE) if (requirements.requiredFeatures.largePoints == VK_TRUE)
if (devFeatures.largePoints == VK_FALSE) continue; if (devFeatures.features.largePoints == VK_FALSE) continue;
if (requirements.requiredFeatures.alphaToOne == VK_TRUE) if (requirements.requiredFeatures.alphaToOne == VK_TRUE)
if (devFeatures.alphaToOne == VK_FALSE) continue; if (devFeatures.features.alphaToOne == VK_FALSE) continue;
if (requirements.requiredFeatures.multiViewport == VK_TRUE) if (requirements.requiredFeatures.multiViewport == VK_TRUE)
if (devFeatures.multiViewport == VK_FALSE) continue; if (devFeatures.features.multiViewport == VK_FALSE) continue;
if (requirements.requiredFeatures.samplerAnisotropy == VK_TRUE) if (requirements.requiredFeatures.samplerAnisotropy == VK_TRUE)
if (devFeatures.samplerAnisotropy == VK_FALSE) continue; if (devFeatures.features.samplerAnisotropy == VK_FALSE) continue;
if (requirements.requiredFeatures.textureCompressionETC2 == VK_TRUE) if (requirements.requiredFeatures.textureCompressionETC2 == VK_TRUE)
if (devFeatures.textureCompressionETC2 == VK_FALSE) continue; if (devFeatures.features.textureCompressionETC2 == VK_FALSE) continue;
if (requirements.requiredFeatures.textureCompressionASTC_LDR == VK_TRUE) if (requirements.requiredFeatures.textureCompressionASTC_LDR == VK_TRUE)
if (devFeatures.textureCompressionASTC_LDR == VK_FALSE) continue; if (devFeatures.features.textureCompressionASTC_LDR == VK_FALSE) continue;
if (requirements.requiredFeatures.textureCompressionBC == VK_TRUE) if (requirements.requiredFeatures.textureCompressionBC == VK_TRUE)
if (devFeatures.textureCompressionBC == VK_FALSE) continue; if (devFeatures.features.textureCompressionBC == VK_FALSE) continue;
if (requirements.requiredFeatures.occlusionQueryPrecise == VK_TRUE) if (requirements.requiredFeatures.occlusionQueryPrecise == VK_TRUE)
if (devFeatures.occlusionQueryPrecise == VK_FALSE) continue; if (devFeatures.features.occlusionQueryPrecise == VK_FALSE) continue;
if (requirements.requiredFeatures.pipelineStatisticsQuery == VK_TRUE) if (requirements.requiredFeatures.pipelineStatisticsQuery == VK_TRUE)
if (devFeatures.pipelineStatisticsQuery == VK_FALSE) continue; if (devFeatures.features.pipelineStatisticsQuery == VK_FALSE) continue;
if (requirements.requiredFeatures.vertexPipelineStoresAndAtomics == VK_TRUE) if (requirements.requiredFeatures.vertexPipelineStoresAndAtomics == VK_TRUE)
if (devFeatures.vertexPipelineStoresAndAtomics == VK_FALSE) continue; if (devFeatures.features.vertexPipelineStoresAndAtomics == VK_FALSE) continue;
if (requirements.requiredFeatures.fragmentStoresAndAtomics == VK_TRUE) if (requirements.requiredFeatures.fragmentStoresAndAtomics == VK_TRUE)
if (devFeatures.fragmentStoresAndAtomics == VK_FALSE) continue; if (devFeatures.features.fragmentStoresAndAtomics == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderTessellationAndGeometryPointSize == VK_TRUE) if (requirements.requiredFeatures.shaderTessellationAndGeometryPointSize == VK_TRUE)
if (devFeatures.shaderTessellationAndGeometryPointSize == VK_FALSE) continue; if (devFeatures.features.shaderTessellationAndGeometryPointSize == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderImageGatherExtended == VK_TRUE) if (requirements.requiredFeatures.shaderImageGatherExtended == VK_TRUE)
if (devFeatures.shaderImageGatherExtended == VK_FALSE) continue; if (devFeatures.features.shaderImageGatherExtended == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderStorageImageExtendedFormats == VK_TRUE) if (requirements.requiredFeatures.shaderStorageImageExtendedFormats == VK_TRUE)
if (devFeatures.shaderStorageImageExtendedFormats == VK_FALSE) continue; if (devFeatures.features.shaderStorageImageExtendedFormats == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderStorageImageMultisample == VK_TRUE) if (requirements.requiredFeatures.shaderStorageImageMultisample == VK_TRUE)
if (devFeatures.shaderStorageImageMultisample == VK_FALSE) continue; if (devFeatures.features.shaderStorageImageMultisample == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderStorageImageReadWithoutFormat == VK_TRUE) if (requirements.requiredFeatures.shaderStorageImageReadWithoutFormat == VK_TRUE)
if (devFeatures.shaderStorageImageReadWithoutFormat == VK_FALSE) continue; if (devFeatures.features.shaderStorageImageReadWithoutFormat == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderStorageImageWriteWithoutFormat == VK_TRUE) if (requirements.requiredFeatures.shaderStorageImageWriteWithoutFormat == VK_TRUE)
if (devFeatures.shaderStorageImageWriteWithoutFormat == VK_FALSE) continue; if (devFeatures.features.shaderStorageImageWriteWithoutFormat == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderUniformBufferArrayDynamicIndexing == VK_TRUE) if (requirements.requiredFeatures.shaderUniformBufferArrayDynamicIndexing == VK_TRUE)
if (devFeatures.shaderUniformBufferArrayDynamicIndexing == VK_FALSE) continue; if (devFeatures.features.shaderUniformBufferArrayDynamicIndexing == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderSampledImageArrayDynamicIndexing == VK_TRUE) if (requirements.requiredFeatures.shaderSampledImageArrayDynamicIndexing == VK_TRUE)
if (devFeatures.shaderSampledImageArrayDynamicIndexing == VK_FALSE) continue; if (devFeatures.features.shaderSampledImageArrayDynamicIndexing == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderStorageBufferArrayDynamicIndexing == VK_TRUE) if (requirements.requiredFeatures.shaderStorageBufferArrayDynamicIndexing == VK_TRUE)
if (devFeatures.shaderStorageBufferArrayDynamicIndexing == VK_FALSE) continue; if (devFeatures.features.shaderStorageBufferArrayDynamicIndexing == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderStorageImageArrayDynamicIndexing == VK_TRUE) if (requirements.requiredFeatures.shaderStorageImageArrayDynamicIndexing == VK_TRUE)
if (devFeatures.shaderStorageImageArrayDynamicIndexing == VK_FALSE) continue; if (devFeatures.features.shaderStorageImageArrayDynamicIndexing == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderClipDistance == VK_TRUE) if (requirements.requiredFeatures.shaderClipDistance == VK_TRUE)
if (devFeatures.shaderClipDistance == VK_FALSE) continue; if (devFeatures.features.shaderClipDistance == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderCullDistance == VK_TRUE) if (requirements.requiredFeatures.shaderCullDistance == VK_TRUE)
if (devFeatures.shaderCullDistance == VK_FALSE) continue; if (devFeatures.features.shaderCullDistance == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderFloat64 == VK_TRUE) if (requirements.requiredFeatures.shaderFloat64 == VK_TRUE)
if (devFeatures.shaderFloat64 == VK_FALSE) continue; if (devFeatures.features.shaderFloat64 == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderInt64 == VK_TRUE) if (requirements.requiredFeatures.shaderInt64 == VK_TRUE)
if (devFeatures.shaderInt64 == VK_FALSE) continue; if (devFeatures.features.shaderInt64 == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderInt16 == VK_TRUE) if (requirements.requiredFeatures.shaderInt16 == VK_TRUE)
if (devFeatures.shaderInt16 == VK_FALSE) continue; if (devFeatures.features.shaderInt16 == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderResourceResidency == VK_TRUE) if (requirements.requiredFeatures.shaderResourceResidency == VK_TRUE)
if (devFeatures.shaderResourceResidency == VK_FALSE) continue; if (devFeatures.features.shaderResourceResidency == VK_FALSE) continue;
if (requirements.requiredFeatures.shaderResourceMinLod == VK_TRUE) if (requirements.requiredFeatures.shaderResourceMinLod == VK_TRUE)
if (devFeatures.shaderResourceMinLod == VK_FALSE) continue; if (devFeatures.features.shaderResourceMinLod == VK_FALSE) continue;
if (requirements.requiredFeatures.sparseBinding == VK_TRUE) if (requirements.requiredFeatures.sparseBinding == VK_TRUE)
if (devFeatures.sparseBinding == VK_FALSE) continue; if (devFeatures.features.sparseBinding == VK_FALSE) continue;
if (requirements.requiredFeatures.sparseResidencyBuffer == VK_TRUE) if (requirements.requiredFeatures.sparseResidencyBuffer == VK_TRUE)
if (devFeatures.sparseResidencyBuffer == VK_FALSE) continue; if (devFeatures.features.sparseResidencyBuffer == VK_FALSE) continue;
if (requirements.requiredFeatures.sparseResidencyImage2D == VK_TRUE) if (requirements.requiredFeatures.sparseResidencyImage2D == VK_TRUE)
if (devFeatures.sparseResidencyImage2D == VK_FALSE) continue; if (devFeatures.features.sparseResidencyImage2D == VK_FALSE) continue;
if (requirements.requiredFeatures.sparseResidencyImage3D == VK_TRUE) if (requirements.requiredFeatures.sparseResidencyImage3D == VK_TRUE)
if (devFeatures.sparseResidencyImage3D == VK_FALSE) continue; if (devFeatures.features.sparseResidencyImage3D == VK_FALSE) continue;
if (requirements.requiredFeatures.sparseResidency2Samples == VK_TRUE) if (requirements.requiredFeatures.sparseResidency2Samples == VK_TRUE)
if (devFeatures.sparseResidency2Samples == VK_FALSE) continue; if (devFeatures.features.sparseResidency2Samples == VK_FALSE) continue;
if (requirements.requiredFeatures.sparseResidency4Samples == VK_TRUE) if (requirements.requiredFeatures.sparseResidency4Samples == VK_TRUE)
if (devFeatures.sparseResidency4Samples == VK_FALSE) continue; if (devFeatures.features.sparseResidency4Samples == VK_FALSE) continue;
if (requirements.requiredFeatures.sparseResidency8Samples == VK_TRUE) if (requirements.requiredFeatures.sparseResidency8Samples == VK_TRUE)
if (devFeatures.sparseResidency8Samples == VK_FALSE) continue; if (devFeatures.features.sparseResidency8Samples == VK_FALSE) continue;
if (requirements.requiredFeatures.sparseResidency16Samples == VK_TRUE) if (requirements.requiredFeatures.sparseResidency16Samples == VK_TRUE)
if (devFeatures.sparseResidency16Samples == VK_FALSE) continue; if (devFeatures.features.sparseResidency16Samples == VK_FALSE) continue;
if (requirements.requiredFeatures.sparseResidencyAliased == VK_TRUE) if (requirements.requiredFeatures.sparseResidencyAliased == VK_TRUE)
if (devFeatures.sparseResidencyAliased == VK_FALSE) continue; if (devFeatures.features.sparseResidencyAliased == VK_FALSE) continue;
if (requirements.requiredFeatures.variableMultisampleRate == VK_TRUE) if (requirements.requiredFeatures.variableMultisampleRate == VK_TRUE)
if (devFeatures.variableMultisampleRate == VK_FALSE) continue; if (devFeatures.features.variableMultisampleRate == VK_FALSE) continue;
if (requirements.requiredFeatures.inheritedQueries == VK_TRUE) if (requirements.requiredFeatures.inheritedQueries == VK_TRUE)
if (devFeatures.inheritedQueries == VK_FALSE) continue; if (devFeatures.features.inheritedQueries == VK_FALSE) continue;
if (requirements.memoryPriorityFeature == VK_TRUE)
if (memoryPriorityFeatures.memoryPriority == VK_FALSE) continue;
} }
bool formatsSupported = true; bool formatsSupported = true;
@ -295,10 +302,19 @@ namespace engine {
}); });
} }
/* set enabled features */
VkPhysicalDeviceMemoryPriorityFeaturesEXT memoryPriorityFeaturesToEnable{};
memoryPriorityFeaturesToEnable.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT;
memoryPriorityFeaturesToEnable.memoryPriority = requirements.memoryPriorityFeature;
VkPhysicalDeviceFeatures2 featuresToEnable{};
featuresToEnable.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
featuresToEnable.pNext = &memoryPriorityFeaturesToEnable;
featuresToEnable.features = requirements.requiredFeatures;
/* create device now */ /* create device now */
VkDeviceCreateInfo deviceCreateInfo{ VkDeviceCreateInfo deviceCreateInfo{
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = nullptr, .pNext = &featuresToEnable,
.flags = 0, .flags = 0,
.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size()), .queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size()),
.pQueueCreateInfos = queueCreateInfos.data(), .pQueueCreateInfos = queueCreateInfos.data(),
@ -306,7 +322,7 @@ namespace engine {
.ppEnabledLayerNames = nullptr, // deprecated and ignored .ppEnabledLayerNames = nullptr, // deprecated and ignored
.enabledExtensionCount = static_cast<uint32_t>(requirements.requiredExtensions.size()), .enabledExtensionCount = static_cast<uint32_t>(requirements.requiredExtensions.size()),
.ppEnabledExtensionNames = requirements.requiredExtensions.data(), .ppEnabledExtensionNames = requirements.requiredExtensions.data(),
.pEnabledFeatures = &requirements.requiredFeatures .pEnabledFeatures = nullptr,
}; };
res = vkCreateDevice(d.physicalDevice, &deviceCreateInfo, nullptr, &d.device); res = vkCreateDevice(d.physicalDevice, &deviceCreateInfo, nullptr, &d.device);

View File

@ -14,6 +14,7 @@ namespace engine {
struct DeviceRequirements { struct DeviceRequirements {
std::vector<const char*> requiredExtensions; std::vector<const char*> requiredExtensions;
VkPhysicalDeviceFeatures requiredFeatures; VkPhysicalDeviceFeatures requiredFeatures;
VkBool32 memoryPriorityFeature;
std::vector<FormatRequirements> formats{}; std::vector<FormatRequirements> formats{};
}; };

View File

@ -44,7 +44,7 @@ namespace engine {
}; };
VmaAllocatorCreateInfo createInfo{ VmaAllocatorCreateInfo createInfo{
.flags = 0, .flags = VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT,
.physicalDevice = physicalDevice, .physicalDevice = physicalDevice,
.device = device, .device = device,
.preferredLargeHeapBlockSize = 0, .preferredLargeHeapBlockSize = 0,

View File

@ -47,7 +47,9 @@ namespace engine {
} }
} }
throw std::runtime_error("Unable to find validation layer!"); LOG_WARN("Unable to find validation layer!");
return nullptr;
} }
@ -144,28 +146,27 @@ namespace engine {
const std::vector<const char*> windowExtensions = getWindowExtensions(window); const std::vector<const char*> windowExtensions = getWindowExtensions(window);
std::vector<const char*> instanceExtensionsToUse = windowExtensions; std::vector<const char*> instanceExtensionsToUse = windowExtensions;
if (useValidation) instanceExtensionsToUse.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
const char* validationLayer = nullptr; const char* validationLayer = nullptr;
if (useValidation) { if (useValidation) {
validationLayer = getValidationLayer(); validationLayer = getValidationLayer();
} }
if (validationLayer) instanceExtensionsToUse.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
VkDebugUtilsMessengerCreateInfoEXT debugMessengerInfo = getDebugMessengerCreateInfo(validationLevel); VkDebugUtilsMessengerCreateInfoEXT debugMessengerInfo = getDebugMessengerCreateInfo(validationLevel);
VkInstanceCreateInfo instanceInfo{}; VkInstanceCreateInfo instanceInfo{};
instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
if (validationLayer) {
instanceInfo.pNext = &debugMessengerInfo; instanceInfo.pNext = &debugMessengerInfo;
}
instanceInfo.flags = 0; instanceInfo.flags = 0;
instanceInfo.pApplicationInfo = &applicationInfo; instanceInfo.pApplicationInfo = &applicationInfo;
if (validationLayer) { if (validationLayer) {
instanceInfo.enabledLayerCount = 1; instanceInfo.enabledLayerCount = 1;
instanceInfo.ppEnabledLayerNames = &validationLayer; instanceInfo.ppEnabledLayerNames = &validationLayer;
} }
else {
instanceInfo.enabledLayerCount = 0;
instanceInfo.ppEnabledLayerNames = nullptr;
}
instanceInfo.enabledExtensionCount = (uint32_t)instanceExtensionsToUse.size(); instanceInfo.enabledExtensionCount = (uint32_t)instanceExtensionsToUse.size();
instanceInfo.ppEnabledExtensionNames = instanceExtensionsToUse.data(); instanceInfo.ppEnabledExtensionNames = instanceExtensionsToUse.data();

View File

@ -286,7 +286,7 @@ namespace engine {
VmaAllocationCreateInfo depthAllocInfo{}; VmaAllocationCreateInfo depthAllocInfo{};
depthAllocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; depthAllocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
depthAllocInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; depthAllocInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
depthAllocInfo.priority = 1.0f; depthAllocInfo.priority = 0.9f;
res = vmaCreateImage(sc->allocator, &depthImageInfo, &depthAllocInfo, &depthImage, &depthAllocation, nullptr); res = vmaCreateImage(sc->allocator, &depthImageInfo, &depthAllocInfo, &depthImage, &depthAllocation, nullptr);
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create depth buffer image! Code: " + std::to_string(res)); if (res != VK_SUCCESS) throw std::runtime_error("Failed to create depth buffer image! Code: " + std::to_string(res));

View File

@ -99,7 +99,7 @@ void playGame(GameSettings settings)
); );
/* skybox */ /* skybox */
{ if (0) {
uint32_t skybox = myScene->createEntity("skybox"); uint32_t skybox = myScene->createEntity("skybox");
auto skyboxRenderable = myScene->addComponent<engine::RenderableComponent>(skybox); auto skyboxRenderable = myScene->addComponent<engine::RenderableComponent>(skybox);
skyboxRenderable->material = std::make_unique<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.skybox")); skyboxRenderable->material = std::make_unique<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.skybox"));
@ -116,6 +116,9 @@ void playGame(GameSettings settings)
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);
auto cubeCollider = myScene->addComponent<engine::ColliderComponent>(cube);
cubeCollider->isStatic = true;
cubeCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f } };
} }
/* floor */ /* floor */