mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
DO lots
This commit is contained in:
parent
75174fea2c
commit
cd617e8619
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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, ©Region);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 glm::mat4 projMatrix = glm::perspectiveZO(verticalFovRadians, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar);
|
||||||
|
/* update SET 0 */
|
||||||
|
RenderData::SetZeroBuffer setZeroBuffer{
|
||||||
|
.proj = projMatrix
|
||||||
|
};
|
||||||
|
m_gfx->writeDescriptorBuffer(renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer), &setZeroBuffer);
|
||||||
}
|
}
|
||||||
const float verticalFovRadians = glm::radians(m_camera.verticalFovDegrees);
|
|
||||||
const glm::mat4 projMatrix = glm::perspectiveZO(verticalFovRadians, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar);
|
|
||||||
|
|
||||||
/* update SET 0 */
|
RenderData::SetOneBuffer setOneBuffer{
|
||||||
RenderData::SetZeroBuffer uniform{
|
.view = viewMatrix
|
||||||
.view = viewMatrix,
|
|
||||||
.proj = projMatrix
|
|
||||||
};
|
};
|
||||||
m_gfx->writeDescriptorBuffer(renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer), &uniform);
|
//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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
instanceInfo.pNext = &debugMessengerInfo;
|
if (validationLayer) {
|
||||||
|
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();
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user