From ee2771f45f7a6637e97bd476e7a1212ee260a4d5 Mon Sep 17 00:00:00 2001 From: redstrate <54911369+redstrate@users.noreply.github.com> Date: Tue, 11 May 2021 19:16:54 -0400 Subject: [PATCH] Add compute pipeline support for Vulkan * Image transition layouts are not handled correctly yet, so auto exposure does not work * Image usage and guessed image layout is redone to remove some errors --- engine/gfx/public/gfx.hpp | 19 +- engine/gfx/vulkan/include/gfx_vulkan.hpp | 1 + engine/gfx/vulkan/src/gfx_vulkan.cpp | 224 +++++++++++++++--- engine/gfx/vulkan/src/gfx_vulkan_pipeline.hpp | 7 - engine/renderer/src/imguipass.cpp | 2 +- engine/renderer/src/renderer.cpp | 48 ++-- engine/renderer/src/scenecapture.cpp | 6 +- engine/renderer/src/shadowpass.cpp | 6 +- engine/renderer/src/smaapass.cpp | 4 +- 9 files changed, 244 insertions(+), 73 deletions(-) diff --git a/engine/gfx/public/gfx.hpp b/engine/gfx/public/gfx.hpp index 5060dcc..563849c 100755 --- a/engine/gfx/public/gfx.hpp +++ b/engine/gfx/public/gfx.hpp @@ -38,10 +38,12 @@ enum class GFXVertexFormat : int { }; enum class GFXTextureUsage : int { - Sampled = 1, - Attachment = 2, - ShaderWrite = 3, - Transfer = 4 + Sampled = 0, + Attachment = 1, + ShaderWrite = 2, + TransferSrc = 4, + TransferDst = 8, + Storage = 16 }; inline GFXTextureUsage operator|(const GFXTextureUsage a, const GFXTextureUsage b) { @@ -200,12 +202,9 @@ struct GFXGraphicsPipelineCreateInfo { struct GFXComputePipelineCreateInfo { std::string label; // only used for debug - - struct Shaders { - std::string_view compute_path; - ShaderSource compute_src; - } shaders; - + + ShaderSource compute_src; + struct ShaderBindings { std::vector push_constants; diff --git a/engine/gfx/vulkan/include/gfx_vulkan.hpp b/engine/gfx/vulkan/include/gfx_vulkan.hpp index dd906d8..23d1f13 100755 --- a/engine/gfx/vulkan/include/gfx_vulkan.hpp +++ b/engine/gfx/vulkan/include/gfx_vulkan.hpp @@ -78,6 +78,7 @@ public: // pipeline operations GFXPipeline* create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) override; + GFXPipeline* create_compute_pipeline(const GFXComputePipelineCreateInfo& info) override; // misc operations GFXSize get_alignment(const GFXSize size) override; diff --git a/engine/gfx/vulkan/src/gfx_vulkan.cpp b/engine/gfx/vulkan/src/gfx_vulkan.cpp index 9e5c1e5..1e35674 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan.cpp +++ b/engine/gfx/vulkan/src/gfx_vulkan.cpp @@ -341,21 +341,31 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) { VkImageTiling imageTiling; imageTiling = VK_IMAGE_TILING_OPTIMAL; + const auto check_flag = [](const GFXTextureUsage usage, const GFXTextureUsage flag) { + return (usage & flag) == flag; + }; + VkImageUsageFlags imageUsage = 0; - if ((info.usage & GFXTextureUsage::Attachment) == GFXTextureUsage::Attachment) { + if(check_flag(info.usage, GFXTextureUsage::Attachment)) { if (info.format == GFXPixelFormat::DEPTH_32F) { - imageUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - } - else { - imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - } - } - else { - 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; + imageUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + } + else { + imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + } + } + + if(check_flag(info.usage, GFXTextureUsage::Sampled)) + imageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT; + + if(check_flag(info.usage, GFXTextureUsage::TransferSrc)) + imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + + if(check_flag(info.usage, GFXTextureUsage::TransferDst)) + imageUsage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + + if(check_flag(info.usage, GFXTextureUsage::Storage)) + imageUsage |= VK_IMAGE_USAGE_STORAGE_BIT; VkImageAspectFlagBits imageAspect; if (info.format == GFXPixelFormat::DEPTH_32F) @@ -396,7 +406,20 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) { texture->height = info.height; texture->format = imageFormat; texture->aspect = imageAspect; - texture->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + if(check_flag(info.usage, GFXTextureUsage::Attachment) && !check_flag(info.usage, GFXTextureUsage::Sampled)) { + if (info.format == GFXPixelFormat::DEPTH_32F) { + texture->layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + } else { + texture->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + } + } else if(check_flag(info.usage, GFXTextureUsage::Storage) && check_flag(info.usage, GFXTextureUsage::ShaderWrite)) { + texture->layout = VK_IMAGE_LAYOUT_GENERAL; + } else if(check_flag(info.usage, GFXTextureUsage::Sampled)) { + texture->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + } else { + texture->layout = VK_IMAGE_LAYOUT_UNDEFINED; + } // allocate memory VkMemoryRequirements memRequirements; @@ -420,7 +443,7 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) { texture->range = range; - transitionImageLayout(texture->handle, imageFormat, imageAspect, range, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + transitionImageLayout(texture->handle, imageFormat, imageAspect, range, VK_IMAGE_LAYOUT_UNDEFINED, texture->layout); // create image view VkImageViewCreateInfo viewInfo = {}; @@ -997,6 +1020,121 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate return pipeline; } +GFXPipeline* GFXVulkan::create_compute_pipeline(const GFXComputePipelineCreateInfo& info) { + GFXVulkanPipeline* pipeline = new GFXVulkanPipeline(); + + vkDeviceWaitIdle(device); + + VkShaderModule compute_module = VK_NULL_HANDLE; + + const bool use_shader_source = !info.compute_src.is_path(); + + if (use_shader_source) { + auto shader_vector = info.compute_src.as_bytecode(); + + compute_module = createShaderModule(shader_vector.data(), shader_vector.size() * sizeof(uint32_t)); + } + else { + auto shader = file::open(file::internal_domain / (info.compute_src.as_path().string()), true); + shader->read_all(); + + compute_module = createShaderModule(shader->cast_data(), shader->size()); + } + + if(!use_shader_source) + name_object(device, VK_OBJECT_TYPE_SHADER_MODULE, (uint64_t)compute_module, info.compute_src.as_path().string()); + + VkPipelineShaderStageCreateInfo shaderStageInfo = {}; + shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; + shaderStageInfo.module = compute_module; + shaderStageInfo.pName = "main"; + + // create push constants + std::vector pushConstants; + for (auto& pushConstant : info.shader_input.push_constants) { + VkPushConstantRange range; + range.offset = pushConstant.offset; + range.size = pushConstant.size; + range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + + pushConstants.push_back(range); + } + + // create descriptor layout + std::vector layoutBindings; + for (auto& binding : info.shader_input.bindings) { + // ignore push constants + if (binding.type == GFXBindingType::PushConstant) + continue; + + VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + switch (binding.type) { + case GFXBindingType::StorageBuffer: + descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + break; + case GFXBindingType::Texture: + descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + break; + case GFXBindingType::StorageImage: + { + descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + pipeline->bindings_marked_as_storage_images.push_back(binding.binding); + } + break; + case GFXBindingType::SampledImage: + { + descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + pipeline->bindings_marked_as_sampled_images.push_back(binding.binding); + } + break; + case GFXBindingType::Sampler: + descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + break; + } + + VkDescriptorSetLayoutBinding layoutBinding = {}; + layoutBinding.binding = binding.binding; + layoutBinding.descriptorType = descriptorType; + layoutBinding.descriptorCount = 1; + layoutBinding.stageFlags = VK_SHADER_STAGE_ALL; + + layoutBindings.push_back(layoutBinding); + } + + VkDescriptorSetLayoutCreateInfo layoutCreateInfo = {}; + layoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layoutCreateInfo.bindingCount = static_cast(layoutBindings.size()); + layoutCreateInfo.pBindings = layoutBindings.data(); + + vkCreateDescriptorSetLayout(device, &layoutCreateInfo, nullptr, &pipeline->descriptorLayout); + + // create layout + VkPipelineLayoutCreateInfo pipelineLayoutInfo = {}; + pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutInfo.pushConstantRangeCount = static_cast(pushConstants.size()); + pipelineLayoutInfo.pPushConstantRanges = pushConstants.data(); + pipelineLayoutInfo.pSetLayouts = &pipeline->descriptorLayout; + pipelineLayoutInfo.setLayoutCount = 1; + + vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipeline->layout); + + // create pipeline + VkComputePipelineCreateInfo pipelineInfo = {}; + pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + pipelineInfo.stage = shaderStageInfo; + pipelineInfo.layout = pipeline->layout; + + vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline->handle); + + pipeline->label = info.label; + + name_object(device, VK_OBJECT_TYPE_PIPELINE, (uint64_t)pipeline->handle, pipeline->label); + name_object(device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)pipeline->layout, pipeline->label); + + return pipeline; +} + GFXSize GFXVulkan::get_alignment(GFXSize size) { VkPhysicalDeviceProperties properties; vkGetPhysicalDeviceProperties(physicalDevice, &properties); @@ -1057,8 +1195,9 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) { VkRenderPass currentRenderPass = VK_NULL_HANDLE; GFXVulkanPipeline* currentPipeline = nullptr; uint64_t lastDescriptorHash = 0; + bool is_compute = false; - const auto try_bind_descriptor = [cmd, this, ¤tPipeline, &lastDescriptorHash]() -> bool { + const auto try_bind_descriptor = [cmd, this, ¤tPipeline, &lastDescriptorHash, &is_compute]() -> bool { if(currentPipeline == nullptr) return false; @@ -1070,7 +1209,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) { if (descriptor_set == VK_NULL_HANDLE) return false; - vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, currentPipeline->layout, 0, 1, &descriptor_set, 0, nullptr); + vkCmdBindDescriptorSets(cmd, is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS, currentPipeline->layout, 0, 1, &descriptor_set, 0, nullptr); lastDescriptorHash = getDescriptorHash(currentPipeline); } @@ -1174,8 +1313,23 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) { resetDescriptorState(); lastDescriptorHash = 0; } + + is_compute = false; } break; + case GFXCommandType::SetComputePipeline: + { + currentPipeline = (GFXVulkanPipeline*)command.data.set_compute_pipeline.pipeline; + if(currentPipeline != nullptr) { + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, currentPipeline->handle); + + resetDescriptorState(); + lastDescriptorHash = 0; + } + + is_compute = true; + } + break; case GFXCommandType::SetVertexBuffer: { VkBuffer buffer = ((GFXVulkanBuffer*)command.data.set_vertex_buffer.buffer)->handle; @@ -1194,8 +1348,12 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) { break; case GFXCommandType::SetPushConstant: { + VkShaderStageFlags applicableStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; + if(is_compute) + applicableStages = VK_SHADER_STAGE_COMPUTE_BIT; + if(currentPipeline != nullptr) - vkCmdPushConstants(cmd, currentPipeline->layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, command.data.set_push_constant.size, command.data.set_push_constant.bytes.data()); + vkCmdPushConstants(cmd, currentPipeline->layout, applicableStages , 0, command.data.set_push_constant.size, command.data.set_push_constant.bytes.data()); } break; case GFXCommandType::BindShaderBuffer: @@ -1297,6 +1455,12 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) { } } break; + case GFXCommandType::Dispatch: + { + if(try_bind_descriptor()) + vkCmdDispatch(cmd, command.data.dispatch.group_count_x, command.data.dispatch.group_count_y, command.data.dispatch.group_count_z); + } + break; } } @@ -1783,33 +1947,26 @@ void GFXVulkan::cacheDescriptorState(GFXVulkanPipeline* pipeline, VkDescriptorSe VkDescriptorImageInfo imageInfo = {}; imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - imageInfo.imageView = vulkanTexture->view; 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 = {}; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptorWrite.dstSet = descriptorSet; descriptorWrite.dstBinding = i; descriptorWrite.descriptorCount = 1; - descriptorWrite.pImageInfo = &imageInfo; if (utility::contains(pipeline->bindings_marked_as_storage_images, i)) { descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - } else if (utility::contains(pipeline->bindings_marked_as_sampled_images, i)) { + imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + } else if (utility::contains(pipeline->bindings_marked_as_sampled_images, i)) { descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; } else { descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; } + descriptorWrite.pImageInfo = &imageInfo; + vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr); i++; @@ -1905,6 +2062,12 @@ void GFXVulkan::inlineTransitionImageLayout(VkCommandBuffer commandBuffer, VkIma case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; break; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + break; + case VK_IMAGE_LAYOUT_GENERAL: + barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + break; default: break; } @@ -1916,6 +2079,9 @@ void GFXVulkan::inlineTransitionImageLayout(VkCommandBuffer commandBuffer, VkIma case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; break; + case VK_IMAGE_LAYOUT_GENERAL: + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + break; default: break; } diff --git a/engine/gfx/vulkan/src/gfx_vulkan_pipeline.hpp b/engine/gfx/vulkan/src/gfx_vulkan_pipeline.hpp index 209d052..f2d3487 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan_pipeline.hpp +++ b/engine/gfx/vulkan/src/gfx_vulkan_pipeline.hpp @@ -20,11 +20,4 @@ public: // dynamic descriptor sets std::map cachedDescriptorSets; - - struct ExpectedTransisition { - VkImageLayout oldLayout; - VkImageLayout newLayout; - }; - - std::map expectedTransisitions; }; diff --git a/engine/renderer/src/imguipass.cpp b/engine/renderer/src/imguipass.cpp index a7b3d9d..0c9d589 100755 --- a/engine/renderer/src/imguipass.cpp +++ b/engine/renderer/src/imguipass.cpp @@ -180,7 +180,7 @@ void ImGuiPass::create_font_texture() { createInfo.width = width; createInfo.height = height; createInfo.format = GFXPixelFormat::RGBA8_UNORM; - createInfo.usage = GFXTextureUsage::Sampled; + createInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst; font_texture = engine->get_gfx()->create_texture(createInfo); engine->get_gfx()->copy_texture(font_texture, pixels, width * height * 4); diff --git a/engine/renderer/src/renderer.cpp b/engine/renderer/src/renderer.cpp index e6f8e2a..865d60e 100755 --- a/engine/renderer/src/renderer.cpp +++ b/engine/renderer/src/renderer.cpp @@ -313,19 +313,12 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge if(render_options.enable_depth_of_field && dof_pass != nullptr) dof_pass->render(commandbuffer, *scene); - - beginInfo.framebuffer = nullptr; - beginInfo.render_pass = nullptr; - - commandbuffer->set_render_pass(beginInfo); - - Viewport viewport = {}; - viewport.width = static_cast(render_extent.width); - viewport.height = static_cast(render_extent.height); - - commandbuffer->set_viewport(viewport); - + commandbuffer->push_group("Post Processing"); + + commandbuffer->end_render_pass(); + + // begin auto exposure commandbuffer->set_compute_pipeline(histogram_pipeline); @@ -357,6 +350,18 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge commandbuffer->dispatch(1, 1, 1); + // continue post processing + beginInfo.framebuffer = nullptr; + beginInfo.render_pass = nullptr; + + commandbuffer->set_render_pass(beginInfo); + + Viewport viewport = {}; + viewport.width = static_cast(render_extent.width); + viewport.height = static_cast(render_extent.height); + + commandbuffer->set_viewport(viewport); + commandbuffer->set_graphics_pipeline(post_pipeline); if(render_options.enable_depth_of_field) @@ -770,7 +775,7 @@ void renderer::create_dummy_texture() { createInfo.width = 1; createInfo.height = 1; createInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; - createInfo.usage = GFXTextureUsage::Sampled; + createInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst; dummy_texture = gfx->create_texture(createInfo); @@ -787,13 +792,14 @@ void renderer::create_render_target_resources(RenderTarget& target) { textureInfo.width = extent.width; textureInfo.height = extent.height; textureInfo.format = GFXPixelFormat::RGBA_32F; - textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; + textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled | GFXTextureUsage::Storage; textureInfo.samplingMode = SamplingMode::ClampToEdge; target.offscreenColorTexture = gfx->create_texture(textureInfo); textureInfo.label = "Offscreen Depth"; textureInfo.format = GFXPixelFormat::DEPTH_32F; + textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; target.offscreenDepthTexture = gfx->create_texture(textureInfo); @@ -874,7 +880,7 @@ void renderer::create_font_texture() { textureInfo.width = font.width; textureInfo.height = font.height; textureInfo.format = GFXPixelFormat::R8_UNORM; - textureInfo.usage = GFXTextureUsage::Sampled; + textureInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst; font_texture = gfx->create_texture(textureInfo); @@ -1000,17 +1006,23 @@ void renderer::generate_brdf() { void renderer::create_histogram_resources() { GFXComputePipelineCreateInfo create_info = {}; - create_info.shaders.compute_path = "histogram.comp"; + create_info.compute_src = ShaderSource(file::Path("histogram.comp")); create_info.workgroup_size_x = 16; create_info.workgroup_size_y = 16; create_info.shader_input.bindings = { + {0, GFXBindingType::StorageImage}, + {1, GFXBindingType::StorageBuffer}, {2, GFXBindingType::PushConstant} }; + + create_info.shader_input.push_constants = { + {sizeof(Vector4), 0} + }; histogram_pipeline = gfx->create_compute_pipeline(create_info); - create_info.shaders.compute_path = "histogram-average.comp"; + create_info.compute_src = ShaderSource(file::Path("histogram-average.comp")); create_info.workgroup_size_x = 256; create_info.workgroup_size_y = 1; @@ -1023,7 +1035,7 @@ void renderer::create_histogram_resources() { texture_info.width = 1; texture_info.height = 1; texture_info.format = GFXPixelFormat::R_16F; - texture_info.usage = GFXTextureUsage::Sampled | GFXTextureUsage::ShaderWrite; + texture_info.usage = GFXTextureUsage::Sampled | GFXTextureUsage::ShaderWrite | GFXTextureUsage::Storage; average_luminance_texture = gfx->create_texture(texture_info); } diff --git a/engine/renderer/src/scenecapture.cpp b/engine/renderer/src/scenecapture.cpp index 013de6a..87f94f0 100755 --- a/engine/renderer/src/scenecapture.cpp +++ b/engine/renderer/src/scenecapture.cpp @@ -84,7 +84,7 @@ SceneCapture::SceneCapture(GFX* gfx) { textureInfo.width = scene_cubemap_resolution; textureInfo.height = scene_cubemap_resolution; textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; - textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Transfer; + textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::TransferSrc | GFXTextureUsage::Sampled; textureInfo.samplingMode = SamplingMode::ClampToEdge; offscreenTexture = gfx->create_texture(textureInfo); @@ -431,7 +431,7 @@ void SceneCapture::createIrradianceResources() { textureInfo.width = irradiance_cubemap_resolution; textureInfo.height = irradiance_cubemap_resolution; textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; - textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Transfer; + textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::TransferSrc; textureInfo.samplingMode = SamplingMode::ClampToEdge; irradianceOffscreenTexture = gfx->create_texture(textureInfo); @@ -486,7 +486,7 @@ void SceneCapture::createPrefilterResources() { textureInfo.width = scene_cubemap_resolution; textureInfo.height = scene_cubemap_resolution; textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; - textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Transfer; + textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::TransferSrc; textureInfo.samplingMode = SamplingMode::ClampToEdge; prefilteredOffscreenTexture = gfx->create_texture(textureInfo); diff --git a/engine/renderer/src/shadowpass.cpp b/engine/renderer/src/shadowpass.cpp index 29258ac..d2c39ec 100755 --- a/engine/renderer/src/shadowpass.cpp +++ b/engine/renderer/src/shadowpass.cpp @@ -381,9 +381,9 @@ void ShadowPass::create_offscreen_resources() { textureInfo.width = render_options.shadow_resolution; textureInfo.height = render_options.shadow_resolution; textureInfo.format = GFXPixelFormat::R_32F; - textureInfo.usage = GFXTextureUsage::Attachment; + textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; textureInfo.samplingMode = SamplingMode::ClampToEdge; - + offscreen_color_texture = gfx->create_texture(textureInfo); GFXTextureCreateInfo depthTextureInfo = {}; @@ -391,7 +391,7 @@ void ShadowPass::create_offscreen_resources() { depthTextureInfo.width = render_options.shadow_resolution; depthTextureInfo.height = render_options.shadow_resolution; depthTextureInfo.format = GFXPixelFormat::DEPTH_32F; - depthTextureInfo.usage = GFXTextureUsage::Attachment; + depthTextureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; depthTextureInfo.samplingMode = SamplingMode::ClampToEdge; offscreen_depth = gfx->create_texture(depthTextureInfo); diff --git a/engine/renderer/src/smaapass.cpp b/engine/renderer/src/smaapass.cpp index 092184d..d912e36 100755 --- a/engine/renderer/src/smaapass.cpp +++ b/engine/renderer/src/smaapass.cpp @@ -102,7 +102,7 @@ void SMAAPass::create_textures() { areaInfo.width = AREATEX_WIDTH; areaInfo.height = AREATEX_HEIGHT; areaInfo.format = GFXPixelFormat::R8G8_UNORM; - areaInfo.usage = GFXTextureUsage::Sampled; + areaInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst; areaInfo.samplingMode = SamplingMode::ClampToEdge; area_image = gfx->create_texture(areaInfo); @@ -115,7 +115,7 @@ void SMAAPass::create_textures() { searchInfo.width = SEARCHTEX_WIDTH; searchInfo.height = SEARCHTEX_HEIGHT; searchInfo.format = GFXPixelFormat::R8_UNORM; - searchInfo.usage = GFXTextureUsage::Sampled; + searchInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst; searchInfo.samplingMode = SamplingMode::ClampToEdge; search_image = gfx->create_texture(searchInfo);