private void Docompute(ComputePass renderPass, RenderContext rc, CommandBuffer cb) { // Record particle movements. cb.BindComputePipeline(computePipeline); cb.BindComputeResourceSet(computePipeline.PipelineLayout, 0, computeResourceSet); cb.Dispatch(storageTex.width / 16, storageTex.height / 16, 1); }
void Preprocess() { Shader shader = Resources.Load <Shader>("shaders/brdf.shader"); { Pass pass = shader.GetPass("SpMap"); uint numMipTailLevels = (uint)kEnvMapLevels - 1; // Compute pre-filtered specular environment map. var specializationInfo = new SpecializationInfo(new VkSpecializationMapEntry(0, 0, sizeof(uint))); specializationInfo.Write(0, numMipTailLevels); pass.ComputeShader.SpecializationInfo = specializationInfo; DescriptorSetLayout resLayout = pass.GetResourceLayout(0); spSet = new DescriptorSet(resLayout); CommandBuffer commandBuffer = Graphics.BeginPrimaryCmd(); // Copy base mipmap level into destination environment map. { Span <VkImageMemoryBarrier> preCopyBarriers = stackalloc[] { new VkImageMemoryBarrier(cubeMap.image, 0, VkAccessFlags.TransferRead, VkImageLayout.ShaderReadOnlyOptimal, VkImageLayout.TransferSrcOptimal, VkImageAspectFlags.Color, 0, 1), new VkImageMemoryBarrier(envMap.image, 0, VkAccessFlags.TransferWrite, VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal), }; Span <VkImageMemoryBarrier> postCopyBarriers = stackalloc[] { new VkImageMemoryBarrier(cubeMap.image, VkAccessFlags.TransferRead, VkAccessFlags.ShaderRead, VkImageLayout.TransferSrcOptimal, VkImageLayout.ShaderReadOnlyOptimal, VkImageAspectFlags.Color, 0, 1), new VkImageMemoryBarrier(envMap.image, VkAccessFlags.TransferWrite, VkAccessFlags.ShaderWrite, VkImageLayout.TransferDstOptimal, VkImageLayout.General), }; commandBuffer.PipelineBarrier(VkPipelineStageFlags.TopOfPipe, VkPipelineStageFlags.Transfer, preCopyBarriers); VkImageCopy copyRegion = new VkImageCopy { extent = new VkExtent3D(envMap.width, envMap.height, 1) }; copyRegion.srcSubresource.aspectMask = VkImageAspectFlags.Color; copyRegion.srcSubresource.layerCount = envMap.layers; copyRegion.dstSubresource = copyRegion.srcSubresource; commandBuffer.CopyImage(cubeMap.image, VkImageLayout.TransferSrcOptimal, envMap.image, VkImageLayout.TransferDstOptimal, ref copyRegion); commandBuffer.PipelineBarrier(VkPipelineStageFlags.Transfer, VkPipelineStageFlags.ComputeShader, postCopyBarriers); // Pre-filter rest of the mip-chain. List <ImageView> envTextureMipTailViews = new List <ImageView>(); var inputTexture = new VkDescriptorImageInfo(computeSampler, cubeMap.imageView, VkImageLayout.ShaderReadOnlyOptimal); spSet.Bind(0, ref inputTexture); Span <VkDescriptorImageInfo> envTextureMipTailDescriptors = stackalloc VkDescriptorImageInfo[(int)numMipTailLevels]; for (uint level = 0; level < numMipTailLevels; ++level) { var view = ImageView.Create(envMap.image, VkImageViewType.ImageCube, VkFormat.R16G16B16A16SFloat, VkImageAspectFlags.Color, level + 1, 1, 0, envMap.image.arrayLayers); envTextureMipTailViews.Add(view); envTextureMipTailDescriptors[(int)level] = new VkDescriptorImageInfo(VkSampler.Null, view, VkImageLayout.General); } spSet.Bind(1, envTextureMipTailDescriptors); spSet.UpdateSets(); commandBuffer.BindComputePipeline(pass); commandBuffer.BindComputeResourceSet(pass.PipelineLayout, 0, spSet); float deltaRoughness = 1.0f / Math.Max((float)numMipTailLevels, 1.0f); for (uint level = 1, size = kEnvMapSize / 2; level < kEnvMapLevels; ++level, size /= 2) { uint numGroups = Math.Max(1, size / 32); var pushConstants = new SpecularFilterPushConstants { level = level - 1, roughness = level * deltaRoughness }; commandBuffer.PushConstants(pass.PipelineLayout, VkShaderStageFlags.Compute, 0, ref pushConstants); commandBuffer.Dispatch(numGroups, numGroups, 6); } var barrier = new VkImageMemoryBarrier(envMap.image, VkAccessFlags.ShaderWrite, 0, VkImageLayout.General, VkImageLayout.ShaderReadOnlyOptimal); commandBuffer.PipelineBarrier(VkPipelineStageFlags.ComputeShader, VkPipelineStageFlags.BottomOfPipe, ref barrier); } Graphics.EndPrimaryCmd(commandBuffer); } // Compute diffuse irradiance cubemap { Pass pass = shader.GetPass("IrMap"); DescriptorSetLayout resLayout = pass.GetResourceLayout(0); irSet = new DescriptorSet(resLayout, cubeMap, irMap); CommandBuffer commandBuffer = Graphics.BeginPrimaryCmd(); { Span <VkImageMemoryBarrier> barriers = stackalloc [] { new VkImageMemoryBarrier(irMap.image, 0, VkAccessFlags.ShaderWrite, VkImageLayout.Undefined, VkImageLayout.General) }; commandBuffer.PipelineBarrier(VkPipelineStageFlags.TopOfPipe, VkPipelineStageFlags.ComputeShader, barriers); commandBuffer.BindComputePipeline(pass); commandBuffer.BindComputeResourceSet(pass.PipelineLayout, 0, irSet); commandBuffer.Dispatch(kIrradianceMapSize / 32, kIrradianceMapSize / 32, 6); Span <VkImageMemoryBarrier> postDispatchBarrier = stackalloc [] { new VkImageMemoryBarrier(irMap.image, VkAccessFlags.ShaderWrite, 0, VkImageLayout.General, VkImageLayout.ShaderReadOnlyOptimal) }; commandBuffer.PipelineBarrier(VkPipelineStageFlags.ComputeShader, VkPipelineStageFlags.BottomOfPipe, postDispatchBarrier); } Graphics.EndPrimaryCmd(commandBuffer); } // Compute Cook-Torrance BRDF 2D LUT for split-sum approximation. { var pass = shader.GetPass("BrdfLUT"); DescriptorSetLayout resLayout = pass.GetResourceLayout(0); brdfLUTSet = new DescriptorSet(resLayout, brdfLUT); CommandBuffer commandBuffer = Graphics.BeginPrimaryCmd(); { Span <VkImageMemoryBarrier> barriers = stackalloc [] { new VkImageMemoryBarrier(brdfLUT.image, 0, VkAccessFlags.ShaderWrite, VkImageLayout.Undefined, VkImageLayout.General) }; commandBuffer.PipelineBarrier(VkPipelineStageFlags.TopOfPipe, VkPipelineStageFlags.ComputeShader, barriers); commandBuffer.BindComputePipeline(pass); commandBuffer.BindComputeResourceSet(pass.PipelineLayout, 0, brdfLUTSet); commandBuffer.Dispatch(kBRDF_LUT_Size / 32, kBRDF_LUT_Size / 32, 6); Span <VkImageMemoryBarrier> postDispatchBarrier = stackalloc [] { new VkImageMemoryBarrier(brdfLUT.image, VkAccessFlags.ShaderWrite, 0, VkImageLayout.General, VkImageLayout.ShaderReadOnlyOptimal) }; commandBuffer.PipelineBarrier(VkPipelineStageFlags.ComputeShader, VkPipelineStageFlags.BottomOfPipe, postDispatchBarrier); } Graphics.EndPrimaryCmd(commandBuffer); } } int selected = 0;