summaryrefslogtreecommitdiffstats
path: root/tools/gfx/vulkan/vk-util.h
blob: 458979a2fa7fd6bb85b32337c6fded75bf5b0de4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// vk-util.h
#pragma once

#include "core/slang-basic.h"
#include "slang-gfx.h"
#include "vk-api.h"

// Macros to make testing vulkan return codes simpler

/// SLANG_VK_RETURN_ON_FAIL can be used in a similar way to SLANG_RETURN_ON_FAIL macro, except it
/// will turn a vulkan failure into Slang::Result in the process Calls handleFail which on debug
/// builds asserts
#define SLANG_VK_RETURN_ON_FAIL(x)               \
    {                                            \
        VkResult _res = x;                       \
        if (_res != VK_SUCCESS)                  \
        {                                        \
            return VulkanUtil::handleFail(_res); \
        }                                        \
    }

#define SLANG_VK_RETURN_NULL_ON_FAIL(x)   \
    {                                     \
        VkResult _res = x;                \
        if (_res != VK_SUCCESS)           \
        {                                 \
            VulkanUtil::handleFail(_res); \
            return nullptr;               \
        }                                 \
    }

/// Is similar to SLANG_VK_RETURN_ON_FAIL, but does not return. Will call checkFail on failure -
/// which asserts on debug builds.
#define SLANG_VK_CHECK(x)                \
    {                                    \
        VkResult _res = x;               \
        if (_res != VK_SUCCESS)          \
        {                                \
            VulkanUtil::checkFail(_res); \
        }                                \
    }

namespace gfx
{

// Utility functions for Vulkan
struct VulkanUtil
{
    /// Get the equivalent VkFormat from the format
    /// Returns VK_FORMAT_UNDEFINED if a match is not found
    static VkFormat getVkFormat(Format format);

    static VkImageAspectFlags getAspectMask(TextureAspect aspect, VkFormat format);

    /// Called by SLANG_VK_RETURN_FAIL if a res is a failure.
    /// On debug builds this will cause an assertion on failure.
    static Slang::Result handleFail(VkResult res);
    /// Called when a failure has occurred with SLANG_VK_CHECK - will typically assert.
    static void checkFail(VkResult res);

    /// Get the VkPrimitiveTopology for the given topology.
    /// Returns VK_PRIMITIVE_TOPOLOGY_MAX_ENUM on failure
    static VkPrimitiveTopology getVkPrimitiveTopology(PrimitiveTopology topology);

    static VkImageLayout mapResourceStateToLayout(ResourceState state);

    /// Returns Slang::Result equivalent of a VkResult
    static Slang::Result toSlangResult(VkResult res);

    static VkShaderStageFlags getShaderStage(SlangStage stage);

    static VkImageLayout getImageLayoutFromState(ResourceState state);

    /// Calculate size taking into account alignment. Alignment must be a power of 2
    static UInt calcAligned(UInt size, UInt alignment)
    {
        return (size + alignment - 1) & ~(alignment - 1);
    }

    static inline bool isDepthFormat(VkFormat format)
    {
        switch (format)
        {
        case VK_FORMAT_D16_UNORM:
        case VK_FORMAT_D24_UNORM_S8_UINT:
        case VK_FORMAT_X8_D24_UNORM_PACK32:
        case VK_FORMAT_D32_SFLOAT:
        case VK_FORMAT_D32_SFLOAT_S8_UINT:
            return true;
        }
        return false;
    }

    static inline bool isStencilFormat(VkFormat format)
    {
        switch (format)
        {
        case VK_FORMAT_S8_UINT:
        case VK_FORMAT_D24_UNORM_S8_UINT:
        case VK_FORMAT_D32_SFLOAT_S8_UINT:
            return true;
        }
        return false;
    }

    static VkSampleCountFlagBits translateSampleCount(uint32_t sampleCount);

    static VkCullModeFlags translateCullMode(CullMode cullMode);

    static VkFrontFace translateFrontFaceMode(FrontFaceMode frontFaceMode);

    static VkPolygonMode translateFillMode(FillMode fillMode);

    static VkBlendFactor translateBlendFactor(BlendFactor blendFactor);

    static VkBlendOp translateBlendOp(BlendOp op);

    static VkPrimitiveTopology translatePrimitiveTypeToListTopology(PrimitiveType primitiveType);

    static VkStencilOp translateStencilOp(StencilOp op);

    static VkFilter translateFilterMode(TextureFilteringMode mode);

    static VkSamplerMipmapMode translateMipFilterMode(TextureFilteringMode mode);

    static VkSamplerAddressMode translateAddressingMode(TextureAddressingMode mode);

    static VkCompareOp translateComparisonFunc(ComparisonFunc func);

    static VkStencilOpState translateStencilState(DepthStencilOpDesc desc);

    static VkSamplerReductionMode translateReductionOp(TextureReductionOp op);

    static CooperativeVectorComponentType translateCooperativeVectorComponentType(
        VkComponentTypeKHR type);
};

struct AccelerationStructureBuildGeometryInfoBuilder
{
public:
    VkAccelerationStructureBuildGeometryInfoKHR buildInfo = {
        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR};
    Slang::List<uint32_t> primitiveCounts;

    Slang::Result build(
        const IAccelerationStructure::BuildInputs& buildInputs,
        IDebugCallback* debugCallback);

private:
    Slang::List<VkAccelerationStructureGeometryKHR> m_geometryInfos;
    VkAccelerationStructureGeometryKHR m_vkInstanceInfo = {
        VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR};
};


} // namespace gfx