过去几周我一直在与Vulkan合作,而我遇到的问题只发生在AMD卡上.特别是AMD 7970M.我在GTX 700和900系列卡上运行我的项目没有问题.我甚至在Windows上运行了一个带有Nvidia卡的Linux(Steam OS).问题只出现在AMD卡上,只出现在我的项目中; 来自Sascha Willems的所有样品和项目都没有问题.
现在我正在绘制纹理Raptor模型并将其旋转到位.我将其渲染到纹理,然后将该纹理应用于全屏三角形; 基本的屏幕外渲染.但是我的7970M上的深度似乎没有正确清晰.相反,我得到这个奇怪的神器,就像深度未被正确清除:

当然我试着用RenderDoc挖掘它,深度是完全错误的.Raptor和Fullscreen Triangle都是一团糟:


我已经尝试将我的代码与Sascha Willems的Offscreen示例进行比较,我看起来几乎都以同样的方式做了一切.我想也许我创建深度的方式可能有问题,但与我见过的所有例子相比,这似乎很好.
以下是我创建深度图像和视图的一些调试视图:

这是整个方法:
bool VKRenderTarget::setupFramebuffer(VKRenderer* renderer)
{
VkDevice device = renderer->GetVKDevice();
VkCommandBuffer setupCommand;
m_colorFormat = renderer->GetPreferredImageFormat();
m_depthFormat = renderer->GetPreferredDepthFormat();
renderer->CreateSetupCommandBuffer();
setupCommand = renderer->GetSetupCommandBuffer();
VkResult err;
//Color attachment
VkImageCreateInfo imageInfo = {};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.pNext = nullptr;
imageInfo.format = m_colorFormat;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.extent.width = m_width;
imageInfo.extent.height = m_height;
imageInfo.mipLevels = 1;
imageInfo.arrayLayers = 1;
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
imageInfo.flags …Run Code Online (Sandbox Code Playgroud) 我一直在阅读Vulkan规范和Khronos的一些例子,但我总体上找不到关于不可变采样器的大量信息.
我要做的是设置一个充满不可变采样器的描述符(类型为VK_DESCRIPTOR_TYPE_SAMPLER,而不是...... COMBINED_IMAGE_SAMPLER),当我想采样纹理时,我在我的着色器中访问这样的采样器:
layout (location = 0) out vec4 out_color;
layout (set = 0, binding = 0) uniform sampler immutableSampler;
layout (set = 3, binding = 0) uniform texture2D color;
void main()
{
vec4 textureColor = texture(sampler2D(color, immutableSampler), in_uv);
out_color = textureColor;
}
Run Code Online (Sandbox Code Playgroud)
使用此着色器的想法是:
sampler2D但是,我在Khronos样本中看到它的方式是:
sampler2D在着色器中以图像形式访问图像; 您绑定的图像与该绑定的不可变采样器配对在Vulkan规范中,它没有说明哪种方式是"正确的"只注意到:
如果
descriptorType指定了一个VK_DESCRIPTOR_TYPE_SAMPLER或VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER类型描述符,那么pImmutableSamplers可以用来初始化一组不可变的采样器.
现在,如果我的着色器按照我预期的方式工作,我就不会问这个问题了.我遇到的问题是,在验证时,Vulkan层会抱怨我的VkPipeline正在使用一个描述符集(设置为0,绑定0,其中采样器所在的位置)从未绑定过!即使我在那里绑定垃圾数据,我仍然必须(至少一次)用垃圾更新描述符集,以便抑制另一个验证错误.然而,与此同时,Vulkan规范说:
不可变采样器永久地绑定到集布局中; 稍后将采样器绑定到描述符集中的不可变采样器槽中是不允许的
因此甚至不允许将数据绑定到该绑定点!
我现在很不确定我对不可变采样器的处理方法是否应该是有效的,因为它有点含糊不清.规范说我可以在没有图像的情况下绑定一个采样器,但是当我这样做时会抱怨,而我发现的几个例子都是绑定一个组合图像采样器.我这样做错了吗?
如果我的方法应该是有效的并且可以工作,我真的很喜欢,因为我正在尝试为DirectX 12和Vulkan构建一个系统.DX12在其"根布局"(管道布局)中占有一席之地,其中所有不可变采样器都被绑定而没有与它们相关联的图像.我想模仿这种行为以保持渲染器之间的平等,但我不确定是否真的可以使用Vulkan并且它在规范中非常模糊.