/* * Copyright (C) 2021 Patrick Mours * SPDX-License-Identifier: BSD-3-Clause OR MIT */ #pragma once #include "reshade_api_resource.hpp" namespace reshade { namespace api { /// /// A list of flags that represent the available shader stages in the render pipeline. /// enum class shader_stage : uint32_t { vertex = 0x1, hull = 0x2, domain = 0x4, geometry = 0x8, pixel = 0x10, compute = 0x20, all = 0x7FFFFFFF, all_compute = compute, all_graphics = vertex | hull | domain | geometry | pixel }; RESHADE_DEFINE_ENUM_FLAG_OPERATORS(shader_stage); /// /// A list of flags that represent the available pipeline stages in the render pipeline. /// enum class pipeline_stage : uint32_t { vertex_shader = 0x8, hull_shader = 0x10, domain_shader = 0x20, geometry_shader = 0x40, pixel_shader = 0x80, compute_shader = 0x800, input_assembler = 0x2, stream_output = 0x4, rasterizer = 0x100, depth_stencil = 0x200, output_merger = 0x400, all = 0x7FFFFFFF, all_compute = compute_shader, all_graphics = vertex_shader | hull_shader | domain_shader | geometry_shader | pixel_shader | input_assembler | stream_output | rasterizer | depth_stencil | output_merger, all_shader_stages = vertex_shader | hull_shader | domain_shader | geometry_shader | pixel_shader | compute_shader }; RESHADE_DEFINE_ENUM_FLAG_OPERATORS(pipeline_stage); /// /// The available descriptor types. /// enum class descriptor_type : uint32_t { sampler = 0, sampler_with_resource_view = 1, shader_resource_view = 2, unordered_access_view = 3, constant_buffer = 6, shader_storage_buffer = 7 }; /// /// The available pipeline layout parameter types. /// enum class pipeline_layout_param_type : uint32_t { push_constants = 1, descriptor_table = 0, push_descriptors = 2, push_descriptors_with_ranges = 3 }; /// /// Describes a range of constants in a pipeline layout. /// struct constant_range { /// /// OpenGL uniform buffer binding index. /// uint32_t binding = 0; /// /// D3D10/D3D11/D3D12 constant buffer register index. /// uint32_t dx_register_index = 0; /// /// D3D12 constant buffer register space. /// uint32_t dx_register_space = 0; /// /// Number of constants in this range (in 32-bit values). /// uint32_t count = 0; /// /// Shader pipeline stages that can make use of the constants in this range. /// shader_stage visibility = shader_stage::all; }; /// /// Describes a range of descriptors of a descriptor table in a pipeline layout. /// struct descriptor_range { /// /// OpenGL/Vulkan binding index (layout(binding=X) in GLSL). /// In D3D this is equivalent to the offset (in descriptors) of this range in the descriptor table (since each binding can only have an array size of 1). /// uint32_t binding = 0; /// /// D3D9/D3D10/D3D11/D3D12 shader register index (register(xX) in HLSL). /// uint32_t dx_register_index = 0; /// /// D3D12 register space (register(..., spaceX) in HLSL). /// uint32_t dx_register_space = 0; /// /// Number of descriptors in this range. /// Set to -1 (UINT32_MAX) to indicate an unbounded range. /// uint32_t count = 0; /// /// Shader pipeline stages that can make use of the descriptors in this range. /// shader_stage visibility = shader_stage::all; /// /// Size of the array in case this is an array binding. /// Only meaningful in Vulkan, in OpenGL and other APIs this has to be 1 (since each array element is a separate binding there). /// If this is less than the total number of descriptors specified in , then the remaining descriptors are assigned a separate binding (with an array size of 1), with the binding index incrementing with each additional descriptor. /// uint32_t array_size = 1; /// /// Type of the descriptors in this range. /// descriptor_type type = descriptor_type::sampler; }; /// /// Describes a single parameter in a pipeline layout. /// struct pipeline_layout_param { constexpr pipeline_layout_param() : push_descriptors() {} constexpr pipeline_layout_param(const constant_range &push_constants) : type(pipeline_layout_param_type::push_constants), push_constants(push_constants) {} constexpr pipeline_layout_param(const descriptor_range &push_descriptors) : type(pipeline_layout_param_type::push_descriptors), push_descriptors(push_descriptors) {} constexpr pipeline_layout_param(uint32_t count, const descriptor_range *ranges) : type(pipeline_layout_param_type::descriptor_table), descriptor_table({ count, ranges }) {} /// /// Type of the parameter. /// pipeline_layout_param_type type = pipeline_layout_param_type::push_descriptors; union { /// /// Used when parameter type is . /// constant_range push_constants; /// /// Used when parameter type is . /// descriptor_range push_descriptors; /// /// Used when parameter type is or . /// struct { uint32_t count; const descriptor_range *ranges; } descriptor_table; }; }; /// /// An opaque handle to a pipeline layout object. /// In D3D12 this is a pointer to a 'ID3D12RootSignature' object, in Vulkan a 'VkPipelineLayout' handle. /// RESHADE_DEFINE_HANDLE(pipeline_layout); /// /// The fill mode to use when rendering triangles. /// enum class fill_mode : uint32_t { solid = 0, wireframe = 1, point = 2 }; /// /// Indicates triangles facing a particular direction are not drawn. /// enum class cull_mode : uint32_t { none = 0, front = 1, back = 2, front_and_back = front | back }; RESHADE_DEFINE_ENUM_FLAG_OPERATORS(cull_mode); /// /// The available logic operations. /// enum class logic_op : uint32_t { clear = 0, bitwise_and = 1, bitwise_and_reverse = 2, copy = 3, bitwise_and_inverted = 4, noop = 5, bitwise_xor = 6, bitwise_or = 7, bitwise_nor = 8, equivalent = 9, invert = 10, bitwise_or_reverse = 11, copy_inverted = 12, bitwise_or_inverted = 13, bitwise_nand = 14, set = 15 }; /// /// The available color or alpha blending operations. /// enum class blend_op : uint32_t { add = 0, subtract = 1, reverse_subtract = 2, min = 3, max = 4 }; /// /// The available blend factors in color or alpha blending operations. /// enum class blend_factor : uint32_t { zero = 0, one = 1, source_color = 2, one_minus_source_color = 3, dest_color = 4, one_minus_dest_color = 5, source_alpha = 6, one_minus_source_alpha = 7, dest_alpha = 8, one_minus_dest_alpha = 9, constant_color = 10, one_minus_constant_color = 11, constant_alpha = 12, one_minus_constant_alpha = 13, source_alpha_saturate = 14, source1_color = 15, one_minus_source1_color = 16, source1_alpha = 17, one_minus_source1_alpha = 18 }; /// /// The available stencil operations that can be performed during depth-stencil testing. /// enum class stencil_op : uint32_t { keep = 0, zero = 1, replace = 2, increment_saturate = 3, decrement_saturate = 4, invert = 5, increment = 6, decrement = 7 }; /// /// Specifies how the pipeline interprets vertex data that is bound to the vertex input stage and subsequently renders it. /// enum class primitive_topology : uint32_t { undefined = 0, point_list = 1, line_list = 2, line_strip = 3, triangle_list = 4, triangle_strip = 5, triangle_fan = 6, quad_list = 8, quad_strip = 9, line_list_adj = 10, line_strip_adj = 11, triangle_list_adj = 12, triangle_strip_adj = 13, patch_list_01_cp = 33, patch_list_02_cp, patch_list_03_cp, patch_list_04_cp, patch_list_05_cp, patch_list_06_cp, patch_list_07_cp, patch_list_08_cp, patch_list_09_cp, patch_list_10_cp, patch_list_11_cp, patch_list_12_cp, patch_list_13_cp, patch_list_14_cp, patch_list_15_cp, patch_list_16_cp, patch_list_17_cp, patch_list_18_cp, patch_list_19_cp, patch_list_20_cp, patch_list_21_cp, patch_list_22_cp, patch_list_23_cp, patch_list_24_cp, patch_list_25_cp, patch_list_26_cp, patch_list_27_cp, patch_list_28_cp, patch_list_29_cp, patch_list_30_cp, patch_list_31_cp, patch_list_32_cp }; /// /// Describes a shader object. /// struct shader_desc { /// /// Shader source code or binary. /// const void *code = nullptr; /// /// Size (in bytes) of the shader source or binary. /// size_t code_size = 0; /// /// Optional entry point name if the shader source or binary contains multiple entry points. /// Can be if it does not, or to use the default "main" entry point. /// const char *entry_point = nullptr; /// /// Number of entries in the and arrays. /// This is meaningful only when the shader binary is a SPIR-V module and is ignored otherwise. /// uint32_t spec_constants = 0; /// /// Pointer to an array of specialization constant indices. /// const uint32_t *spec_constant_ids = nullptr; /// /// Pointer to an array of constant values, one for each specialization constant index in . /// const uint32_t *spec_constant_values = nullptr; }; /// /// Describes a single element in the vertex layout for the input-assembler stage. /// struct input_element { /// /// GLSL attribute location associated with this element (layout(location = X)). /// uint32_t location = 0; /// /// HLSL semantic associated with this element. /// const char *semantic = nullptr; /// /// Optional index for the HLSL semantic (e.g. for "TEXCOORD1" set to "TEXCOORD" and to 1). /// uint32_t semantic_index = 0; /// /// Format of the element data. /// format format = format::unknown; /// /// Index of the vertex buffer binding. /// uint32_t buffer_binding = 0; /// /// Offset (in bytes) from the start of the vertex to this element. /// uint32_t offset = 0; /// /// Stride of the entire vertex (this has to be consistent for all elements per vertex buffer binding). /// Set to zero in case this is unknown. /// uint32_t stride = 0; /// /// Number of instances to draw using the same per-instance data before advancing by one element. /// This has to be consistent for all elements per vertex buffer binding. /// Set to zero to indicate that this element is per-vertex rather than per-instance. /// uint32_t instance_step_rate = 0; }; /// /// Describes the state of the stream-output stage. /// struct stream_output_desc { /// /// Index of the stream output stream to be sent to the rasterizer stage. /// uint32_t rasterized_stream = 0; }; /// /// Describes the state of the output-merger stage. /// struct blend_desc { /// /// Use alpha-to-coverage as a multisampling technique when setting a pixel to a render target. /// bool alpha_to_coverage_enable = false; /// /// Enable or disable blending for each render target. /// /// bool blend_enable[8] = { false, false, false, false, false, false, false, false }; /// /// Enable or disable a logical operation for each render target. /// /// bool logic_op_enable[8] = { false, false, false, false, false, false, false, false }; /// /// Source to use for the RGB value that the pixel shader outputs. /// /// blend_factor source_color_blend_factor[8] = { blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one }; /// /// Destination to use for the current RGB value in the render target. /// /// blend_factor dest_color_blend_factor[8] = { blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero }; /// /// Operation to use to combine and . /// /// blend_op color_blend_op[8] = { blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add }; /// /// Source to use for the alpha value that the pixel shader outputs. /// /// blend_factor source_alpha_blend_factor[8] = { blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one }; /// /// Destination to use for the current alpha value in the render target. /// /// blend_factor dest_alpha_blend_factor[8] = { blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero }; /// /// Operation to use to combine and . /// /// blend_op alpha_blend_op[8] = { blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add }; /// /// Constant RGBA value to use when or is . /// float blend_constant[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; /// /// Logical operation for each render target. Ignored if is . /// /// logic_op logic_op[8] = { logic_op::noop, logic_op::noop, logic_op::noop, logic_op::noop, logic_op::noop, logic_op::noop, logic_op::noop, logic_op::noop }; /// /// A write mask specifying which color components are written to each render target. Bitwise combination of 0x1 for red, 0x2 for green, 0x4 for blue and 0x8 for alpha. /// uint8_t render_target_write_mask[8] = { 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF }; }; /// /// Describes the state of the rasterizer stage. /// struct rasterizer_desc { /// /// Fill mode to use when rendering triangles. /// /// fill_mode fill_mode = fill_mode::solid; /// /// Triangles facing the specified direction are not drawn. /// cull_mode cull_mode = cull_mode::back; /// /// Determines if a triangle is front or back-facing. /// bool front_counter_clockwise = false; /// /// Depth value added to a given pixel. /// float depth_bias = 0.0f; /// /// Maximum depth bias of a pixel. /// float depth_bias_clamp = 0.0f; /// /// Scalar on the slope of a given pixel. /// float slope_scaled_depth_bias = 0.0f; /// /// Enable or disable clipping based on distance. /// bool depth_clip_enable = true; /// /// Enable or disable scissor testing (scissor rectangle culling). /// bool scissor_enable = false; /// /// Use the quadrilateral or alpha line anti-aliasing algorithm on multisample antialiasing render targets. /// bool multisample_enable = false; /// /// Enable or disable line antialiasing. Only applies if doing line drawing and is . /// bool antialiased_line_enable = false; /// /// Enable or disable conservative rasterization mode. /// /// uint32_t conservative_rasterization = 0; }; /// /// Describes the state of the depth-stencil stage. /// struct depth_stencil_desc { /// /// Enable or disable depth testing. /// bool depth_enable = true; /// /// Enable or disable writes to the depth-stencil buffer. /// bool depth_write_mask = true; /// /// Comparison function to use to compare new depth value from a fragment against current depth value in the depth-stencil buffer. /// compare_op depth_func = compare_op::less; /// /// Enable or disable stencil testing. /// bool stencil_enable = false; /// /// Mask applied to stencil values read from the depth-stencil buffer for pixels whose surface normal is towards the camera. /// uint8_t front_stencil_read_mask = 0xFF; /// /// Mask applied to stencil values written to the depth-stencil buffer for pixels whose surface normal is towards the camera. /// uint8_t front_stencil_write_mask = 0xFF; /// /// Reference value to perform against when stencil testing pixels whose surface normal is towards the camera. /// uint8_t front_stencil_reference_value = 0; /// /// Comparison function to use to compare new stencil value from a fragment against current stencil value for pixels whose surface normal is facing towards the camera. /// compare_op front_stencil_func = compare_op::always; /// /// Stencil operation to perform when stencil testing and depth testing both pass for pixels whose surface normal is facing towards the camera. /// stencil_op front_stencil_pass_op = stencil_op::keep; /// /// Stencil operation to perform when stencil testing fails for pixels whose surface normal is towards the camera. /// stencil_op front_stencil_fail_op = stencil_op::keep; /// /// Stencil operation to perform when stencil testing passes and depth testing fails for pixels whose surface normal is facing towards the camera. /// stencil_op front_stencil_depth_fail_op = stencil_op::keep; /// /// Mask applied to stencil values read from the depth-stencil buffer for pixels whose surface normal is facing away from the camera. /// uint8_t back_stencil_read_mask = 0xFF; /// /// Mask applied to stencil values written to the depth-stencil buffer for pixels whose surface normal is facing away from the camera. /// uint8_t back_stencil_write_mask = 0xFF; /// /// Reference value to perform against when stencil testing pixels whose surface normal is facing away from the camera. /// uint8_t back_stencil_reference_value = 0; /// /// Comparison function to use to compare new stencil value from a fragment against current stencil value for pixels whose surface normal is facing away from the camera. /// compare_op back_stencil_func = compare_op::always; /// /// Stencil operation to perform when stencil testing and depth testing both pass for pixels whose surface normal is facing away from the camera. /// stencil_op back_stencil_pass_op = stencil_op::keep; /// /// Stencil operation to perform when stencil testing fails for pixels whose surface normal is facing away from the camera. /// stencil_op back_stencil_fail_op = stencil_op::keep; /// /// Stencil operation to perform when stencil testing passes and depth testing fails for pixels whose surface normal is facing away from the camera. /// stencil_op back_stencil_depth_fail_op = stencil_op::keep; }; /// /// The available pipeline sub-object types. /// enum class pipeline_subobject_type : uint32_t { unknown, /// /// Vertex shader to use. /// Sub-object data is a pointer to a . /// /// /// vertex_shader, /// /// Hull shader to use. /// Sub-object data is a pointer to a . /// /// /// hull_shader, /// /// Domain shader to use. /// Sub-object data is a pointer to a . /// /// /// domain_shader, /// /// Geometry shader to use. /// Sub-object data is a pointer to a . /// /// /// geometry_shader, /// /// Pixel shader to use. /// Sub-object data is a pointer to a . /// /// /// pixel_shader, /// /// Compute shader to use. /// Sub-object data is a pointer to a . /// /// /// compute_shader, /// /// Vertex layout for the input-assembler stage. /// Sub-object data is a pointer to an array of . /// /// input_layout, /// /// State of the stream-output stage. /// Sub-object data is a pointer to a . /// /// stream_output_state, /// /// State of the output-merger stage. /// Sub-object data is a pointer to a . /// /// blend_state, /// /// State of the rasterizer stage. /// Sub-object data is a pointer to a . /// /// rasterizer_state, /// /// State of the depth-stencil stage. /// Sub-object data is a pointer to a . /// /// depth_stencil_state, /// /// Primitive topology to use when rendering. /// Sub-object data is a pointer to a value. /// primitive_topology, /// /// Format of the depth-stencil view that may be used with this pipeline. /// Sub-object data is a pointer to a value. /// depth_stencil_format, /// /// Formats of the render target views that may be used with this pipeline. /// Sub-object data is a pointer to an array of values. /// render_target_formats, /// /// Mask applied to the coverage mask for a fragment during rasterization. /// Sub-object data is a pointer to a 32-bit unsigned integer value. /// sample_mask, /// /// Number of samples used in rasterization. /// Sub-object data is a pointer to a 32-bit unsigned integer value. /// sample_count, /// /// Maximum number of viewports that may be bound via with this pipeline. /// Sub-object data is a pointer to a 32-bit unsigned integer value. /// viewport_count, /// /// States that may be dynamically updated via after binding this pipeline. /// Sub-object data is a pointer to an array of values. /// dynamic_pipeline_states, /// /// Maximum number of vertices a draw call with this pipeline will draw. /// Sub-object data is a pointer to a 32-bit unsigned integer value. /// max_vertex_count }; /// /// Describes a pipeline sub-object. /// struct pipeline_subobject { /// /// Type of the specified sub-object . /// pipeline_subobject_type type = pipeline_subobject_type::unknown; /// /// Number of sub-object descriptions. /// This should usually be 1, except for array sub-objects like (where this specifies the number of render targets) or . /// uint32_t count = 0; /// /// Pointer to an array of sub-object descriptions (which should be as large as the specified ). /// Depending on the sub-object this should be a pointer to a , , , or ... /// void *data = nullptr; }; /// /// An opaque handle to a pipeline state object. /// In D3D9, D3D10, D3D11 or D3D12 this is a pointer to a 'IDirect3D(...)Shader', 'ID3D10(...)(Shader/State)', 'ID3D11(...)(Shader/State)' or 'ID3D12PipelineState' object, in Vulkan a 'VkPipeline' handle. /// RESHADE_DEFINE_HANDLE(pipeline); /// /// A constant buffer resource descriptor. /// struct buffer_range { /// /// Constant buffer resource. /// resource buffer = { 0 }; /// /// Offset from the start of the buffer resource (in bytes). /// uint64_t offset = 0; /// /// Number of elements this range covers in the buffer resource (in bytes). /// Set to -1 (UINT64_MAX) to indicate that the whole buffer should be used. /// uint64_t size = UINT64_MAX; }; /// /// A combined sampler and resource view descriptor. /// struct sampler_with_resource_view { /// /// Sampler to sampler the shader resource view with. /// sampler sampler = { 0 }; /// /// Shader resource view. /// resource_view view = { 0 }; }; /// /// An opaque handle to a descriptor table in a descriptor heap. /// In Vulkan this is a 'VkDescriptorSet' handle. /// RESHADE_DEFINE_HANDLE(descriptor_table); /// /// All information needed to copy descriptors between descriptor tables. /// struct descriptor_table_copy { /// /// Descriptor table to copy from. /// descriptor_table source_table = { 0 }; /// /// Index of the binding in the source descriptor table. /// uint32_t source_binding = 0; /// /// Array index in the specified source binding to begin copying from. /// uint32_t source_array_offset = 0; /// /// Descriptor table to copy to. /// descriptor_table dest_table = { 0 }; /// /// Index of the binding in the destination descriptor table. /// uint32_t dest_binding = 0; /// /// Array index in the specified destination binding to begin copying to. /// uint32_t dest_array_offset = 0; /// /// Number of descriptors to copy. /// uint32_t count = 0; }; /// /// All information needed to update descriptors in a descriptor table. /// struct descriptor_table_update { /// /// Descriptor table to update. /// descriptor_table table = { 0 }; /// /// OpenGL/Vulkan binding index in the descriptor set. /// In D3D this is equivalent to the offset (in descriptors) from the start of the table. /// uint32_t binding = 0; /// /// Array index in the specified to begin updating at. /// Only meaningful in Vulkan, in OpenGL and other APIs this has to be 0 (since each array element gets a separate binding). /// uint32_t array_offset = 0; /// /// Number of descriptors to update, starting at the specified . /// If the specified has fewer than array elements starting from , then the remainder will be used to update the subsequent binding starting at array element zero, recursively. /// uint32_t count = 0; /// /// Type of the specified . /// descriptor_type type = descriptor_type::sampler; /// /// Pointer to an array of descriptors to update in the descriptor table (which should be as large as the specified ). /// Depending on the descriptor this should be pointer to an array of , , or . /// const void *descriptors = nullptr; }; /// /// An opaque handle to a descriptor heap. /// In D3D12 this is a pointer to a 'ID3D12DescriptorHeap' object, in Vulkan a 'VkDescriptorPool' handle. /// RESHADE_DEFINE_HANDLE(descriptor_heap); /// /// The available query types. /// enum class query_type { occlusion = 0, binary_occlusion = 1, timestamp = 2, pipeline_statistics = 3, stream_output_statistics_0 = 4, stream_output_statistics_1, stream_output_statistics_2, stream_output_statistics_3 }; /// /// An opaque handle to a query heap. /// In D3D12 this is a pointer to a 'ID3D12QueryHeap' object, in Vulkan a 'VkQueryPool' handle. /// RESHADE_DEFINE_HANDLE(query_heap); /// /// A list of all possible render pipeline states that can be set independent of pipeline state objects. /// Support for these varies between render APIs (e.g. modern APIs like D3D12 and Vulkan support much less dynamic states than D3D9). /// enum class dynamic_state { unknown = 0, alpha_test_enable = 15, alpha_reference_value = 24, alpha_func = 25, srgb_write_enable = 194, primitive_topology = 1000, sample_mask = 162, // Blend state alpha_to_coverage_enable = 1003, blend_enable = 27, logic_op_enable = 1004, source_color_blend_factor = 19, dest_color_blend_factor = 20, color_blend_op = 171, source_alpha_blend_factor = 207, dest_alpha_blend_factor = 208, alpha_blend_op = 209, blend_constant = 193, logic_op = 1005, render_target_write_mask = 168, // Rasterizer state fill_mode = 8, cull_mode = 22, front_counter_clockwise = 1001, depth_bias = 195, depth_bias_clamp = 1002, depth_bias_slope_scaled = 175, depth_clip_enable = 136, scissor_enable = 174, multisample_enable = 161, antialiased_line_enable = 176, // Depth-stencil state depth_enable = 7, depth_write_mask = 14, depth_func = 23, stencil_enable = 52, front_stencil_read_mask = 58, front_stencil_write_mask = 59, front_stencil_reference_value = 57, front_stencil_func = 56, front_stencil_pass_op = 55, front_stencil_fail_op = 53, front_stencil_depth_fail_op = 54, back_stencil_read_mask = 1006, back_stencil_write_mask = 1007, back_stencil_reference_value = 1008, back_stencil_func = 189, back_stencil_pass_op = 188, back_stencil_fail_op = 186, back_stencil_depth_fail_op = 187, }; /// /// Describes a rectangle. /// struct rect { int32_t left = 0; int32_t top = 0; int32_t right = 0; int32_t bottom = 0; constexpr uint32_t width() const { return right - left; } constexpr uint32_t height() const { return bottom - top; } }; /// /// Describes a render viewport. /// struct viewport { float x = 0.0f; float y = 0.0f; float width = 0.0f; float height = 0.0f; float min_depth = 0.0f; float max_depth = 1.0f; }; } }