Archived
1
Fork 0

Fix vulkan image transitions

This commit is contained in:
redstrate 2021-02-03 09:04:30 -05:00
parent 9ccfcf90c2
commit 38250e1663
6 changed files with 120 additions and 57 deletions

View file

@ -75,6 +75,7 @@ private:
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
void transitionImageLayout(VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageLayout oldLayout, VkImageLayout newLayout); void transitionImageLayout(VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageLayout oldLayout, VkImageLayout newLayout);
void inlineTransitionImageLayout(VkCommandBuffer command_buffer, VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageLayout oldLayout, VkImageLayout newLayout);
VkShaderModule createShaderModule(const uint32_t* code, const int length); VkShaderModule createShaderModule(const uint32_t* code, const int length);
VkCommandBuffer beginSingleTimeCommands(); VkCommandBuffer beginSingleTimeCommands();
void endSingleTimeCommands(VkCommandBuffer commandBuffer); void endSingleTimeCommands(VkCommandBuffer commandBuffer);

View file

@ -266,26 +266,7 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) {
imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
} }
VkImageLayout imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; VkImageAspectFlagBits imageAspect;
if ((info.usage & GFXTextureUsage::Attachment) == GFXTextureUsage::Attachment) {
if (info.format == GFXPixelFormat::DEPTH_32F) {
if((info.usage & GFXTextureUsage::Sampled) == GFXTextureUsage::Sampled)
imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
else
imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
}
else {
if((info.usage & GFXTextureUsage::Sampled) == GFXTextureUsage::Sampled)
imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
else
imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
}
}
else {
imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
VkImageAspectFlags imageAspect;
if (info.format == GFXPixelFormat::DEPTH_32F) if (info.format == GFXPixelFormat::DEPTH_32F)
imageAspect = VK_IMAGE_ASPECT_DEPTH_BIT; imageAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
else else
@ -318,10 +299,11 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) {
vkCreateImage(device, &imageInfo, nullptr, &texture->handle); vkCreateImage(device, &imageInfo, nullptr, &texture->handle);
texture->layout = imageLayout;
texture->width = info.width; texture->width = info.width;
texture->height = info.height; texture->height = info.height;
texture->format = imageFormat; texture->format = imageFormat;
texture->aspect = imageAspect;
texture->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
// allocate memory // allocate memory
VkMemoryRequirements memRequirements; VkMemoryRequirements memRequirements;
@ -336,8 +318,6 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) {
vkBindImageMemory(device, texture->handle, texture->memory, 0); vkBindImageMemory(device, texture->handle, texture->memory, 0);
transitionImageLayout(texture->handle, imageFormat, imageAspect, VK_IMAGE_LAYOUT_UNDEFINED, imageLayout);
// create image view // create image view
VkImageViewCreateInfo viewInfo = {}; VkImageViewCreateInfo viewInfo = {};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
@ -426,12 +406,12 @@ void GFXVulkan::copy_texture(GFXTexture* texture, void* data, GFXSize size) {
vkUnmapMemory(device, stagingBufferMemory); vkUnmapMemory(device, stagingBufferMemory);
// copy staging buffer to image // copy staging buffer to image
transitionImageLayout(vulkanTexture->handle, vulkanTexture->format, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkCommandBuffer commandBuffer = beginSingleTimeCommands(); VkCommandBuffer commandBuffer = beginSingleTimeCommands();
inlineTransitionImageLayout(commandBuffer, vulkanTexture->handle, vulkanTexture->format, vulkanTexture->aspect, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkBufferImageCopy region = {}; VkBufferImageCopy region = {};
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.aspectMask = vulkanTexture->aspect;
region.imageSubresource.mipLevel = 0; region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0; region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1; region.imageSubresource.layerCount = 1;
@ -443,9 +423,9 @@ void GFXVulkan::copy_texture(GFXTexture* texture, void* data, GFXSize size) {
vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, vulkanTexture->handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region); vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, vulkanTexture->handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
endSingleTimeCommands(commandBuffer); inlineTransitionImageLayout(commandBuffer, vulkanTexture->handle, vulkanTexture->format, vulkanTexture->aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
transitionImageLayout(vulkanTexture->handle, vulkanTexture->format, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); endSingleTimeCommands(commandBuffer);
} }
void GFXVulkan::copy_texture(GFXTexture* from, GFXTexture* to) { void GFXVulkan::copy_texture(GFXTexture* from, GFXTexture* to) {
@ -453,7 +433,25 @@ void GFXVulkan::copy_texture(GFXTexture* from, GFXTexture* to) {
} }
void GFXVulkan::copy_texture(GFXTexture* from, GFXBuffer* to) { void GFXVulkan::copy_texture(GFXTexture* from, GFXBuffer* to) {
console::error(System::GFX, "Copy Texture->Buffer unimplemented!"); GFXVulkanTexture* vulkanTexture = (GFXVulkanTexture*)from;
GFXVulkanBuffer* vulkanBuffer = (GFXVulkanBuffer*)to;
VkCommandBuffer commandBuffer = beginSingleTimeCommands();
VkBufferImageCopy region = {};
region.imageSubresource.aspectMask = vulkanTexture->aspect;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageExtent = {
(uint32_t)vulkanTexture->width,
(uint32_t)vulkanTexture->height,
1
};
vkCmdCopyImageToBuffer(commandBuffer, vulkanTexture->handle, vulkanTexture->layout, vulkanBuffer->get(0).handle, 1, &region);
endSingleTimeCommands(commandBuffer);
} }
GFXSampler* GFXVulkan::create_sampler(const GFXSamplerCreateInfo& info) { GFXSampler* GFXVulkan::create_sampler(const GFXSamplerCreateInfo& info) {
@ -492,6 +490,12 @@ GFXFramebuffer* GFXVulkan::create_framebuffer(const GFXFramebufferCreateInfo& in
for (auto& attachment : info.attachments) { for (auto& attachment : info.attachments) {
GFXVulkanTexture* texture = (GFXVulkanTexture*)attachment; GFXVulkanTexture* texture = (GFXVulkanTexture*)attachment;
attachments.push_back(texture->view); attachments.push_back(texture->view);
VkImageLayout expectedLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
if (texture->aspect & VK_IMAGE_ASPECT_DEPTH_BIT)
expectedLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
transitionImageLayout(texture->handle, texture->format, texture->aspect, texture->layout, expectedLayout);
} }
VkFramebufferCreateInfo framebufferInfo = {}; VkFramebufferCreateInfo framebufferInfo = {};
@ -530,10 +534,6 @@ GFXRenderPass* GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info
if (info.attachments[i] == GFXPixelFormat::DEPTH_32F) if (info.attachments[i] == GFXPixelFormat::DEPTH_32F)
isDepthAttachment = true; isDepthAttachment = true;
VkImageLayout imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
if (isDepthAttachment)
imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentDescription attachment = {}; VkAttachmentDescription attachment = {};
attachment.format = toVkFormat(info.attachments[i]); attachment.format = toVkFormat(info.attachments[i]);
attachment.samples = VK_SAMPLE_COUNT_1_BIT; attachment.samples = VK_SAMPLE_COUNT_1_BIT;
@ -542,17 +542,19 @@ GFXRenderPass* GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachment.finalLayout = imageLayout;
if (imageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) if (isDepthAttachment)
attachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
if (imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
else
attachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VkAttachmentReference attachmentRef = {}; VkAttachmentReference attachmentRef = {};
attachmentRef.attachment = i; attachmentRef.attachment = i;
attachmentRef.layout = imageLayout;
if (isDepthAttachment)
attachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
else
attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
if (isDepthAttachment) { if (isDepthAttachment) {
hasDepthAttachment = true; hasDepthAttachment = true;
@ -1021,6 +1023,10 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
if (!currentPipeline->cachedDescriptorSets.count(getDescriptorHash(currentPipeline))) if (!currentPipeline->cachedDescriptorSets.count(getDescriptorHash(currentPipeline)))
cacheDescriptorState(currentPipeline, currentPipeline->descriptorLayout); cacheDescriptorState(currentPipeline, currentPipeline->descriptorLayout);
for (auto [texture, trans] : currentPipeline->expectedTransisitions) {
inlineTransitionImageLayout(commandBuffers[imageIndex], texture->handle, texture->format, texture->aspect, trans.oldLayout, trans.newLayout);
}
vkCmdBindDescriptorSets(commandBuffers[imageIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, currentPipeline->layout, 0, 1, &currentPipeline->cachedDescriptorSets[getDescriptorHash(currentPipeline)], 0, nullptr); vkCmdBindDescriptorSets(commandBuffers[imageIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, currentPipeline->layout, 0, 1, &currentPipeline->cachedDescriptorSets[getDescriptorHash(currentPipeline)], 0, nullptr);
lastDescriptorHash = getDescriptorHash(currentPipeline); lastDescriptorHash = getDescriptorHash(currentPipeline);
@ -1035,6 +1041,10 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
if (!currentPipeline->cachedDescriptorSets.count(getDescriptorHash(currentPipeline))) if (!currentPipeline->cachedDescriptorSets.count(getDescriptorHash(currentPipeline)))
cacheDescriptorState(currentPipeline, currentPipeline->descriptorLayout); cacheDescriptorState(currentPipeline, currentPipeline->descriptorLayout);
for (auto [texture, trans] : currentPipeline->expectedTransisitions) {
inlineTransitionImageLayout(commandBuffers[imageIndex], texture->handle, texture->format, texture->aspect, trans.oldLayout, trans.newLayout);
}
vkCmdBindDescriptorSets(commandBuffers[imageIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, currentPipeline->layout, 0, 1, &currentPipeline->cachedDescriptorSets[getDescriptorHash(currentPipeline)], 0, nullptr); vkCmdBindDescriptorSets(commandBuffers[imageIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, currentPipeline->layout, 0, 1, &currentPipeline->cachedDescriptorSets[getDescriptorHash(currentPipeline)], 0, nullptr);
lastDescriptorHash = getDescriptorHash(currentPipeline); lastDescriptorHash = getDescriptorHash(currentPipeline);
@ -1114,8 +1124,8 @@ void GFXVulkan::createInstance(std::vector<const char*> layers, std::vector<cons
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo = {}; VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo = {};
debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
debugCreateInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; debugCreateInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
debugCreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT ; debugCreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT ;
debugCreateInfo.pfnUserCallback = DebugCallback; // global function debugCreateInfo.pfnUserCallback = DebugCallback;
VkApplicationInfo appInfo = {}; VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
@ -1504,12 +1514,20 @@ void GFXVulkan::cacheDescriptorState(GFXVulkanPipeline* pipeline, VkDescriptorSe
imageInfo.imageLayout = vulkanTexture->layout; imageInfo.imageLayout = vulkanTexture->layout;
// color attachments are not the right layout // color attachments are not the right layout
//if (imageInfo.imageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) if (imageInfo.imageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
// imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
imageInfo.imageView = vulkanTexture->view; imageInfo.imageView = vulkanTexture->view;
imageInfo.sampler = vulkanTexture->sampler; imageInfo.sampler = vulkanTexture->sampler;
//if (imageInfo.imageLayout != vulkanTexture->layout) {
GFXVulkanPipeline::ExpectedTransisition trans;
trans.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
trans.newLayout = imageInfo.imageLayout;
pipeline->expectedTransisitions[vulkanTexture] = trans;
//}
VkWriteDescriptorSet descriptorWrite = {}; VkWriteDescriptorSet descriptorWrite = {};
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrite.dstSet = descriptorSet; descriptorWrite.dstSet = descriptorSet;
@ -1595,7 +1613,13 @@ uint32_t GFXVulkan::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags pr
void GFXVulkan::transitionImageLayout(VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageLayout oldLayout, VkImageLayout newLayout) { void GFXVulkan::transitionImageLayout(VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageLayout oldLayout, VkImageLayout newLayout) {
VkCommandBuffer commandBuffer = beginSingleTimeCommands(); VkCommandBuffer commandBuffer = beginSingleTimeCommands();
VkImageMemoryBarrier barrier = {}; inlineTransitionImageLayout(commandBuffer, image, format, aspect, oldLayout, newLayout);
endSingleTimeCommands(commandBuffer);
}
void GFXVulkan::inlineTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageLayout oldLayout, VkImageLayout newLayout) {
VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.oldLayout = oldLayout; barrier.oldLayout = oldLayout;
barrier.newLayout = newLayout; barrier.newLayout = newLayout;
@ -1607,19 +1631,40 @@ void GFXVulkan::transitionImageLayout(VkImage image, VkFormat format, VkImageAsp
barrier.subresourceRange.levelCount = 1; barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1; barrier.subresourceRange.layerCount = 1;
barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT; // TODO
barrier.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT; // TODO VkPipelineStageFlags sourceStage;
VkPipelineStageFlags destinationStage;
if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
}
else {
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
}
vkCmdPipelineBarrier( vkCmdPipelineBarrier(
commandBuffer, commandBuffer,
VK_PIPELINE_STAGE_HOST_BIT /* TODO */, VK_PIPELINE_STAGE_HOST_BIT /* TODO */, sourceStage, destinationStage,
0, 0,
0, nullptr, 0, nullptr,
0, nullptr, 0, nullptr,
1, &barrier 1, &barrier
); );
endSingleTimeCommands(commandBuffer);
} }
VkShaderModule GFXVulkan::createShaderModule(const uint32_t* code, const int length) { VkShaderModule GFXVulkan::createShaderModule(const uint32_t* code, const int length) {

View file

@ -4,6 +4,8 @@
#include "gfx_pipeline.hpp" #include "gfx_pipeline.hpp"
class GFXVulkanTexture;
class GFXVulkanPipeline : public GFXPipeline { class GFXVulkanPipeline : public GFXPipeline {
public: public:
std::string label; std::string label;
@ -18,4 +20,11 @@ public:
// dynamic descriptor sets // dynamic descriptor sets
std::map<uint64_t, VkDescriptorSet> cachedDescriptorSets; std::map<uint64_t, VkDescriptorSet> cachedDescriptorSets;
struct ExpectedTransisition {
VkImageLayout oldLayout;
VkImageLayout newLayout;
};
std::map<GFXVulkanTexture*, ExpectedTransisition> expectedTransisitions;
}; };

View file

@ -14,5 +14,6 @@ public:
int width, height; int width, height;
VkFormat format; VkFormat format;
VkImageLayout layout; VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
VkImageAspectFlagBits aspect;
}; };

View file

@ -81,6 +81,12 @@ struct UIPushConstant {
Matrix4x4 mvp; Matrix4x4 mvp;
}; };
struct SkyPushConstant {
Matrix4x4 view;
Vector4 sun_position_fov;
float aspect;
};
Renderer::Renderer(GFX* gfx, const bool enable_imgui) : gfx(gfx) { Renderer::Renderer(GFX* gfx, const bool enable_imgui) : gfx(gfx) {
Expects(gfx != nullptr); Expects(gfx != nullptr);
@ -534,12 +540,7 @@ void Renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj
render_screen(command_buffer, screen.screen, continuity, options); render_screen(command_buffer, screen.screen, continuity, options);
} }
struct SkyPushConstant { SkyPushConstant pc;
Matrix4x4 view;
Vector4 sun_position_fov;
float aspect;
} pc;
pc.view = matrix_from_quat(scene.get<Transform>(camera_object).rotation); pc.view = matrix_from_quat(scene.get<Transform>(camera_object).rotation);
pc.aspect = static_cast<float>(extent.width) / static_cast<float>(extent.height); pc.aspect = static_cast<float>(extent.width) / static_cast<float>(extent.height);
@ -956,7 +957,7 @@ void Renderer::createSkyPipeline() {
}; };
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {
{sizeof(Matrix4x4) + sizeof(Vector4) + sizeof(float), 0} {sizeof(SkyPushConstant), 0}
}; };
pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual; pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual;

View file

@ -1,5 +1,11 @@
layout (location = 0) out vec2 out_uv; layout (location = 0) out vec2 out_uv;
layout(push_constant, binding = 1) uniform PushConstant{
mat4 view;
vec4 sun_position_fov;
float aspect;
};
void main() { void main() {
out_uv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); out_uv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
gl_Position = vec4(out_uv * 2.0f + -1.0f, 1.0f, 1.0f); gl_Position = vec4(out_uv * 2.0f + -1.0f, 1.0f, 1.0f);