Skip to content
Snippets Groups Projects
vkd3d_shader.h 95.3 KiB
Newer Older
/*
 * Copyright 2017-2019 Józef Kucia for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#ifndef __VKD3D_SHADER_H
#define __VKD3D_SHADER_H

#include <stdbool.h>
#include <stdint.h>
#include <vkd3d_types.h>

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus */

/**
 * \file vkd3d_shader.h
 *
 * This file contains definitions for the vkd3d-shader library.
 *
 * The vkd3d-shader library provides multiple utilities related to the
 * compilation, transformation, and reflection of GPU shaders.
 */

/** \since 1.3 */
enum vkd3d_shader_api_version
{
    VKD3D_SHADER_API_VERSION_1_0,
    VKD3D_SHADER_API_VERSION_1_1,
    VKD3D_SHADER_API_VERSION_1_2,
    VKD3D_SHADER_API_VERSION_1_3,
    VKD3D_SHADER_API_VERSION_1_4,
    VKD3D_SHADER_API_VERSION_1_5,
    VKD3D_SHADER_API_VERSION_1_6,
    VKD3D_SHADER_API_VERSION_1_7,
    VKD3D_SHADER_API_VERSION_1_8,
    VKD3D_SHADER_API_VERSION_1_9,
    VKD3D_SHADER_API_VERSION_1_10,
    VKD3D_SHADER_API_VERSION_1_11,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_API_VERSION),
};

/** The type of a chained structure. */
enum vkd3d_shader_structure_type
{
    /** The structure is a vkd3d_shader_compile_info structure. */
    VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO,
    /** The structure is a vkd3d_shader_interface_info structure. */
    VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO,
    /** The structure is a vkd3d_shader_scan_descriptor_info structure. */
    VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO,
    /** The structure is a vkd3d_shader_spirv_domain_shader_target_info structure. */
    VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_DOMAIN_SHADER_TARGET_INFO,
    /** The structure is a vkd3d_shader_spirv_target_info structure. */
    VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO,
    /** The structure is a vkd3d_shader_transform_feedback_info structure. */
    VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO,

    /**
     * The structure is a vkd3d_shader_hlsl_source_info structure.
     * \since 1.3
     */
    VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO,
    /**
     * The structure is a vkd3d_shader_preprocess_info structure.
     * \since 1.3
     */
    VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO,
    /**
     * The structure is a vkd3d_shader_descriptor_offset_info structure.
     * \since 1.3
     */
    VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO,
    /**
     * The structure is a vkd3d_shader_scan_signature_info structure.
     * \since 1.9
     */
    VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO,
    /**
     * The structure is a vkd3d_shader_varying_map_info structure.
     * \since 1.9
     */
    VKD3D_SHADER_STRUCTURE_TYPE_VARYING_MAP_INFO,
    /**
     * The structure is a vkd3d_shader_scan_combined_resource_sampler_info structure.
     * \since 1.10
     */
    VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
};

/**
 * Determines how buffer UAVs are stored.
 *
 * This also affects UAV counters in Vulkan environments. In OpenGL
 * environments, atomic counter buffers are always used for UAV counters.
 */
enum vkd3d_shader_compile_option_buffer_uav
{
    /** Use buffer textures for buffer UAVs. This is the default value. */
    VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV_STORAGE_TEXEL_BUFFER = 0x00000000,
    /** Use storage buffers for buffer UAVs. */
    VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV_STORAGE_BUFFER       = 0x00000001,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV),
};

/**
 * Determines how typed UAVs are declared.
 * \since 1.5
 */
enum vkd3d_shader_compile_option_typed_uav
{
    /** Use R32(u)i/R32f format for UAVs which are read from. This is the default value. */
    VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV_READ_FORMAT_R32     = 0x00000000,
    /**
     * Use Unknown format for UAVs which are read from. This should only be set if
     * shaderStorageImageReadWithoutFormat is enabled in the target environment.
     */
    VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV_READ_FORMAT_UNKNOWN = 0x00000001,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV),
};

enum vkd3d_shader_compile_option_formatting_flags
{
    VKD3D_SHADER_COMPILE_OPTION_FORMATTING_NONE    = 0x00000000,
    VKD3D_SHADER_COMPILE_OPTION_FORMATTING_COLOUR  = 0x00000001,
    VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT  = 0x00000002,
    VKD3D_SHADER_COMPILE_OPTION_FORMATTING_OFFSETS = 0x00000004,
    VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER  = 0x00000008,
    VKD3D_SHADER_COMPILE_OPTION_FORMATTING_RAW_IDS = 0x00000010,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FORMATTING_FLAGS),
};

/** Determines how matrices are stored. \since 1.9 */
enum vkd3d_shader_compile_option_pack_matrix_order
{
    VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR    = 0x00000001,
    VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR = 0x00000002,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER),
};

/** Individual options to enable various backward compatibility features. \since 1.10 */
enum vkd3d_shader_compile_option_backward_compatibility
{
    /**
     *  Causes compiler to convert SM1-3 semantics to corresponding System Value semantics,
     *  when compiling HLSL sources for SM4+ targets.
     *
     *  This option does the following conversions:
     *
     *  - POSITION to SV_Position for vertex shader outputs, pixel shader inputs,
     *    and geometry shader inputs and outputs;
     *  - COLORN to SV_TargetN for pixel shader outputs;
     *  - DEPTH to SV_Depth for pixel shader outputs.
     */
    VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES = 0x00000001,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY),
};

/**
 * Determines the origin of fragment coordinates.
 *
 * \since 1.10
 */
enum vkd3d_shader_compile_option_fragment_coordinate_origin
{
    /** Fragment coordinates originate from the upper-left. This is the
     * default; it's also the only value supported by Vulkan environments. */
    VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN_UPPER_LEFT = 0x00000000,
    /** Fragment coordinates originate from the lower-left. This matches the
     * traditional behaviour of OpenGL environments. */
    VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN_LOWER_LEFT = 0x00000001,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN),
};

/** Advertises feature availability. \since 1.11 */
enum vkd3d_shader_compile_option_feature_flags
{
    /** The SPIR-V target environment supports 64-bit integer types. This
     * corresponds to the "shaderInt64" feature in the Vulkan API, and the
     * "GL_ARB_gpu_shader_int64" extension in the OpenGL API. */
    VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64         = 0x00000001,
    /** The SPIR-V target environment supports 64-bit floating-point types.
     * This corresponds to the "shaderFloat64" feature in the Vulkan API, and
     * the "GL_ARB_gpu_shader_fp64" extension in the OpenGL API. */
    VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64       = 0x00000002,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLAGS),
};

enum vkd3d_shader_compile_option_name
{
    /**
     * If \a value is nonzero, do not include debug information in the
     * compiled shader. The default value is zero.
     *
     * This option is supported by vkd3d_shader_compile(). However, not all
     * compilers support generating debug information.
     */
    VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG = 0x00000001,
    /** \a value is a member of enum vkd3d_shader_compile_option_buffer_uav. */
    VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV  = 0x00000002,
    /** \a value is a member of enum vkd3d_shader_compile_option_formatting_flags. */
    VKD3D_SHADER_COMPILE_OPTION_FORMATTING  = 0x00000003,
    /** \a value is a member of enum vkd3d_shader_api_version. \since 1.3 */
    VKD3D_SHADER_COMPILE_OPTION_API_VERSION = 0x00000004,
    /** \a value is a member of enum vkd3d_shader_compile_option_typed_uav. \since 1.5 */
    VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV   = 0x00000005,
    /**
     * If \a value is nonzero, write the point size for Vulkan tessellation and
     * geometry shaders. This option should be enabled if and only if the
     * shaderTessellationAndGeometryPointSize feature is enabled. The default
     * value is nonzero, i.e. write the point size.
     *
     * This option is supported by vkd3d_shader_compile() for the SPIR-V target
     * type and Vulkan targets; it should not be enabled otherwise.
     *
     * \since 1.7
     */
    VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE = 0x00000006,
    /**
     * This option specifies default matrix packing order for HLSL sources.
     * Explicit variable modifiers or pragmas will take precedence.
     *
     * \a value is a member of enum vkd3d_shader_compile_option_pack_matrix_order.
     *
     * \since 1.9
     */
    VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER = 0x00000007,
    /**
     * This option is used to enable various backward compatibility features.
     *
     * \a value is a mask of values from enum vkd3d_shader_compile_option_backward_compatibility.
     *
     * \since 1.10
     */
    VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY = 0x00000008,
    /**
     * This option specifies the origin of fragment coordinates for SPIR-V
     * targets.
     *
     * \a value is a member of enum
     * vkd3d_shader_compile_option_fragment_coordinate_origin.
     *
     * \since 1.10
     */
    VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN = 0x00000009,
    /**
     * This option specifies the shader features available in the target
     * environment. These are not extensions, i.e. they are always supported
     * by the driver, but may not be supported by the available hardware.
     *
     * \a value is a member of enum vkd3d_shader_compile_option_feature_flags.
     *
     * \since 1.11
     */
    VKD3D_SHADER_COMPILE_OPTION_FEATURE = 0x0000000a,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME),
};

/**
 * Various settings which may affect shader compilation or scanning, passed as
 * part of struct vkd3d_shader_compile_info. For more details, see the
 * documentation for individual options.
 */
struct vkd3d_shader_compile_option
{
    /** Name of the option. */
    enum vkd3d_shader_compile_option_name name;
    /**
     * A value associated with the option. The type and interpretation of the
     * value depends on the option in question.
     */
    unsigned int value;
};

/** Describes which shader stages a resource is visible to. */
enum vkd3d_shader_visibility
{
    /** The resource is visible to all shader stages. */
    VKD3D_SHADER_VISIBILITY_ALL = 0,
    /** The resource is visible only to the vertex shader. */
    VKD3D_SHADER_VISIBILITY_VERTEX = 1,
    /** The resource is visible only to the hull shader. */
    VKD3D_SHADER_VISIBILITY_HULL = 2,
    /** The resource is visible only to the domain shader. */
    VKD3D_SHADER_VISIBILITY_DOMAIN = 3,
    /** The resource is visible only to the geometry shader. */
    VKD3D_SHADER_VISIBILITY_GEOMETRY = 4,
    /** The resource is visible only to the pixel shader. */
    VKD3D_SHADER_VISIBILITY_PIXEL = 5,

    /** The resource is visible only to the compute shader. */
    VKD3D_SHADER_VISIBILITY_COMPUTE = 1000000000,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_VISIBILITY),
};

/** A generic structure containing a GPU shader, in text or byte-code format. */
struct vkd3d_shader_code
{
    /**
     * Pointer to the code. Note that textual formats are not null-terminated.
     * Therefore \a size should not include a null terminator, when this
     * structure is passed as input to a vkd3d-shader function, and the
     * allocated string will not include a null terminator when this structure
     * is used as output.
     */
    const void *code;
    /** Size of \a code, in bytes. */
    size_t size;
};

/** The type of a shader resource descriptor. */
enum vkd3d_shader_descriptor_type
{
    /**
     * The descriptor is a shader resource view. In Direct3D assembly, this is
     * bound to a t# register.
     */
    VKD3D_SHADER_DESCRIPTOR_TYPE_SRV     = 0x0,
    /**
     * The descriptor is an unordered access view. In Direct3D assembly, this is
     * bound to a u# register.
     */
    VKD3D_SHADER_DESCRIPTOR_TYPE_UAV     = 0x1,
    /**
     * The descriptor is a constant buffer view. In Direct3D assembly, this is
     * bound to a cb# register.
     */
    VKD3D_SHADER_DESCRIPTOR_TYPE_CBV     = 0x2,
    /**
     * The descriptor is a sampler. In Direct3D assembly, this is bound to an s#
     * register.
     */
    VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER = 0x3,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_TYPE),
};

/**
 * A common structure describing the bind point of a descriptor or descriptor
 * array in the target environment.
 */
struct vkd3d_shader_descriptor_binding
{
    /**
     * The set of the descriptor. If the target environment does not support
     * descriptor sets, this value must be set to 0.
     */
    unsigned int set;
    /** The binding index of the descriptor. */
    unsigned int binding;
    /**
     * The size of this descriptor array. If an offset is specified for this
     * binding by the vkd3d_shader_descriptor_offset_info structure, counting
     * starts at that offset.
     */
    unsigned int count;
};

enum vkd3d_shader_binding_flag
{
    VKD3D_SHADER_BINDING_FLAG_BUFFER = 0x00000001,
    VKD3D_SHADER_BINDING_FLAG_IMAGE  = 0x00000002,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_BINDING_FLAG),
};

enum vkd3d_shader_parameter_type
{
    VKD3D_SHADER_PARAMETER_TYPE_UNKNOWN,
    VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT,
    VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_TYPE),
};

enum vkd3d_shader_parameter_data_type
{
    VKD3D_SHADER_PARAMETER_DATA_TYPE_UNKNOWN,
    VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_DATA_TYPE),
};

enum vkd3d_shader_parameter_name
{
    VKD3D_SHADER_PARAMETER_NAME_UNKNOWN,
    VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME),
};

struct vkd3d_shader_parameter_immediate_constant
{
    union
    {
        uint32_t u32;
    } u;
};

struct vkd3d_shader_parameter_specialization_constant
{
    uint32_t id;
};

struct vkd3d_shader_parameter
{
    enum vkd3d_shader_parameter_name name;
    enum vkd3d_shader_parameter_type type;
    enum vkd3d_shader_parameter_data_type data_type;
    union
    {
        struct vkd3d_shader_parameter_immediate_constant immediate_constant;
        struct vkd3d_shader_parameter_specialization_constant specialization_constant;
    } u;
};

/**
 * Symbolic register indices for mapping uniform constant register sets in
 * legacy Direct3D bytecode to constant buffer views in the target environment.
 *
 * Members of this enumeration are used in
 * \ref vkd3d_shader_resource_binding.register_index.
 *
 * \since 1.9
 */
enum vkd3d_shader_d3dbc_constant_register
{
    /** The float constant register set, c# in Direct3D assembly. */
    VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER  = 0x0,
    /** The integer constant register set, i# in Direct3D assembly. */
    VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER    = 0x1,
    /** The boolean constant register set, b# in Direct3D assembly. */
    VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER   = 0x2,
};

/**
 * Describes the mapping of a single resource or resource array to its binding
 * point in the target environment.
 *
 * For example, to map a Direct3D SRV with register space 2, register "t3" to
 * a Vulkan descriptor in set 4 and with binding 5, set the following members:
 * - \a type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV
 * - \a register_space = 2
 * - \a register_index = 3
 * - \a binding.set = 4
 * - \a binding.binding = 5
 * - \a binding.count = 1
 *
 * This structure is used in struct vkd3d_shader_interface_info.
 */
struct vkd3d_shader_resource_binding
{
    /** The type of this descriptor. */
    enum vkd3d_shader_descriptor_type type;
    /**
     * Register space of the Direct3D resource. If the source format does not
     * support multiple register spaces, this parameter must be set to 0.
     */
    unsigned int register_space;
    /**
     * Register index of the Direct3D resource.
     *
     * For legacy Direct3D shaders, vkd3d-shader maps each constant register
     * set to a single constant buffer view. This parameter names the register
     * set to map, and must be a member of
     * enum vkd3d_shader_d3dbc_constant_register.
     */
    unsigned int register_index;
    /** Shader stage(s) to which the resource is visible. */
    enum vkd3d_shader_visibility shader_visibility;
    /** A combination of zero or more elements of vkd3d_shader_binding_flag. */
    unsigned int flags;

    /** The binding in the target environment. */
    struct vkd3d_shader_descriptor_binding binding;
};

#define VKD3D_SHADER_DUMMY_SAMPLER_INDEX ~0u

/**
 * Describes the mapping of a Direct3D resource-sampler pair to a combined
 * sampler (i.e. sampled image).
 *
 * This structure is used in struct vkd3d_shader_interface_info.
 */
struct vkd3d_shader_combined_resource_sampler
{
    /**
     * Register space of the Direct3D resource. If the source format does not
     * support multiple register spaces, this parameter must be set to 0.
     */
    unsigned int resource_space;
    /** Register index of the Direct3D resource. */
    unsigned int resource_index;
    /**
     * Register space of the Direct3D sampler. If the source format does not
     * support multiple register spaces, this parameter must be set to 0.
     */
    unsigned int sampler_space;
    /** Register index of the Direct3D sampler. */
    unsigned int sampler_index;
    /** Shader stage(s) to which the resource is visible. */
    enum vkd3d_shader_visibility shader_visibility;
    /** A combination of zero or more elements of vkd3d_shader_binding_flag. */
    unsigned int flags;

    /** The binding in the target environment. */
    struct vkd3d_shader_descriptor_binding binding;
};

/**
 * Describes the mapping of a single Direct3D UAV counter.
 *
 * This structure is used in struct vkd3d_shader_interface_info.
 */
struct vkd3d_shader_uav_counter_binding
{
    /**
     * Register space of the Direct3D UAV descriptor. If the source format does
     * not support multiple register spaces, this parameter must be set to 0.
     */
    unsigned int register_space;
    /** Register index of the Direct3D UAV descriptor. */
    unsigned int register_index;
    /** Shader stage(s) to which the UAV counter is visible. */
    enum vkd3d_shader_visibility shader_visibility;

    /** The binding in the target environment. */
    struct vkd3d_shader_descriptor_binding binding;
    unsigned int offset;
};

/**
 * Describes the mapping of a Direct3D constant buffer to a range of push
 * constants in the target environment.
 *
 * This structure is used in struct vkd3d_shader_interface_info.
 */
struct vkd3d_shader_push_constant_buffer
{
    /**
     * Register space of the Direct3D resource. If the source format does not
     * support multiple register spaces, this parameter must be set to 0.
     */
    unsigned int register_space;
    /** Register index of the Direct3D resource. */
    unsigned int register_index;
    /** Shader stage(s) to which the resource is visible. */
    enum vkd3d_shader_visibility shader_visibility;

    /** Offset, in bytes, of the target push constants. */
    unsigned int offset;
    /** Size, in bytes, of the target push constants. */
    unsigned int size;
};

/**
 * A chained structure describing the interface between a compiled shader and
 * the target environment.
 *
 * For example, when compiling Direct3D shader byte code to SPIR-V, this
 * structure contains mappings from Direct3D descriptor registers to SPIR-V
 * descriptor bindings.
 *
 * This structure is optional. If omitted, vkd3d_shader_compile() will use a
 * default mapping, in which resources are mapped to sequential bindings in
 * register set 0.
 *
 * This structure extends vkd3d_shader_compile_info.
 *
 * This structure contains only input parameters.
 */
struct vkd3d_shader_interface_info
{
    /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO. */
    enum vkd3d_shader_structure_type type;
    /** Optional pointer to a structure containing further parameters. */
    const void *next;

    /** Pointer to an array of bindings for shader resource descriptors. */
    const struct vkd3d_shader_resource_binding *bindings;
    /** Size, in elements, of \ref bindings. */
    unsigned int binding_count;

    /** Pointer to an array of bindings for push constant buffers. */
    const struct vkd3d_shader_push_constant_buffer *push_constant_buffers;
    /** Size, in elements, of \ref push_constant_buffers. */
    unsigned int push_constant_buffer_count;

    /** Pointer to an array of bindings for combined samplers. */
    const struct vkd3d_shader_combined_resource_sampler *combined_samplers;
    /** Size, in elements, of \ref combined_samplers. */
    unsigned int combined_sampler_count;

    /** Pointer to an array of bindings for UAV counters. */
    const struct vkd3d_shader_uav_counter_binding *uav_counters;
    /** Size, in elements, of \ref uav_counters. */
    unsigned int uav_counter_count;
};

struct vkd3d_shader_transform_feedback_element
{
    unsigned int stream_index;
    const char *semantic_name;
    unsigned int semantic_index;
    uint8_t component_index;
    uint8_t component_count;
    uint8_t output_slot;
};

/* Extends vkd3d_shader_interface_info. */
struct vkd3d_shader_transform_feedback_info
{
    enum vkd3d_shader_structure_type type;
    const void *next;

    const struct vkd3d_shader_transform_feedback_element *elements;
    unsigned int element_count;
    const unsigned int *buffer_strides;
    unsigned int buffer_stride_count;
};

struct vkd3d_shader_descriptor_offset
{
    unsigned int static_offset;
    unsigned int dynamic_offset_index;
};

/**
 * A chained structure containing descriptor offsets.
 *
 * This structure is optional.
 *
 * This structure extends vkd3d_shader_interface_info.
 *
 * This structure contains only input parameters.
 *
 * \since 1.3
 */
struct vkd3d_shader_descriptor_offset_info
{
    /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO. */
    enum vkd3d_shader_structure_type type;
    /** Optional pointer to a structure containing further parameters. */
    const void *next;

    /**
     * Byte offset within the push constants of an array of 32-bit
     * descriptor array offsets. See the description of 'binding_offsets'
     * below.
     */
    unsigned int descriptor_table_offset;
    /** Size, in elements, of the descriptor table push constant array. */
    unsigned int descriptor_table_count;

    /**
     * Pointer to an array of struct vkd3d_shader_descriptor_offset objects.
     * The 'static_offset' field contains an offset into the descriptor arrays
     * referenced by the 'bindings' array in struct vkd3d_shader_interface_info.
     * This allows mapping multiple shader resource arrays to a single binding
     * point in the target environment.
     *
     * 'dynamic_offset_index' in struct vkd3d_shader_descriptor_offset allows
     * offsets to be set at runtime. The 32-bit descriptor table push constant
     * at this index will be added to 'static_offset' to calculate the final
     * binding offset.
     *
     * If runtime offsets are not required, set all 'dynamic_offset_index'
     * values to \c ~0u and 'descriptor_table_count' to zero.
     *
     * For example, to map Direct3D constant buffer registers 'cb0[0:3]' and
     * 'cb1[6:7]' to descriptors 8-12 and 4-5 in the Vulkan descriptor array in
     * descriptor set 3 and with binding 2, set the following values in the
     * 'bindings' array in struct vkd3d_shader_interface_info:
     *
     * \code
     * type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
     * register_space = 0
     * register_index = 0
     * binding.set = 3
     * binding.binding = 2
     * binding.count = 4
     *
     * type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
     * register_space = 0
     * register_index = 6
     * binding.set = 3
     * binding.binding = 2
     * binding.count = 2
     * \endcode
     *
     * and then pass \c {8, \c 4} as static binding offsets here.
     *
     * This field may be NULL, in which case the corresponding offsets are
     * specified to be 0.
     */
    const struct vkd3d_shader_descriptor_offset *binding_offsets;

    /**
     * Pointer to an array of offsets into the descriptor arrays referenced by
     * the 'uav_counters' array in struct vkd3d_shader_interface_info. This
     * works the same way as \ref binding_offsets above.
     */
    const struct vkd3d_shader_descriptor_offset *uav_counter_offsets;
};

/** The format of a shader to be compiled or scanned. */
enum vkd3d_shader_source_type
{
    /**
     * The shader has no type or is to be ignored. This is not a valid value
     * for vkd3d_shader_compile() or vkd3d_shader_scan().
     */
    VKD3D_SHADER_SOURCE_NONE,
    /**
     * A 'Tokenized Program Format' shader embedded in a DXBC container. This is
     * the format used for Direct3D shader model 4 and 5 shaders.
     */
    VKD3D_SHADER_SOURCE_DXBC_TPF,
    /** High-Level Shader Language source code. \since 1.3 */
    VKD3D_SHADER_SOURCE_HLSL,
    /**
     * Legacy Direct3D byte-code. This is the format used for Direct3D shader
     * model 1, 2, and 3 shaders. \since 1.3
     */
    VKD3D_SHADER_SOURCE_D3D_BYTECODE,
    /**
     * A 'DirectX Intermediate Language' shader embedded in a DXBC container. This is
     * the format used for Direct3D shader model 6 shaders. \since 1.9
     */
    VKD3D_SHADER_SOURCE_DXBC_DXIL,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SOURCE_TYPE),
};

/** The output format of a compiled shader. */
enum vkd3d_shader_target_type
{
    /**
     * The shader has no type or is to be ignored. This is not a valid value
     * for vkd3d_shader_compile().
     */
    VKD3D_SHADER_TARGET_NONE,
    /**
     * A SPIR-V shader in binary form. This is the format used for Vulkan
     * shaders.
     */
    VKD3D_SHADER_TARGET_SPIRV_BINARY,
    VKD3D_SHADER_TARGET_SPIRV_TEXT,
    /**
     * Direct3D shader assembly. \since 1.3
     */
    VKD3D_SHADER_TARGET_D3D_ASM,
    /**
     * Legacy Direct3D byte-code. This is the format used for Direct3D shader
     * model 1, 2, and 3 shaders. \since 1.3
     */
    VKD3D_SHADER_TARGET_D3D_BYTECODE,
    /**
     * A 'Tokenized Program Format' shader embedded in a DXBC container. This is
     * the format used for Direct3D shader model 4 and 5 shaders. \since 1.3
     */
    VKD3D_SHADER_TARGET_DXBC_TPF,
    /**
     * An 'OpenGL Shading Language' shader. \since 1.3
     */
    VKD3D_SHADER_TARGET_GLSL,
    /**
     * Binary format used by Direct3D 9/10.x/11 effects profiles.
     * Output is a raw FX section without container. \since 1.11
     */
    VKD3D_SHADER_TARGET_FX,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TARGET_TYPE),
};

/**
 * Describes the minimum severity of compilation messages returned by
 * vkd3d_shader_compile() and similar functions.
 */
enum vkd3d_shader_log_level
{
    /** No messages will be returned. */
    VKD3D_SHADER_LOG_NONE,
    /** Only fatal errors which prevent successful compilation will be returned. */
    VKD3D_SHADER_LOG_ERROR,
    /** Non-fatal warnings and fatal errors will be returned. */
    VKD3D_SHADER_LOG_WARNING,
    /**
     * All messages, including general informational messages, will be returned.
     */
    VKD3D_SHADER_LOG_INFO,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_LOG_LEVEL),
};

/**
 * A chained structure containing compilation parameters.
 */
struct vkd3d_shader_compile_info
{
    /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO. */
    enum vkd3d_shader_structure_type type;
    /**
     * Optional pointer to a structure containing further parameters. For a list
     * of valid structures, refer to the respective function documentation. If
     * no further parameters are needed, this field should be set to NULL.
     */
    const void *next;

    /** Input source code or byte code. */
    struct vkd3d_shader_code source;

    /** Format of the input code passed in \ref source. */
    enum vkd3d_shader_source_type source_type;
    /** Desired output format. */
    enum vkd3d_shader_target_type target_type;

    /**
     * Pointer to an array of compilation options. This field is ignored if
     * \ref option_count is zero, but must be valid otherwise.
     *
     * If the same option is specified multiple times, only the last value is
     * used.
     *
     * Options not relevant to or not supported by a particular shader compiler
     * or scanner will be ignored.
     */
    const struct vkd3d_shader_compile_option *options;
    /** Size, in elements, of \ref options. */
    unsigned int option_count;

    /** Minimum severity of messages returned from the shader function. */
    enum vkd3d_shader_log_level log_level;
    /**
     * Name of the initial source file, which may be used in error messages or
     * debug information. This parameter is optional and may be NULL.
     */
    const char *source_name;
};

enum vkd3d_shader_spirv_environment
{
    VKD3D_SHADER_SPIRV_ENVIRONMENT_NONE,
    VKD3D_SHADER_SPIRV_ENVIRONMENT_OPENGL_4_5,
    VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0, /* default target */

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SPIRV_ENVIRONMENT),
};

enum vkd3d_shader_spirv_extension
{
    VKD3D_SHADER_SPIRV_EXTENSION_NONE,
    VKD3D_SHADER_SPIRV_EXTENSION_EXT_DEMOTE_TO_HELPER_INVOCATION,
    /** \since 1.3 */
    VKD3D_SHADER_SPIRV_EXTENSION_EXT_DESCRIPTOR_INDEXING,
    /** \since 1.3 */
    VKD3D_SHADER_SPIRV_EXTENSION_EXT_STENCIL_EXPORT,
    /** \since 1.11 */
    VKD3D_SHADER_SPIRV_EXTENSION_EXT_VIEWPORT_INDEX_LAYER,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SPIRV_EXTENSION),
};

/* Extends vkd3d_shader_compile_info. */
struct vkd3d_shader_spirv_target_info
{
    enum vkd3d_shader_structure_type type;
    const void *next;

    const char *entry_point; /* "main" if NULL. */

    enum vkd3d_shader_spirv_environment environment;

    const enum vkd3d_shader_spirv_extension *extensions;
    unsigned int extension_count;

    const struct vkd3d_shader_parameter *parameters;
    unsigned int parameter_count;

    bool dual_source_blending;
    const unsigned int *output_swizzles;
    unsigned int output_swizzle_count;
};

enum vkd3d_shader_tessellator_output_primitive
{
    VKD3D_SHADER_TESSELLATOR_OUTPUT_POINT        = 0x1,
    VKD3D_SHADER_TESSELLATOR_OUTPUT_LINE         = 0x2,
    VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CW  = 0x3,
    VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CCW = 0x4,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TESSELLATOR_OUTPUT_PRIMITIVE),
};

enum vkd3d_shader_tessellator_partitioning
{
    VKD3D_SHADER_TESSELLATOR_PARTITIONING_INTEGER         = 0x1,
    VKD3D_SHADER_TESSELLATOR_PARTITIONING_POW2            = 0x2,
    VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD  = 0x3,
    VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 0x4,

    VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TESSELLATOR_PARTITIONING),
};

/* Extends vkd3d_shader_spirv_target_info. */
struct vkd3d_shader_spirv_domain_shader_target_info
{
    enum vkd3d_shader_structure_type type;
    const void *next;

    enum vkd3d_shader_tessellator_output_primitive output_primitive;
    enum vkd3d_shader_tessellator_partitioning partitioning;
};

/**
 * A single preprocessor macro, passed as part of struct
 * vkd3d_shader_preprocess_info.
 */
struct vkd3d_shader_macro
{
    /**
     * Pointer to a null-terminated string containing the name of a macro. This
     * macro must not be a parameterized (i.e. function-like) macro. If this
     * field is not a valid macro identifier, this macro will be ignored.
     */
    const char *name;
    /**
     * Optional pointer to a null-terminated string containing the expansion of
     * the macro. This field may be set to NULL, in which case the macro has an
     * empty expansion.
     */
    const char *value;
};

/**
 * Type of a callback function which will be used to open preprocessor includes.
 *
 * This callback function is passed as part of struct
 * vkd3d_shader_preprocess_info.
 *
 * If this function fails, vkd3d-shader will emit a compilation error, and the
 * \a pfn_close_include callback will not be called.
 *
 * \param filename Unquoted string used as an argument to the \#include
 * directive.
 *
 * \param local Whether the \#include directive is requesting a local (i.e.
 * double-quoted) or system (i.e. angle-bracketed) include.
 *
 * \param parent_data Unprocessed source code of the file in which this
 * \#include directive is evaluated. This parameter may be NULL.
 *
 * \param context The user-defined pointer passed to struct
 * vkd3d_shader_preprocess_info.
 *
 * \param out Output location for the full contents of the included file. The
 * code need not be allocated using standard vkd3d functions, but must remain
 * valid until the corresponding call to \a pfn_close_include. If this function
 * fails, the contents of this parameter are ignored.
 *
 * \return A member of \ref vkd3d_result.
 */
typedef int (*PFN_vkd3d_shader_open_include)(const char *filename, bool local,
        const char *parent_data, void *context, struct vkd3d_shader_code *out);
/**
 * Type of a callback function which will be used to close preprocessor
 * includes.
 *
 * This callback function is passed as part of struct
 * vkd3d_shader_preprocess_info.
 *