簡體   English   中英

vulkan glsl 中的非統一紋理訪問

[英]Non uniform texture access in vulkan glsl

我正在嘗試編寫一個計算着色器,它對圖像進行光線跟蹤,圖像 A 的 yz 平面樣本右側的像素,圖像 B 左側的像素。

我不想對兩個圖像都進行采樣,所以我嘗試通過以下方式使用非統一訪問:

texture(textures[nonuniformEXT(sampler_id)], vec2(0.5));

並在着色器中啟用相關擴展。 這會觸發以下驗證層錯誤:

Message: Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-01091 ] Object 0: handle = 0x55a1c21315d0, name = Logical device: AMD RADV RAVEN2, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xa7bb8db6 | vkCreateShaderModule(): The SPIR-V Capability (SampledImageArrayNonUniformIndexing) was declared, but none of the requirements were met to use it. The Vulkan spec states: If pCode declares any of the capabilities listed in the SPIR-V Environment appendix, one of the corresponding requirements must be satisfied (https://vulkan.lunarg.com/doc/view/1.2.182.0/linux/1.2-extensions/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-01091)

如果我閱讀文檔,這似乎是一項硬件功能,但有人說如果創建正確的擴展 object,我仍然可以進行非統一訪問。但我不完全確定該怎么做。

您必須在創建設備時啟用該功能。

您可以通過調用vkGetPhysicalDeviceFeatures2並跟隨pNext鏈直到VkPhysicalDeviceVulkan12Features來檢查是否支持該功能,並檢查shaderSampledImageArrayNonUniformIndexing成員是否為VK_TRUE

之后,當使用vkCreateDevice創建設備時,在pCreateInfo結構內,在pNext鏈中,您必須將VkPhysicalDeviceVulkan12FeaturesshaderSampledImageArrayNonUniformIndexing設置為VK_TRUE

bool checkForNonUniformIndexing(VkPhysicalDevice physicalDevice)
{
    VkPhysicalDeviceFeatures2 features;
    vkGetPhysicalDeviceFeatures2(physicalDevice, &features);

    if(features.sType != VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2)
    {
        return false;
    }

    const VkPhysicalDeviceFeatures2* next = &features;

    do
    {
        // We know the type of the struct based on the `sType` member, but the first 
        // two fields are the same in all of these structs. There may be a more appropriate 
        // generic structure to use, but as long as we don't access any further members
        // we should be mostly fine.
        next = reinterpret_cast<const VkPhysicalDeviceFeatures*>(next->pNext);
        if(next.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES)
        {
            const VkPhysicalDeviceVulkan12Features* pVk12Features = reinterpret_cast<const VkPhysicalDeviceVulkan12Features*>(next);
            return next.shaderSampledImageArrayNonUniformIndexing == VK_TRUE;
        }
    } while(next);

    return false;
}

VkDevice* createDevice(VkPhysicalDevice physicalDevice, const VkAllocationCallbacks* pAllocator)
{
    VkPhysicalDeviceVulkan12Features features;
    features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
    features.shaderSampledImageArrayNonUniformIndexing = VK_TRUE;

    VkDeviceCreateInfo createInfo;
    createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    createInfo.pNext = &features;
    // Setting other create data

    VkDevice device;
    vkCreateDevice(physicalDevice, &createInfo, pAllocator, &device);

    // Error checking

    return device;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM