/* * Copyright (C) 2021 Patrick Mours * SPDX-License-Identifier: BSD-3-Clause OR MIT */ #pragma once #define RESHADE_DEFINE_HANDLE(name) \ typedef struct { uint64_t handle; } name; \ constexpr bool operator< (name lhs, name rhs) { return lhs.handle < rhs.handle; } \ constexpr bool operator!=(name lhs, name rhs) { return lhs.handle != rhs.handle; } \ constexpr bool operator!=(name lhs, uint64_t rhs) { return lhs.handle != rhs; } \ constexpr bool operator==(name lhs, name rhs) { return lhs.handle == rhs.handle; } \ constexpr bool operator==(name lhs, uint64_t rhs) { return lhs.handle == rhs; } #define RESHADE_DEFINE_ENUM_FLAG_OPERATORS(type) \ constexpr type operator~(type a) { return static_cast(~static_cast(a)); } \ inline type &operator&=(type &a, type b) { return reinterpret_cast(reinterpret_cast(a) &= static_cast(b)); } \ constexpr type operator&(type a, type b) { return static_cast(static_cast(a) & static_cast(b)); } \ inline type &operator|=(type &a, type b) { return reinterpret_cast(reinterpret_cast(a) |= static_cast(b)); } \ constexpr type operator|(type a, type b) { return static_cast(static_cast(a) | static_cast(b)); } \ inline type &operator^=(type &a, type b) { return reinterpret_cast(reinterpret_cast(a) ^= static_cast(b)); } \ constexpr type operator^(type a, type b) { return static_cast(static_cast(a) ^ static_cast(b)); } \ constexpr bool operator==(type lhs, uint32_t rhs) { return static_cast(lhs) == rhs; } \ constexpr bool operator!=(type lhs, uint32_t rhs) { return static_cast(lhs) != rhs; } #include "reshade_api_format.hpp" namespace reshade { namespace api { /// /// Comparison operations. /// enum class compare_op : uint32_t { never = 0, less = 1, equal = 2, less_equal = 3, greater = 4, not_equal = 5, greater_equal = 6, always = 7 }; /// /// Texture filtering modes available for texture sampling operations. /// enum class filter_mode : uint32_t { min_mag_mip_point = 0, min_mag_point_mip_linear = 0x1, min_point_mag_linear_mip_point = 0x4, min_point_mag_mip_linear = 0x5, min_linear_mag_mip_point = 0x10, min_linear_mag_point_mip_linear = 0x11, min_mag_linear_mip_point = 0x14, min_mag_mip_linear = 0x15, min_mag_anisotropic_mip_point = 0x54, anisotropic = 0x55, compare_min_mag_mip_point = 0x80, compare_min_mag_point_mip_linear = 0x81, compare_min_point_mag_linear_mip_point = 0x84, compare_min_point_mag_mip_linear = 0x85, compare_min_linear_mag_mip_point = 0x90, compare_min_linear_mag_point_mip_linear = 0x91, compare_min_mag_linear_mip_point = 0x94, compare_min_mag_mip_linear = 0x95, compare_min_mag_anisotropic_mip_point = 0xd4, compare_anisotropic = 0xd5 }; /// /// Sampling behavior at texture coordinates outside the bounds of a texture resource. /// enum class texture_address_mode : uint32_t { wrap = 1, mirror = 2, clamp = 3, border = 4, mirror_once = 5 }; /// /// Describes a sampler state. /// struct sampler_desc { /// /// Filtering mode to use when sampling a texture. /// filter_mode filter = filter_mode::min_mag_mip_linear; /// /// Method to use for resolving U texture coordinates outside 0 to 1 range. /// texture_address_mode address_u = texture_address_mode::clamp; /// /// Method to use for resolving V texture coordinates outside 0 to 1 range. /// texture_address_mode address_v = texture_address_mode::clamp; /// /// Method to use for resolving W texture coordinates outside 0 to 1 range. /// texture_address_mode address_w = texture_address_mode::clamp; /// /// Offset applied to the calculated mipmap level when sampling a texture. /// float mip_lod_bias = 0.0f; /// /// Clamping value to use when filtering mode is . /// float max_anisotropy = 1.0f; /// /// Comparison function to use to compare sampled data against existing sampled data. /// compare_op compare_op = compare_op::never; /// /// RGBA value to return for texture coordinates outside 0 to 1 range when addressing mode is . /// float border_color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; /// /// Lower end of the mipmap range to clamp access to. /// float min_lod = -FLT_MAX; /// /// Upper end of the mipmap range to clamp access to. /// float max_lod = +FLT_MAX; }; /// /// An opaque handle to a sampler state object. /// /// Depending on the graphics API this can be: /// /// Direct3D 9: An opaque value. /// Direct3D 10: A pointer to a 'ID3D10SamplerState' object. /// Direct3D 11: A pointer to a 'ID3D11SamplerState' object. /// Direct3D 12: A 'D3D12_CPU_DESCRIPTOR_HANDLE' (to a sampler descriptor). /// OpenGL: An OpenGL sampler object name. /// Vulkan: A 'VkSampler' handle. /// /// /// RESHADE_DEFINE_HANDLE(sampler); /// /// Memory mapping access types. /// enum class map_access { read_only = 1, write_only, read_write, write_discard }; /// /// Memory heap types, which give a hint as to where to place the allocation for a resource. /// enum class memory_heap : uint32_t { unknown, // Usually indicates a resource that is reserved, but not yet bound to any memory. gpu_only, // Upload heap cpu_to_gpu, // Readback heap gpu_to_cpu, cpu_only, custom }; /// /// Type of a resource. This is specified during creation and is immutable. /// Various operations may have special requirements on the type of resources they operate on (e.g. copies can only happen between resources of the same type, ...). /// enum class resource_type : uint32_t { unknown, buffer, texture_1d, texture_2d, texture_3d, surface // Special type for resources that are implicitly both resource and render target view. }; /// /// Flags that specify additional parameters of a resource. /// enum class resource_flags : uint32_t { none = 0, /// /// Dynamic resources can be frequently updated during a frame, with previous contents automatically being shadowed so to no affect already executing operations on the GPU. /// Required for . The flag is not supported in D3D12 or Vulkan. /// dynamic = (1 << 3), /// /// Required to create or views of the resource. /// cube_compatible = (1 << 2), /// /// Required to use the resource with . /// generate_mipmaps = (1 << 0), /// /// Shared resources can be imported/exported from/to different graphics APIs and/or processes. /// Required to use the "shared_handle" parameter of . /// shared = (1 << 1), shared_nt_handle = (1 << 11), /// /// Resource is backed using sparse memory binding. /// sparse_binding = (1 << 18), }; RESHADE_DEFINE_ENUM_FLAG_OPERATORS(resource_flags); /// /// Flags that specify how a resource is used. /// This needs to be specified during creation and is also used to transition between different resource states within a command list. /// enum class resource_usage : uint32_t { undefined = 0, index_buffer = 0x2, vertex_buffer = 0x1, constant_buffer = 0x8000, stream_output = 0x100, indirect_argument = 0x200, depth_stencil = 0x30, depth_stencil_read = 0x20, depth_stencil_write = 0x10, render_target = 0x4, shader_resource = 0xC0, shader_resource_pixel = 0x80, shader_resource_non_pixel = 0x40, unordered_access = 0x8, copy_dest = 0x400, copy_source = 0x800, resolve_dest = 0x1000, resolve_source = 0x2000, acceleration_structure = 0x400000, // The following are special resource states and may only be used in barriers: general = 0x80000000, present = 0x80000000 | render_target | copy_source, cpu_access = vertex_buffer | index_buffer | shader_resource | indirect_argument | copy_source }; RESHADE_DEFINE_ENUM_FLAG_OPERATORS(resource_usage); /// /// Describes a resource, such as a buffer or texture. /// struct [[nodiscard]] resource_desc { constexpr resource_desc() : texture({ 0, 0, 0, 0, format::unknown, 0 }) {} constexpr resource_desc(uint64_t size, memory_heap heap, resource_usage usage, resource_flags flags = resource_flags::none) : type(resource_type::buffer), buffer({ size }), heap(heap), usage(usage), flags(flags) {} constexpr resource_desc(uint32_t width, uint32_t height, uint16_t layers, uint16_t levels, format format, uint16_t samples, memory_heap heap, resource_usage usage, resource_flags flags = resource_flags::none) : type(resource_type::texture_2d), texture({ width, height, layers, levels, format, samples }), heap(heap), usage(usage), flags(flags) {} constexpr resource_desc(resource_type type, uint32_t width, uint32_t height, uint16_t depth_or_layers, uint16_t levels, format format, uint16_t samples, memory_heap heap, resource_usage usage, resource_flags flags = resource_flags::none) : type(type), texture({ width, height, depth_or_layers, levels, format, samples }), heap(heap), usage(usage), flags(flags) {} /// /// Type of the resource. /// resource_type type = resource_type::unknown; union { /// /// Used when resource type is a buffer. /// struct { /// /// Size of the buffer (in bytes). /// uint64_t size = 0; /// /// Structure stride for structured buffers (in bytes), otherwise zero. /// uint32_t stride = 0; } buffer; /// /// Used when resource type is a texture or surface. /// struct { /// /// Width of the texture (in texels). /// uint32_t width = 1; /// /// If this is a 2D or 3D texture, height of the texture (in texels), otherwise 1. /// uint32_t height = 1; /// /// If this is a 3D texture, depth of the texture (in texels), otherwise number of array layers. /// uint16_t depth_or_layers = 1; /// /// Maximum number of mipmap levels in the texture, including the base level, so at least 1. /// Can also be zero in case the exact number of mipmap levels is unknown. /// uint16_t levels = 1; /// /// Data format of each texel in the texture. /// format format = format::unknown; /// /// The number of samples per texel. Set to a value higher than 1 for multisampling. /// uint16_t samples = 1; } texture; }; /// /// Memory heap the resource allocation is placed in. /// memory_heap heap = memory_heap::unknown; /// /// Flags that specify how this resource is used. /// This should contain all resource states the resource will ever be transitioned to (including the initial state specified for resource creation). /// resource_usage usage = resource_usage::undefined; /// /// Flags that specify additional parameters. /// resource_flags flags = resource_flags::none; }; /// /// An opaque handle to a resource object (buffer, texture, ...). /// Resources created by the application are only guaranteed to be valid during event callbacks. /// /// Depending on the graphics API this can be: /// /// Direct3D 9: A pointer to a 'IDirect3DResource9' object. /// Direct3D 10: A pointer to a 'ID3D10Resource' object. /// Direct3D 11: A pointer to a 'ID3D11Resource' object. /// Direct3D 12: A pointer to a 'ID3D12Resource' object. /// OpenGL: The upper 24-bit contain the OpenGL object type (like GL_BUFFER, GL_TEXTURE_2D, GL_RENDERBUFFER, ...), the lower 32-bit contain the OpenGL object name. So the object type can be extracted with (handle >> 40), the object with (handle & 0xFFFFFFFF). /// Vulkan: A 'VkImage' handle. /// /// /// RESHADE_DEFINE_HANDLE(resource); /// /// Type of a resource view. This identifies how a resource view interprets the data of its resource. /// enum class resource_view_type : uint32_t { unknown, buffer, texture_1d, texture_1d_array, texture_2d, texture_2d_array, texture_2d_multisample, texture_2d_multisample_array, texture_3d, texture_cube, texture_cube_array, acceleration_structure }; /// /// Describes a resource view, which specifies how to interpret the data of a resource. /// struct [[nodiscard]] resource_view_desc { constexpr resource_view_desc() : texture({ 0, 0, 0, 0 }) {} constexpr resource_view_desc(format format, uint64_t offset, uint64_t size) : type(resource_view_type::buffer), format(format), buffer({ offset, size }) {} constexpr resource_view_desc(format format, uint32_t first_level, uint32_t levels, uint32_t first_layer, uint32_t layers) : type(resource_view_type::texture_2d), format(format), texture({ first_level, levels, first_layer, layers }) {} constexpr resource_view_desc(resource_view_type type, format format, uint64_t offset, uint64_t size) : type(type), format(format), buffer({ offset, size }) {} constexpr resource_view_desc(resource_view_type type, format format, uint32_t first_level, uint32_t levels, uint32_t first_layer, uint32_t layers) : type(type), format(format), texture({ first_level, levels, first_layer, layers }) {} constexpr explicit resource_view_desc(format format) : type(resource_view_type::texture_2d), format(format), texture({ 0, 1, 0, 1 }) {} /// /// Resource type the view should interpret the resource data to. /// resource_view_type type = resource_view_type::unknown; /// /// Format the view should reinterpret the resource data to (can be different than the format of the resource as long as they are compatible). /// format format = format::unknown; union { /// /// Used when view type is a buffer or acceleration structure. /// struct { /// /// Offset from the start of the buffer resource (in bytes). /// uint64_t offset = 0; /// /// Number of elements this view covers in the buffer resource (in bytes). /// Set to -1 (UINT64_MAX) to indicate that the entire buffer resource should be used. /// uint64_t size = UINT64_MAX; } buffer; /// /// Used when view type is a texture. /// struct { /// /// Index of the most detailed mipmap level to use. This number has to be between zero and the maximum number of mipmap levels in the texture minus 1. /// uint32_t first_level = 0; /// /// Maximum number of mipmap levels for the view of the texture. /// Set to -1 (UINT32_MAX) to indicate that all mipmap levels down to the least detailed should be used. /// uint32_t level_count = UINT32_MAX; /// /// Index of the first array layer of the texture array to use. This value is ignored if the texture is not layered. /// uint32_t first_layer = 0; /// /// Maximum number of array layers for the view of the texture array. This value is ignored if the texture is not layered. /// Set to -1 (UINT32_MAX) to indicate that all array layers should be used. /// uint32_t layer_count = UINT32_MAX; } texture; }; }; /// /// An opaque handle to a resource view object (depth-stencil, render target, shader resource view, ...). /// Resource views created by the application are only guaranteed to be valid during event callbacks. /// /// Depending on the graphics API this can be: /// /// Direct3D 9: A pointer to a 'IDirect3DResource9' object. /// Direct3D 10: A pointer to a 'ID3D10View' object. /// Direct3D 11: A pointer to a 'ID3D11View' object. /// Direct3D 12: A 'D3D12_CPU_DESCRIPTOR_HANDLE' (to a view descriptor) or 'D3D12_GPU_VIRTUAL_ADDRESS' (to an acceleration structrue). /// OpenGL: The upper 24-bit contain the OpenGL object type (like GL_TEXTURE_BUFFER, GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP_POSITIVE_X, ...), the lower 32-bit contain the OpenGL object ID. So the object type can be extracted with (handle >> 40), the object with (handle & 0xFFFFFFFF). /// Vulkan: A 'VkImageView' or 'VkAccelerationStructureKHR' handle. /// /// /// RESHADE_DEFINE_HANDLE(resource_view); /// /// Describes a region inside a subresource. /// struct subresource_box { uint32_t left = 0; uint32_t top = 0; uint32_t front = 0; uint32_t right = 0; uint32_t bottom = 0; uint32_t back = 0; constexpr uint32_t width() const { return right - left; } constexpr uint32_t height() const { return bottom - top; } constexpr uint32_t depth() const { return back - front; } }; /// /// Describes the data of a subresource. /// struct subresource_data { /// /// Pointer to the data. /// void *data = nullptr; /// /// Row pitch of the data (added to the data pointer to move between texture rows, unused for buffers and 1D textures). /// /// uint32_t row_pitch = 0; /// /// Depth pitch of the data (added to the data pointer to move between texture depth/array slices, unused for buffers and 1D/2D textures). /// /// uint32_t slice_pitch = 0; }; /// /// Specifies how the contents of a render target or depth-stencil view are treated at the start of a render pass. /// enum class render_pass_load_op : uint32_t { load, clear, discard, no_access }; /// /// Specifies how the contents of a render target or depth-stencil view are treated at the end of a render pass. /// enum class render_pass_store_op : uint32_t { store, discard, no_access }; /// /// Describes a depth-stencil view and how it is treated at the start and end of a render pass. /// struct render_pass_depth_stencil_desc { /// /// Depth-stencil resource view. /// resource_view view = { 0 }; /// /// Specifies how the depth contents of the depth-stencil view are treated at the start of the render pass. /// render_pass_load_op depth_load_op = render_pass_load_op::load; /// /// Specifies how the depth contents of the depth-stencil view are treated at the end of the render pass. /// render_pass_store_op depth_store_op = render_pass_store_op::store; /// /// Specifies how the stencil contents of the depth-stencil view are treated at the start of the render pass. /// render_pass_load_op stencil_load_op = render_pass_load_op::load; /// /// Specifies how the stencil contents of the depth-stencil view are treated at the end of the render pass. /// render_pass_store_op stencil_store_op = render_pass_store_op::store; /// /// Value the depth contents of the depth-stencil resource is cleared to when is . /// float clear_depth = 0.0f; /// /// Value the stencil contents of the depth-stencil resource is cleared to when is . /// uint8_t clear_stencil = 0; }; /// /// Describes a render target view and how it is treated at the start and end of a render pass. /// struct render_pass_render_target_desc { /// /// Render target resource view. /// resource_view view = { 0 }; /// /// Specifies how the contents of the render target view are treated at the start of the render pass. /// render_pass_load_op load_op = render_pass_load_op::load; /// /// Specifies how the contents of the render target view are treated at the end of the render pass. /// render_pass_store_op store_op = render_pass_store_op::store; /// /// Value the render target resource is cleared to when is . /// float clear_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; }; /// /// Type of an acceleration structure. /// enum class acceleration_structure_type { top_level = 0, bottom_level = 1, generic = 2 }; /// /// Type of an acceleration structure copy operation. /// enum class acceleration_structure_copy_mode { clone = 0, compact = 1, serialize = 2, deserialize = 3 }; /// /// Type of an acceleration structure build operation. /// enum class acceleration_structure_build_mode { build = 0, update = 1 }; /// /// Flags that specify additional parameters to an acceleration structure build operation. /// enum class acceleration_structure_build_flags : uint32_t { none = 0, allow_update = (1 << 0), allow_compaction = (1 << 1), prefer_fast_trace = (1 << 2), prefer_fast_build = (1 << 3), minimize_memory_usage = (1 << 4) }; RESHADE_DEFINE_ENUM_FLAG_OPERATORS(acceleration_structure_build_flags); /// /// Type of an acceleration structure structure build input. /// enum class acceleration_structure_build_input_type : uint32_t { triangles = 0, aabbs = 1, instances = 2 }; /// /// Flags that specify additional parameters of an acceleration structure build input. /// enum class acceleration_structure_build_input_flags : uint32_t { none = 0, opaque = (1 << 0), no_duplicate_any_hit_invocation = (1 << 1) }; RESHADE_DEFINE_ENUM_FLAG_OPERATORS(acceleration_structure_build_input_flags); /// /// Describes a single instance in a top-level acceleration structure. /// The data in should be an array of this structure. /// struct acceleration_structure_instance { float transform[3][4]; uint32_t custom_index : 24; uint32_t mask : 8; uint32_t shader_binding_table_offset : 24; uint32_t flags : 8; uint64_t acceleration_structure_gpu_address; }; /// /// Describes a build input for an acceleration structure build operation. /// struct acceleration_structure_build_input { constexpr acceleration_structure_build_input() : triangles() {} constexpr acceleration_structure_build_input(api::resource vertex_buffer, uint64_t vertex_offset, uint32_t vertex_count, uint64_t vertex_stride, api::format vertex_format, api::resource index_buffer, uint64_t index_offset, uint32_t index_count, api::format index_format, uint64_t transform_address = 0) : type(acceleration_structure_build_input_type::triangles), triangles({ vertex_buffer, vertex_offset, vertex_count, vertex_stride, vertex_format, index_buffer, index_offset, index_count, index_format, transform_address }) {} constexpr acceleration_structure_build_input(api::resource aabb_buffer, uint64_t aabb_offset, uint32_t aabb_count, uint64_t aabb_stride) : type(acceleration_structure_build_input_type::aabbs), aabbs({ aabb_buffer, aabb_offset, aabb_count, aabb_stride }) {} constexpr acceleration_structure_build_input(api::resource instance_buffer, uint64_t instance_offset, uint32_t instance_count, bool array_of_pointers = false) : type(acceleration_structure_build_input_type::instances), instances({ instance_buffer, instance_offset, instance_count, array_of_pointers }) {} /// /// Type of the acceleration structure build input. /// acceleration_structure_build_input_type type = acceleration_structure_build_input_type::triangles; union { /// /// Used when build input type is . /// struct { api::resource vertex_buffer = {}; uint64_t vertex_offset = 0; uint32_t vertex_count = 0; uint64_t vertex_stride = 0; api::format vertex_format = api::format::unknown; api::resource index_buffer = {}; uint64_t index_offset = 0; uint32_t index_count = 0; api::format index_format = api::format::unknown; api::resource transform_buffer = {}; uint64_t transform_offset = 0; } triangles; /// /// Used when build input type is . /// struct { api::resource buffer = {}; uint64_t offset = 0; uint32_t count = 0; uint64_t stride = 0; } aabbs; /// /// Used when build input type is . /// struct { api::resource buffer = {}; uint64_t offset = 0; uint32_t count = 0; bool array_of_pointers = false; } instances; }; /// /// Flags that specify additional parameters. /// acceleration_structure_build_input_flags flags = acceleration_structure_build_input_flags::none; }; } }