Archived
1
Fork 0

Support CopyTexture command on Vulkan

This commit is contained in:
redstrate 2021-02-15 17:59:54 -05:00
parent 0887fbda28
commit 6d77396b4d
7 changed files with 168 additions and 92 deletions

View file

@ -41,6 +41,7 @@ enum class GFXTextureUsage : int {
Sampled = 1, Sampled = 1,
Attachment = 2, Attachment = 2,
ShaderWrite = 3, ShaderWrite = 3,
Transfer = 4
}; };
inline GFXTextureUsage operator|(const GFXTextureUsage a, const GFXTextureUsage b) { inline GFXTextureUsage operator|(const GFXTextureUsage a, const GFXTextureUsage b) {

View file

@ -60,7 +60,8 @@ enum class GFXCommandType {
PushGroup, PushGroup,
PopGroup, PopGroup,
InsertLabel, InsertLabel,
Dispatch Dispatch,
EndRenderPass
}; };
struct GFXDrawCommand { struct GFXDrawCommand {
@ -362,5 +363,12 @@ public:
commands.push_back(command); commands.push_back(command);
} }
void end_render_pass() {
GFXDrawCommand command;
command.type = GFXCommandType::EndRenderPass;
commands.push_back(command);
}
std::vector<GFXDrawCommand> commands; std::vector<GFXDrawCommand> commands;
}; };

View file

@ -74,8 +74,8 @@ private:
uint64_t getDescriptorHash(GFXVulkanPipeline* pipeline); uint64_t getDescriptorHash(GFXVulkanPipeline* pipeline);
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, VkImageSubresourceRange range, VkImageLayout oldLayout, VkImageLayout newLayout);
void inlineTransitionImageLayout(VkCommandBuffer command_buffer, VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageLayout oldLayout, VkImageLayout newLayout); void inlineTransitionImageLayout(VkCommandBuffer command_buffer, VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageSubresourceRange range, 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

@ -342,6 +342,9 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) {
else { else {
imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
} }
if((info.usage & GFXTextureUsage::Transfer) == GFXTextureUsage::Transfer)
imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
VkImageAspectFlagBits imageAspect; VkImageAspectFlagBits imageAspect;
if (info.format == GFXPixelFormat::DEPTH_32F) if (info.format == GFXPixelFormat::DEPTH_32F)
@ -396,8 +399,19 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) {
vkAllocateMemory(device, &allocInfo, nullptr, &texture->memory); vkAllocateMemory(device, &allocInfo, nullptr, &texture->memory);
vkBindImageMemory(device, texture->handle, texture->memory, 0); vkBindImageMemory(device, texture->handle, texture->memory, 0);
VkImageSubresourceRange range = {};
range.baseMipLevel = 0;
range.levelCount = info.mip_count;
range.baseArrayLayer = 0;
range.layerCount = info.array_length;
if(info.type == GFXTextureType::Cubemap || info.type == GFXTextureType::CubemapArray)
range.layerCount *= 6;
texture->range = range;
transitionImageLayout(texture->handle, imageFormat, imageAspect, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); transitionImageLayout(texture->handle, imageFormat, imageAspect, range, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
// create image view // create image view
VkImageViewCreateInfo viewInfo = {}; VkImageViewCreateInfo viewInfo = {};
@ -419,11 +433,8 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) {
break; break;
} }
viewInfo.format = imageFormat; viewInfo.format = imageFormat;
viewInfo.subresourceRange = range;
viewInfo.subresourceRange.aspectMask = imageAspect; viewInfo.subresourceRange.aspectMask = imageAspect;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = info.mip_count;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = array_length;
vkCreateImageView(device, &viewInfo, nullptr, &texture->view); vkCreateImageView(device, &viewInfo, nullptr, &texture->view);
@ -487,8 +498,14 @@ void GFXVulkan::copy_texture(GFXTexture* texture, void* data, GFXSize size) {
// copy staging buffer to image // copy staging buffer to image
VkCommandBuffer commandBuffer = beginSingleTimeCommands(); VkCommandBuffer commandBuffer = beginSingleTimeCommands();
inlineTransitionImageLayout(commandBuffer, vulkanTexture->handle, vulkanTexture->format, vulkanTexture->aspect, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VkImageSubresourceRange range = {};
range.baseMipLevel = 0;
range.levelCount = 1;
range.baseArrayLayer = 0;
range.layerCount = 1;
inlineTransitionImageLayout(commandBuffer, vulkanTexture->handle, vulkanTexture->format, vulkanTexture->aspect, range, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkBufferImageCopy region = {}; VkBufferImageCopy region = {};
region.imageSubresource.aspectMask = vulkanTexture->aspect; region.imageSubresource.aspectMask = vulkanTexture->aspect;
@ -503,7 +520,7 @@ 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);
inlineTransitionImageLayout(commandBuffer, vulkanTexture->handle, vulkanTexture->format, vulkanTexture->aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); inlineTransitionImageLayout(commandBuffer, vulkanTexture->handle, vulkanTexture->format, vulkanTexture->aspect, range, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
endSingleTimeCommands(commandBuffer); endSingleTimeCommands(commandBuffer);
} }
@ -574,7 +591,13 @@ GFXFramebuffer* GFXVulkan::create_framebuffer(const GFXFramebufferCreateInfo& in
if (texture->aspect & VK_IMAGE_ASPECT_DEPTH_BIT) if (texture->aspect & VK_IMAGE_ASPECT_DEPTH_BIT)
expectedLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; expectedLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
transitionImageLayout(texture->handle, texture->format, texture->aspect, texture->layout, expectedLayout); VkImageSubresourceRange range = {};
range.baseMipLevel = 0;
range.levelCount = 1;
range.baseArrayLayer = 0;
range.layerCount = 1;
transitionImageLayout(texture->handle, texture->format, texture->aspect, range, texture->layout, expectedLayout);
} }
VkFramebufferCreateInfo framebufferInfo = {}; VkFramebufferCreateInfo framebufferInfo = {};
@ -1015,91 +1038,91 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
for (auto command : command_buffer->commands) { for (auto command : command_buffer->commands) {
switch (command.type) { switch (command.type) {
case GFXCommandType::SetRenderPass: case GFXCommandType::SetRenderPass:
{ {
// end the previous render pass // end the previous render pass
if (currentRenderPass != VK_NULL_HANDLE) { if (currentRenderPass != VK_NULL_HANDLE) {
vkCmdEndRenderPass(cmd); vkCmdEndRenderPass(cmd);
} }
GFXVulkanRenderPass* renderPass = (GFXVulkanRenderPass*)command.data.set_render_pass.render_pass; GFXVulkanRenderPass* renderPass = (GFXVulkanRenderPass*)command.data.set_render_pass.render_pass;
GFXVulkanFramebuffer* framebuffer = (GFXVulkanFramebuffer*)command.data.set_render_pass.framebuffer; GFXVulkanFramebuffer* framebuffer = (GFXVulkanFramebuffer*)command.data.set_render_pass.framebuffer;
if (renderPass != nullptr) { if (renderPass != nullptr) {
currentRenderPass = renderPass->handle; currentRenderPass = renderPass->handle;
} }
else { else {
currentRenderPass = swapchainRenderPass; currentRenderPass = swapchainRenderPass;
} }
VkRenderPassBeginInfo renderPassInfo = {}; VkRenderPassBeginInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = currentRenderPass; renderPassInfo.renderPass = currentRenderPass;
if (framebuffer != nullptr) { if (framebuffer != nullptr) {
renderPassInfo.framebuffer = framebuffer->handle; renderPassInfo.framebuffer = framebuffer->handle;
VkViewport viewport = {}; VkViewport viewport = {};
viewport.y = static_cast<float>(framebuffer->height); viewport.y = static_cast<float>(framebuffer->height);
viewport.width = static_cast<float>(framebuffer->width); viewport.width = static_cast<float>(framebuffer->width);
viewport.height = -static_cast<float>(framebuffer->height); viewport.height = -static_cast<float>(framebuffer->height);
viewport.maxDepth = 1.0f; viewport.maxDepth = 1.0f;
vkCmdSetViewport(cmd, 0, 1, &viewport); vkCmdSetViewport(cmd, 0, 1, &viewport);
VkRect2D scissor = {}; VkRect2D scissor = {};
scissor.extent.width = framebuffer->width; scissor.extent.width = framebuffer->width;
scissor.extent.height = framebuffer->height; scissor.extent.height = framebuffer->height;
vkCmdSetScissor(cmd, 0, 1, &scissor); vkCmdSetScissor(cmd, 0, 1, &scissor);
} }
else { else {
renderPassInfo.framebuffer = swapchainFramebuffers[imageIndex]; renderPassInfo.framebuffer = swapchainFramebuffers[imageIndex];
VkViewport viewport = {}; VkViewport viewport = {};
viewport.y = static_cast<float>(surfaceHeight); viewport.y = static_cast<float>(surfaceHeight);
viewport.width = static_cast<float>(surfaceWidth); viewport.width = static_cast<float>(surfaceWidth);
viewport.height = -static_cast<float>(surfaceHeight); viewport.height = -static_cast<float>(surfaceHeight);
viewport.maxDepth = 1.0f; viewport.maxDepth = 1.0f;
vkCmdSetViewport(cmd, 0, 1, &viewport); vkCmdSetViewport(cmd, 0, 1, &viewport);
VkRect2D scissor = {}; VkRect2D scissor = {};
scissor.extent.width = surfaceWidth; scissor.extent.width = surfaceWidth;
scissor.extent.height = surfaceHeight; scissor.extent.height = surfaceHeight;
vkCmdSetScissor(cmd, 0, 1, &scissor); vkCmdSetScissor(cmd, 0, 1, &scissor);
} }
renderPassInfo.renderArea.offset = { command.data.set_render_pass.render_area.offset.x, command.data.set_render_pass.render_area.offset.y }; renderPassInfo.renderArea.offset = { command.data.set_render_pass.render_area.offset.x, command.data.set_render_pass.render_area.offset.y };
renderPassInfo.renderArea.extent = { command.data.set_render_pass.render_area.extent.width, command.data.set_render_pass.render_area.extent.height }; renderPassInfo.renderArea.extent = { command.data.set_render_pass.render_area.extent.width, command.data.set_render_pass.render_area.extent.height };
std::vector<VkClearValue> clearColors; std::vector<VkClearValue> clearColors;
if (renderPass != nullptr) { if (renderPass != nullptr) {
clearColors.resize(renderPass->numAttachments); clearColors.resize(renderPass->numAttachments);
} }
else { else {
clearColors.resize(1); clearColors.resize(1);
} }
clearColors[0].color.float32[0] = command.data.set_render_pass.clear_color.r; clearColors[0].color.float32[0] = command.data.set_render_pass.clear_color.r;
clearColors[0].color.float32[1] = command.data.set_render_pass.clear_color.g; clearColors[0].color.float32[1] = command.data.set_render_pass.clear_color.g;
clearColors[0].color.float32[2] = command.data.set_render_pass.clear_color.b; clearColors[0].color.float32[2] = command.data.set_render_pass.clear_color.b;
clearColors[0].color.float32[3] = command.data.set_render_pass.clear_color.a; clearColors[0].color.float32[3] = command.data.set_render_pass.clear_color.a;
if(renderPass != nullptr) { if(renderPass != nullptr) {
if(renderPass->depth_attachment != -1) if(renderPass->depth_attachment != -1)
clearColors[renderPass->depth_attachment].depthStencil.depth = 1.0f; clearColors[renderPass->depth_attachment].depthStencil.depth = 1.0f;
} }
renderPassInfo.clearValueCount = static_cast<uint32_t>(clearColors.size()); renderPassInfo.clearValueCount = static_cast<uint32_t>(clearColors.size());
renderPassInfo.pClearValues = clearColors.data(); renderPassInfo.pClearValues = clearColors.data();
vkCmdBeginRenderPass(cmd, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(cmd, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
currentPipeline = nullptr; currentPipeline = nullptr;
} }
break; break;
case GFXCommandType::SetGraphicsPipeline: case GFXCommandType::SetGraphicsPipeline:
{ {
currentPipeline = (GFXVulkanPipeline*)command.data.set_graphics_pipeline.pipeline; currentPipeline = (GFXVulkanPipeline*)command.data.set_graphics_pipeline.pipeline;
@ -1170,7 +1193,40 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
vkCmdSetDepthBias(cmd, command.data.set_depth_bias.constant, command.data.set_depth_bias.clamp, command.data.set_depth_bias.slope_factor); vkCmdSetDepthBias(cmd, command.data.set_depth_bias.constant, command.data.set_depth_bias.clamp, command.data.set_depth_bias.slope_factor);
} }
break; break;
case GFXCommandType::CopyTexture:
{
GFXVulkanTexture* src = (GFXVulkanTexture*)command.data.copy_texture.src;
GFXVulkanTexture* dst = (GFXVulkanTexture*)command.data.copy_texture.dst;
inlineTransitionImageLayout(cmd, src->handle, src->format, src->aspect, src->range, src->layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
inlineTransitionImageLayout(cmd, dst->handle, dst->format, dst->aspect, dst->range, dst->layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
const int slice_offset = command.data.copy_texture.to_slice + command.data.copy_texture.to_layer * 6;
VkImageCopy region = {};
region.extent = {static_cast<uint32_t>(command.data.copy_texture.width), static_cast<uint32_t>(command.data.copy_texture.height), 1};
region.dstSubresource.baseArrayLayer = slice_offset;
region.dstSubresource.mipLevel = command.data.copy_texture.to_level;
region.srcSubresource.aspectMask = src->aspect;
region.dstSubresource.aspectMask = dst->aspect;
region.srcSubresource.layerCount = 1;
region.dstSubresource.layerCount = 1;
vkCmdCopyImage(cmd, src->handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst->handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
inlineTransitionImageLayout(cmd, src->handle, src->format, src->aspect, src->range, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, src->layout);
inlineTransitionImageLayout(cmd, dst->handle, dst->format, dst->aspect, dst->range, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst->layout);
}
break;
case GFXCommandType::EndRenderPass:
{
if(currentRenderPass != nullptr) {
vkCmdEndRenderPass(cmd);
currentRenderPass = nullptr;
}
} }
break;
}
} }
// end the last render pass // end the last render pass
@ -1744,15 +1800,15 @@ uint32_t GFXVulkan::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags pr
return -1; return -1;
} }
void GFXVulkan::transitionImageLayout(VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageLayout oldLayout, VkImageLayout newLayout) { void GFXVulkan::transitionImageLayout(VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageSubresourceRange range, VkImageLayout oldLayout, VkImageLayout newLayout) {
VkCommandBuffer commandBuffer = beginSingleTimeCommands(); VkCommandBuffer commandBuffer = beginSingleTimeCommands();
inlineTransitionImageLayout(commandBuffer, image, format, aspect, oldLayout, newLayout); inlineTransitionImageLayout(commandBuffer, image, format, aspect, range, oldLayout, newLayout);
endSingleTimeCommands(commandBuffer); endSingleTimeCommands(commandBuffer);
} }
void GFXVulkan::inlineTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageLayout oldLayout, VkImageLayout newLayout) { void GFXVulkan::inlineTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageSubresourceRange range, VkImageLayout oldLayout, VkImageLayout newLayout) {
VkImageMemoryBarrier barrier{}; VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.oldLayout = oldLayout; barrier.oldLayout = oldLayout;
@ -1760,11 +1816,8 @@ void GFXVulkan::inlineTransitionImageLayout(VkCommandBuffer commandBuffer, VkIma
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = image; barrier.image = image;
barrier.subresourceRange = range;
barrier.subresourceRange.aspectMask = aspect; barrier.subresourceRange.aspectMask = aspect;
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
VkPipelineStageFlags sourceStage; VkPipelineStageFlags sourceStage;
VkPipelineStageFlags destinationStage; VkPipelineStageFlags destinationStage;

View file

@ -16,4 +16,5 @@ public:
VkFormat format; VkFormat format;
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED; VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
VkImageAspectFlagBits aspect; VkImageAspectFlagBits aspect;
VkImageSubresourceRange range;
}; };

View file

@ -42,6 +42,18 @@ struct SceneInformation {
int p[3]; int p[3];
}; };
struct SkyPushConstant {
Matrix4x4 view;
Vector4 sun_position_fov;
float aspect;
};
struct FilterPushConstant {
Matrix4x4 mvp;
float roughness;
float buffer[15];
};
const int mipLevels = 5; const int mipLevels = 5;
const std::array<Matrix4x4, 6> sceneTransforms = { const std::array<Matrix4x4, 6> sceneTransforms = {
@ -71,7 +83,7 @@ SceneCapture::SceneCapture(GFX* gfx) {
textureInfo.width = scene_cubemap_resolution; textureInfo.width = scene_cubemap_resolution;
textureInfo.height = scene_cubemap_resolution; textureInfo.height = scene_cubemap_resolution;
textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM;
textureInfo.usage = GFXTextureUsage::Attachment; textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Transfer;
textureInfo.samplingMode = SamplingMode::ClampToEdge; textureInfo.samplingMode = SamplingMode::ClampToEdge;
offscreenTexture = gfx->create_texture(textureInfo); offscreenTexture = gfx->create_texture(textureInfo);
@ -297,6 +309,7 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
command_buffer->draw(0, 4, 0, 1); command_buffer->draw(0, 4, 0, 1);
command_buffer->end_render_pass();
command_buffer->copy_texture(offscreenTexture, scene_cubemap_resolution, scene_cubemap_resolution, environmentCube, face, 0, 0); command_buffer->copy_texture(offscreenTexture, scene_cubemap_resolution, scene_cubemap_resolution, environmentCube, face, 0, 0);
}; };
@ -332,7 +345,8 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
command_buffer->set_push_constant(&mvp, sizeof(Matrix4x4)); command_buffer->set_push_constant(&mvp, sizeof(Matrix4x4));
command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0); command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0);
command_buffer->end_render_pass();
command_buffer->copy_texture(irradianceOffscreenTexture, irradiance_cubemap_resolution, irradiance_cubemap_resolution, scene->irradianceCubeArray, face, last_probe, 0); command_buffer->copy_texture(irradianceOffscreenTexture, irradiance_cubemap_resolution, irradiance_cubemap_resolution, scene->irradianceCubeArray, face, last_probe, 0);
}; };
@ -359,11 +373,7 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
command_buffer->set_vertex_buffer(cubeMesh->position_buffer, 0, 0); command_buffer->set_vertex_buffer(cubeMesh->position_buffer, 0, 0);
command_buffer->set_index_buffer(cubeMesh->index_buffer, IndexType::UINT32); command_buffer->set_index_buffer(cubeMesh->index_buffer, IndexType::UINT32);
struct PushConstant { FilterPushConstant pc;
Matrix4x4 mvp;
float roughness;
} pc;
pc.mvp = projection * sceneTransforms[face]; pc.mvp = projection * sceneTransforms[face];
pc.roughness = ((float)mip) / (float)(mipLevels - 1); pc.roughness = ((float)mip) / (float)(mipLevels - 1);
@ -373,6 +383,7 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0); command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0);
command_buffer->end_render_pass();
command_buffer->copy_texture(prefilteredOffscreenTexture, info.render_area.extent.width, info.render_area.extent.height, scene->prefilteredCubeArray, face, last_probe, mip); command_buffer->copy_texture(prefilteredOffscreenTexture, info.render_area.extent.width, info.render_area.extent.height, scene->prefilteredCubeArray, face, last_probe, mip);
}; };
@ -401,7 +412,7 @@ void SceneCapture::createSkyResources() {
}; };
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;
@ -417,7 +428,7 @@ void SceneCapture::createIrradianceResources() {
textureInfo.width = irradiance_cubemap_resolution; textureInfo.width = irradiance_cubemap_resolution;
textureInfo.height = irradiance_cubemap_resolution; textureInfo.height = irradiance_cubemap_resolution;
textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM;
textureInfo.usage = GFXTextureUsage::Attachment; textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Transfer;
textureInfo.samplingMode = SamplingMode::ClampToEdge; textureInfo.samplingMode = SamplingMode::ClampToEdge;
irradianceOffscreenTexture = gfx->create_texture(textureInfo); irradianceOffscreenTexture = gfx->create_texture(textureInfo);
@ -471,7 +482,7 @@ void SceneCapture::createPrefilterResources() {
textureInfo.width = scene_cubemap_resolution; textureInfo.width = scene_cubemap_resolution;
textureInfo.height = scene_cubemap_resolution; textureInfo.height = scene_cubemap_resolution;
textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM;
textureInfo.usage = GFXTextureUsage::Attachment; textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Transfer;
textureInfo.samplingMode = SamplingMode::ClampToEdge; textureInfo.samplingMode = SamplingMode::ClampToEdge;
prefilteredOffscreenTexture = gfx->create_texture(textureInfo); prefilteredOffscreenTexture = gfx->create_texture(textureInfo);
@ -504,7 +515,7 @@ void SceneCapture::createPrefilterResources() {
pipelineInfo.vertex_input.attributes.push_back(positionAttribute); pipelineInfo.vertex_input.attributes.push_back(positionAttribute);
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {
{sizeof(Matrix4x4) + sizeof(float), 0} {sizeof(FilterPushConstant), 0}
}; };
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {

View file

@ -245,6 +245,7 @@ void ShadowPass::render_spot(GFXCommandBuffer* command_buffer, Scene& scene, Obj
if(light.enable_shadows) if(light.enable_shadows)
render_meshes(command_buffer, scene, realMVP, Matrix4x4(), scene.get<Transform>(light_object).get_world_position(), Light::Type::Spot, frustum, 0); render_meshes(command_buffer, scene, realMVP, Matrix4x4(), scene.get<Transform>(light_object).get_world_position(), Light::Type::Spot, frustum, 0);
command_buffer->end_render_pass();
command_buffer->copy_texture(offscreen_depth, render_options.shadow_resolution, render_options.shadow_resolution, scene.spotLightArray, 0, last_spot_light, 0); command_buffer->copy_texture(offscreen_depth, render_options.shadow_resolution, render_options.shadow_resolution, scene.spotLightArray, 0, last_spot_light, 0);
scene.spot_light_dirty[last_spot_light] = false; scene.spot_light_dirty[last_spot_light] = false;
@ -286,6 +287,7 @@ void ShadowPass::render_point(GFXCommandBuffer* command_buffer, Scene& scene, Ob
render_meshes(command_buffer, scene, projection * shadowTransforms[face], model, lightPos, Light::Type::Point, frustum, last_point_light); render_meshes(command_buffer, scene, projection * shadowTransforms[face], model, lightPos, Light::Type::Point, frustum, last_point_light);
command_buffer->end_render_pass();
command_buffer->copy_texture(offscreen_color_texture, render_options.shadow_resolution, render_options.shadow_resolution, scene.pointLightArray, face, last_point_light, 0); command_buffer->copy_texture(offscreen_color_texture, render_options.shadow_resolution, render_options.shadow_resolution, scene.pointLightArray, face, last_point_light, 0);
} }