texture 如果要被采样就该绑成srv这里封成两种就很奇怪了 跟了下看
使用时比如
这里
// Custom Depth / Stencil SHADER_PARAMETER_TEXTURE(Texture2D<float>, CustomDepthTextureNonMS) SHADER_PARAMETER_TEXTURE(Texture2D, CustomDepthTexture) SHADER_PARAMETER_SAMPLER(SamplerState, CustomDepthTextureSampler) SHADER_PARAMETER_SRV(Texture2D<uint2>, CustomStencilTexture) SHADER_PARAMETER_SRV(Texture2D<uint2>, SceneStencilTexture)
stencil仅仅bind成srv 而不是像上面depth那样 texture+sampler
从使用上能看到这种patten
最底层这两者封装差异能看到
inline void SetTexture(uint8 DescriptorSet, uint32 BindingIndex, const FVulkanTextureBase* TextureBase, VkImageLayout Layout) { check(TextureBase && TextureBase->PartialView); MarkDirty(DSWriter[DescriptorSet].WriteImage(BindingIndex, *TextureBase->PartialView, Layout)); } inline void SetSRVBufferViewState(uint8 DescriptorSet, uint32 BindingIndex, const FVulkanBufferView* View) { check(View && (View->Flags & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) == VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT); MarkDirty(DSWriter[DescriptorSet].WriteUniformTexelBuffer(BindingIndex, View)); } inline void SetSRVTextureView(uint8 DescriptorSet, uint32 BindingIndex, const FVulkanTextureView& TextureView, VkImageLayout Layout) { MarkDirty(DSWriter[DescriptorSet].WriteImage(BindingIndex, TextureView, Layout)); }
上面是pipeline那层的封装
中间省略100层封装
最后
descriptorSets层的封装差异
template <VkDescriptorType DescriptorType> bool WriteTextureView(uint32 DescriptorIndex, const FVulkanTextureView& TextureView, VkImageLayout Layout) { check(DescriptorIndex < NumWrites); if (DescriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) { check(WriteDescriptors[DescriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || WriteDescriptors[DescriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); ensureMsgf(Layout == VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR || Layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL || Layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL || Layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL || Layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL || Layout == VK_IMAGE_LAYOUT_GENERAL, TEXT("Invalid Layout %d, Index %d, Type %d "), Layout, DescriptorIndex, WriteDescriptors[DescriptorIndex].descriptorType); } else { check(WriteDescriptors[DescriptorIndex].descriptorType == DescriptorType); } VkDescriptorImageInfo* ImageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[DescriptorIndex].pImageInfo); check(ImageInfo); bool bChanged = false; if (UseVulkanDescriptorCache()) { FVulkanHashableDescriptorInfo& HashableInfo = HashableDescriptorInfos[DescriptorIndex]; check(TextureView.ViewId > 0); if (HashableInfo.Image.ImageViewId != TextureView.ViewId) { HashableInfo.Image.ImageViewId = TextureView.ViewId; ImageInfo->imageView = TextureView.View; bChanged = true; } if (HashableInfo.Image.ImageLayout != static_cast<uint32>(Layout)) { HashableInfo.Image.ImageLayout = static_cast<uint32>(Layout); ImageInfo->imageLayout = Layout; bChanged = true; } bIsKeyDirty |= bChanged; } else { bChanged = CopyAndReturnNotEqual(ImageInfo->imageView, TextureView.View); bChanged |= CopyAndReturnNotEqual(ImageInfo->imageLayout, Layout); } return bChanged; } template <VkDescriptorType DescriptorType> bool WriteBufferView(uint32 DescriptorIndex, const FVulkanBufferView* View) { check(DescriptorIndex < NumWrites); check(WriteDescriptors[DescriptorIndex].descriptorType == DescriptorType); WriteDescriptors[DescriptorIndex].pTexelBufferView = &View->View; BufferViewReferences[DescriptorIndex] = View; if (UseVulkanDescriptorCache()) { bool bChanged = false; FVulkanHashableDescriptorInfo& HashableInfo = HashableDescriptorInfos[DescriptorIndex]; check(View->ViewId > 0); if (HashableInfo.BufferView.Id != View->ViewId) { HashableInfo.BufferView.Id = View->ViewId; bChanged = true; } bIsKeyDirty |= bChanged; return bChanged; } else { return true; } }
descriptor更新 view更新
除此中间还有些buffer flag的差异
总结:
rhi层封装为texture view和buffer view的区分