| /* |
| * Copyright © 2016 Red Hat. |
| * Copyright © 2016 Bas Nieuwenhuizen |
| * |
| * based in part on anv driver which is: |
| * Copyright © 2015 Intel Corporation |
| * |
| * SPDX-License-Identifier: MIT |
| */ |
| |
| #ifndef RADV_PIPELINE_GRAPHICS_H |
| #define RADV_PIPELINE_GRAPHICS_H |
| |
| #include "sid.h" |
| |
| #include "radv_descriptor_set.h" |
| #include "radv_pipeline.h" |
| #include "radv_pipeline_layout.h" |
| #include "radv_shader.h" |
| |
| #include "vk_graphics_state.h" |
| #include "vk_meta.h" |
| |
| #define VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO_RADV (VkStructureType)2000290001 |
| |
| #define VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO_RADV_cast VkGraphicsPipelineCreateInfoRADV |
| |
| typedef struct VkGraphicsPipelineCreateInfoRADV { |
| VkStructureType sType; |
| const void *pNext; |
| VkBool32 db_depth_clear; |
| VkBool32 db_stencil_clear; |
| VkBool32 depth_compress_disable; |
| VkBool32 stencil_compress_disable; |
| uint32_t custom_blend_mode; |
| } VkGraphicsPipelineCreateInfoRADV; |
| |
| struct radv_sample_locations_state { |
| VkSampleCountFlagBits per_pixel; |
| VkExtent2D grid_size; |
| uint32_t count; |
| VkSampleLocationEXT locations[MAX_SAMPLE_LOCATIONS]; |
| }; |
| |
| struct radv_dynamic_state { |
| struct vk_dynamic_graphics_state vk; |
| |
| /** |
| * Bitmask of (1ull << VK_DYNAMIC_STATE_*). |
| * Defines the set of saved dynamic state. |
| */ |
| uint64_t mask; |
| |
| struct { |
| struct { |
| float scale[3]; |
| float translate[3]; |
| } xform[MAX_VIEWPORTS]; |
| } hw_vp; |
| |
| struct radv_sample_locations_state sample_location; |
| |
| VkImageAspectFlags feedback_loop_aspects; |
| }; |
| |
| struct radv_multisample_state { |
| bool sample_shading_enable; |
| float min_sample_shading; |
| }; |
| |
| struct radv_ia_multi_vgt_param_helpers { |
| uint32_t base; |
| bool partial_es_wave; |
| bool ia_switch_on_eoi; |
| bool partial_vs_wave; |
| }; |
| |
| struct radv_sqtt_shaders_reloc { |
| struct radeon_winsys_bo *bo; |
| union radv_shader_arena_block *alloc; |
| uint64_t va[MESA_VULKAN_SHADER_STAGES]; |
| }; |
| |
| struct radv_graphics_pipeline { |
| struct radv_pipeline base; |
| |
| bool uses_drawid; |
| bool uses_baseinstance; |
| |
| /* Whether the pipeline forces per-vertex VRS (GFX10.3+). */ |
| bool force_vrs_per_vertex; |
| |
| /* Whether the pipeline uses NGG (GFX10+). */ |
| bool is_ngg; |
| bool has_ngg_culling; |
| |
| uint8_t vtx_emit_num; |
| |
| uint32_t vtx_base_sgpr; |
| uint64_t dynamic_states; |
| uint64_t needed_dynamic_state; |
| |
| VkShaderStageFlags active_stages; |
| |
| struct radv_dynamic_state dynamic_state; |
| |
| struct radv_vertex_input_state vertex_input; |
| |
| struct radv_multisample_state ms; |
| struct radv_ia_multi_vgt_param_helpers ia_multi_vgt_param; |
| uint32_t binding_stride[MAX_VBS]; |
| uint32_t db_render_control; |
| |
| /* Last pre-PS API stage */ |
| gl_shader_stage last_vgt_api_stage; |
| |
| unsigned rast_prim; |
| |
| /* Custom blend mode for internal operations. */ |
| unsigned custom_blend_mode; |
| |
| /* Whether the pipeline uses out-of-order rasterization. */ |
| bool uses_out_of_order_rast; |
| |
| /* Whether the pipeline uses VRS. */ |
| bool uses_vrs; |
| |
| /* Whether the pipeline uses a VRS attachment. */ |
| bool uses_vrs_attachment; |
| |
| /* Whether the pipeline uses VRS coarse shading internally. */ |
| bool uses_vrs_coarse_shading; |
| |
| /* For relocation of shaders with RGP. */ |
| struct radv_sqtt_shaders_reloc *sqtt_shaders_reloc; |
| |
| /* Whether the pipeline imported binaries. */ |
| bool has_pipeline_binaries; |
| }; |
| |
| RADV_DECL_PIPELINE_DOWNCAST(graphics, RADV_PIPELINE_GRAPHICS) |
| |
| struct radv_retained_shaders { |
| struct { |
| void *serialized_nir; |
| size_t serialized_nir_size; |
| unsigned char shader_sha1[SHA1_DIGEST_LENGTH]; |
| struct radv_shader_stage_key key; |
| } stages[MESA_VULKAN_SHADER_STAGES]; |
| }; |
| |
| struct radv_graphics_lib_pipeline { |
| struct radv_graphics_pipeline base; |
| |
| struct vk_graphics_pipeline_state graphics_state; |
| |
| /* For vk_graphics_pipeline_state */ |
| void *state_data; |
| |
| struct radv_pipeline_layout layout; |
| |
| VkGraphicsPipelineLibraryFlagsEXT lib_flags; |
| |
| struct radv_retained_shaders retained_shaders; |
| |
| void *mem_ctx; |
| |
| unsigned stage_count; |
| VkPipelineShaderStageCreateInfo *stages; |
| struct radv_shader_stage_key stage_keys[MESA_VULKAN_SHADER_STAGES]; |
| }; |
| |
| RADV_DECL_PIPELINE_DOWNCAST(graphics_lib, RADV_PIPELINE_GRAPHICS_LIB) |
| |
| static inline bool |
| radv_pipeline_has_stage(const struct radv_graphics_pipeline *pipeline, gl_shader_stage stage) |
| { |
| return pipeline->base.shaders[stage]; |
| } |
| |
| static inline uint32_t |
| radv_conv_prim_to_gs_out(uint32_t topology, bool is_ngg) |
| { |
| switch (topology) { |
| case V_008958_DI_PT_POINTLIST: |
| case V_008958_DI_PT_PATCH: |
| return V_028A6C_POINTLIST; |
| case V_008958_DI_PT_LINELIST: |
| case V_008958_DI_PT_LINESTRIP: |
| case V_008958_DI_PT_LINELIST_ADJ: |
| case V_008958_DI_PT_LINESTRIP_ADJ: |
| return V_028A6C_LINESTRIP; |
| case V_008958_DI_PT_TRILIST: |
| case V_008958_DI_PT_TRISTRIP: |
| case V_008958_DI_PT_TRIFAN: |
| case V_008958_DI_PT_TRILIST_ADJ: |
| case V_008958_DI_PT_TRISTRIP_ADJ: |
| return V_028A6C_TRISTRIP; |
| case V_008958_DI_PT_RECTLIST: |
| return is_ngg ? V_028A6C_RECTLIST : V_028A6C_TRISTRIP; |
| default: |
| assert(0); |
| return 0; |
| } |
| } |
| |
| static inline uint32_t |
| radv_conv_gl_prim_to_gs_out(unsigned gl_prim) |
| { |
| switch (gl_prim) { |
| case MESA_PRIM_POINTS: |
| return V_028A6C_POINTLIST; |
| case MESA_PRIM_LINES: |
| case MESA_PRIM_LINE_STRIP: |
| case MESA_PRIM_LINES_ADJACENCY: |
| return V_028A6C_LINESTRIP; |
| |
| case MESA_PRIM_TRIANGLES: |
| case MESA_PRIM_TRIANGLE_STRIP_ADJACENCY: |
| case MESA_PRIM_TRIANGLE_STRIP: |
| case MESA_PRIM_QUADS: |
| return V_028A6C_TRISTRIP; |
| default: |
| assert(0); |
| return 0; |
| } |
| } |
| |
| static inline uint32_t |
| radv_translate_prim(unsigned topology) |
| { |
| switch (topology) { |
| case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: |
| return V_008958_DI_PT_POINTLIST; |
| case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: |
| return V_008958_DI_PT_LINELIST; |
| case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: |
| return V_008958_DI_PT_LINESTRIP; |
| case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: |
| return V_008958_DI_PT_TRILIST; |
| case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: |
| return V_008958_DI_PT_TRISTRIP; |
| case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: |
| return V_008958_DI_PT_TRIFAN; |
| case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: |
| return V_008958_DI_PT_LINELIST_ADJ; |
| case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: |
| return V_008958_DI_PT_LINESTRIP_ADJ; |
| case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: |
| return V_008958_DI_PT_TRILIST_ADJ; |
| case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: |
| return V_008958_DI_PT_TRISTRIP_ADJ; |
| case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: |
| return V_008958_DI_PT_PATCH; |
| case VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA: |
| return V_008958_DI_PT_RECTLIST; |
| default: |
| unreachable("unhandled primitive type"); |
| } |
| } |
| |
| static inline bool |
| radv_prim_is_lines(unsigned topology) |
| { |
| switch (topology) { |
| case V_008958_DI_PT_LINELIST: |
| case V_008958_DI_PT_LINESTRIP: |
| case V_008958_DI_PT_LINELIST_ADJ: |
| case V_008958_DI_PT_LINESTRIP_ADJ: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| static inline bool |
| radv_prim_is_points_or_lines(unsigned topology) |
| { |
| return topology == V_008958_DI_PT_POINTLIST || radv_prim_is_lines(topology); |
| } |
| |
| static inline bool |
| radv_rast_prim_is_point(unsigned rast_prim) |
| { |
| return rast_prim == V_028A6C_POINTLIST; |
| } |
| |
| static inline bool |
| radv_rast_prim_is_line(unsigned rast_prim) |
| { |
| return rast_prim == V_028A6C_LINESTRIP; |
| } |
| |
| static inline bool |
| radv_rast_prim_is_points_or_lines(unsigned rast_prim) |
| { |
| return radv_rast_prim_is_point(rast_prim) || radv_rast_prim_is_line(rast_prim); |
| } |
| |
| static inline bool |
| radv_polygon_mode_is_point(unsigned polygon_mode) |
| { |
| return polygon_mode == V_028814_X_DRAW_POINTS; |
| } |
| |
| static inline bool |
| radv_polygon_mode_is_line(unsigned polygon_mode) |
| { |
| return polygon_mode == V_028814_X_DRAW_LINES; |
| } |
| |
| static inline bool |
| radv_polygon_mode_is_points_or_lines(unsigned polygon_mode) |
| { |
| return radv_polygon_mode_is_point(polygon_mode) || radv_polygon_mode_is_line(polygon_mode); |
| } |
| |
| static inline bool |
| radv_primitive_topology_is_line_list(unsigned primitive_topology) |
| { |
| return primitive_topology == V_008958_DI_PT_LINELIST || primitive_topology == V_008958_DI_PT_LINELIST_ADJ; |
| } |
| |
| static inline unsigned |
| radv_get_num_vertices_per_prim(const struct radv_graphics_state_key *gfx_state) |
| { |
| if (gfx_state->ia.topology == V_008958_DI_PT_NONE) { |
| /* When the topology is unknown (with graphics pipeline library), return the maximum number of |
| * vertices per primitives for VS. This is used to lower NGG (the HW will ignore the extra |
| * bits for points/lines) and also to enable NGG culling unconditionally (it will be disabled |
| * dynamically for points/lines). |
| */ |
| return 3; |
| } else { |
| /* Need to add 1, because: V_028A6C_POINTLIST=0, V_028A6C_LINESTRIP=1, V_028A6C_TRISTRIP=2, etc. */ |
| return radv_conv_prim_to_gs_out(gfx_state->ia.topology, false) + 1; |
| } |
| } |
| |
| static inline uint32_t |
| radv_translate_fill(VkPolygonMode func) |
| { |
| switch (func) { |
| case VK_POLYGON_MODE_FILL: |
| return V_028814_X_DRAW_TRIANGLES; |
| case VK_POLYGON_MODE_LINE: |
| return V_028814_X_DRAW_LINES; |
| case VK_POLYGON_MODE_POINT: |
| return V_028814_X_DRAW_POINTS; |
| default: |
| assert(0); |
| return V_028814_X_DRAW_POINTS; |
| } |
| } |
| |
| static inline uint32_t |
| radv_translate_stencil_op(VkStencilOp op) |
| { |
| switch (op) { |
| case VK_STENCIL_OP_KEEP: |
| return V_02842C_STENCIL_KEEP; |
| case VK_STENCIL_OP_ZERO: |
| return V_02842C_STENCIL_ZERO; |
| case VK_STENCIL_OP_REPLACE: |
| return V_02842C_STENCIL_REPLACE_TEST; |
| case VK_STENCIL_OP_INCREMENT_AND_CLAMP: |
| return V_02842C_STENCIL_ADD_CLAMP; |
| case VK_STENCIL_OP_DECREMENT_AND_CLAMP: |
| return V_02842C_STENCIL_SUB_CLAMP; |
| case VK_STENCIL_OP_INVERT: |
| return V_02842C_STENCIL_INVERT; |
| case VK_STENCIL_OP_INCREMENT_AND_WRAP: |
| return V_02842C_STENCIL_ADD_WRAP; |
| case VK_STENCIL_OP_DECREMENT_AND_WRAP: |
| return V_02842C_STENCIL_SUB_WRAP; |
| default: |
| return 0; |
| } |
| } |
| |
| static inline uint32_t |
| radv_translate_blend_logic_op(VkLogicOp op) |
| { |
| switch (op) { |
| case VK_LOGIC_OP_CLEAR: |
| return V_028808_ROP3_CLEAR; |
| case VK_LOGIC_OP_AND: |
| return V_028808_ROP3_AND; |
| case VK_LOGIC_OP_AND_REVERSE: |
| return V_028808_ROP3_AND_REVERSE; |
| case VK_LOGIC_OP_COPY: |
| return V_028808_ROP3_COPY; |
| case VK_LOGIC_OP_AND_INVERTED: |
| return V_028808_ROP3_AND_INVERTED; |
| case VK_LOGIC_OP_NO_OP: |
| return V_028808_ROP3_NO_OP; |
| case VK_LOGIC_OP_XOR: |
| return V_028808_ROP3_XOR; |
| case VK_LOGIC_OP_OR: |
| return V_028808_ROP3_OR; |
| case VK_LOGIC_OP_NOR: |
| return V_028808_ROP3_NOR; |
| case VK_LOGIC_OP_EQUIVALENT: |
| return V_028808_ROP3_EQUIVALENT; |
| case VK_LOGIC_OP_INVERT: |
| return V_028808_ROP3_INVERT; |
| case VK_LOGIC_OP_OR_REVERSE: |
| return V_028808_ROP3_OR_REVERSE; |
| case VK_LOGIC_OP_COPY_INVERTED: |
| return V_028808_ROP3_COPY_INVERTED; |
| case VK_LOGIC_OP_OR_INVERTED: |
| return V_028808_ROP3_OR_INVERTED; |
| case VK_LOGIC_OP_NAND: |
| return V_028808_ROP3_NAND; |
| case VK_LOGIC_OP_SET: |
| return V_028808_ROP3_SET; |
| default: |
| unreachable("Unhandled logic op"); |
| } |
| } |
| |
| static inline uint32_t |
| radv_translate_blend_function(VkBlendOp op) |
| { |
| switch (op) { |
| case VK_BLEND_OP_ADD: |
| return V_028780_COMB_DST_PLUS_SRC; |
| case VK_BLEND_OP_SUBTRACT: |
| return V_028780_COMB_SRC_MINUS_DST; |
| case VK_BLEND_OP_REVERSE_SUBTRACT: |
| return V_028780_COMB_DST_MINUS_SRC; |
| case VK_BLEND_OP_MIN: |
| return V_028780_COMB_MIN_DST_SRC; |
| case VK_BLEND_OP_MAX: |
| return V_028780_COMB_MAX_DST_SRC; |
| default: |
| return 0; |
| } |
| } |
| |
| static inline uint32_t |
| radv_translate_blend_factor(enum amd_gfx_level gfx_level, VkBlendFactor factor) |
| { |
| switch (factor) { |
| case VK_BLEND_FACTOR_ZERO: |
| return V_028780_BLEND_ZERO; |
| case VK_BLEND_FACTOR_ONE: |
| return V_028780_BLEND_ONE; |
| case VK_BLEND_FACTOR_SRC_COLOR: |
| return V_028780_BLEND_SRC_COLOR; |
| case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: |
| return V_028780_BLEND_ONE_MINUS_SRC_COLOR; |
| case VK_BLEND_FACTOR_DST_COLOR: |
| return V_028780_BLEND_DST_COLOR; |
| case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR: |
| return V_028780_BLEND_ONE_MINUS_DST_COLOR; |
| case VK_BLEND_FACTOR_SRC_ALPHA: |
| return V_028780_BLEND_SRC_ALPHA; |
| case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: |
| return V_028780_BLEND_ONE_MINUS_SRC_ALPHA; |
| case VK_BLEND_FACTOR_DST_ALPHA: |
| return V_028780_BLEND_DST_ALPHA; |
| case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: |
| return V_028780_BLEND_ONE_MINUS_DST_ALPHA; |
| case VK_BLEND_FACTOR_CONSTANT_COLOR: |
| return gfx_level >= GFX11 ? V_028780_BLEND_CONSTANT_COLOR_GFX11 : V_028780_BLEND_CONSTANT_COLOR_GFX6; |
| case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: |
| return gfx_level >= GFX11 ? V_028780_BLEND_ONE_MINUS_CONSTANT_COLOR_GFX11 |
| : V_028780_BLEND_ONE_MINUS_CONSTANT_COLOR_GFX6; |
| case VK_BLEND_FACTOR_CONSTANT_ALPHA: |
| return gfx_level >= GFX11 ? V_028780_BLEND_CONSTANT_ALPHA_GFX11 : V_028780_BLEND_CONSTANT_ALPHA_GFX6; |
| case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: |
| return gfx_level >= GFX11 ? V_028780_BLEND_ONE_MINUS_CONSTANT_ALPHA_GFX11 |
| : V_028780_BLEND_ONE_MINUS_CONSTANT_ALPHA_GFX6; |
| case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE: |
| return V_028780_BLEND_SRC_ALPHA_SATURATE; |
| case VK_BLEND_FACTOR_SRC1_COLOR: |
| return gfx_level >= GFX11 ? V_028780_BLEND_SRC1_COLOR_GFX11 : V_028780_BLEND_SRC1_COLOR_GFX6; |
| case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: |
| return gfx_level >= GFX11 ? V_028780_BLEND_INV_SRC1_COLOR_GFX11 : V_028780_BLEND_INV_SRC1_COLOR_GFX6; |
| case VK_BLEND_FACTOR_SRC1_ALPHA: |
| return gfx_level >= GFX11 ? V_028780_BLEND_SRC1_ALPHA_GFX11 : V_028780_BLEND_SRC1_ALPHA_GFX6; |
| case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: |
| return gfx_level >= GFX11 ? V_028780_BLEND_INV_SRC1_ALPHA_GFX11 : V_028780_BLEND_INV_SRC1_ALPHA_GFX6; |
| default: |
| return 0; |
| } |
| } |
| |
| static inline uint32_t |
| radv_translate_blend_opt_factor(VkBlendFactor factor, bool is_alpha) |
| { |
| switch (factor) { |
| case VK_BLEND_FACTOR_ZERO: |
| return V_028760_BLEND_OPT_PRESERVE_NONE_IGNORE_ALL; |
| case VK_BLEND_FACTOR_ONE: |
| return V_028760_BLEND_OPT_PRESERVE_ALL_IGNORE_NONE; |
| case VK_BLEND_FACTOR_SRC_COLOR: |
| return is_alpha ? V_028760_BLEND_OPT_PRESERVE_A1_IGNORE_A0 : V_028760_BLEND_OPT_PRESERVE_C1_IGNORE_C0; |
| case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: |
| return is_alpha ? V_028760_BLEND_OPT_PRESERVE_A0_IGNORE_A1 : V_028760_BLEND_OPT_PRESERVE_C0_IGNORE_C1; |
| case VK_BLEND_FACTOR_SRC_ALPHA: |
| return V_028760_BLEND_OPT_PRESERVE_A1_IGNORE_A0; |
| case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: |
| return V_028760_BLEND_OPT_PRESERVE_A0_IGNORE_A1; |
| case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE: |
| return is_alpha ? V_028760_BLEND_OPT_PRESERVE_ALL_IGNORE_NONE : V_028760_BLEND_OPT_PRESERVE_NONE_IGNORE_A0; |
| default: |
| return V_028760_BLEND_OPT_PRESERVE_NONE_IGNORE_NONE; |
| } |
| } |
| |
| static inline uint32_t |
| radv_translate_blend_opt_function(VkBlendOp op) |
| { |
| switch (op) { |
| case VK_BLEND_OP_ADD: |
| return V_028760_OPT_COMB_ADD; |
| case VK_BLEND_OP_SUBTRACT: |
| return V_028760_OPT_COMB_SUBTRACT; |
| case VK_BLEND_OP_REVERSE_SUBTRACT: |
| return V_028760_OPT_COMB_REVSUBTRACT; |
| case VK_BLEND_OP_MIN: |
| return V_028760_OPT_COMB_MIN; |
| case VK_BLEND_OP_MAX: |
| return V_028760_OPT_COMB_MAX; |
| default: |
| return V_028760_OPT_COMB_BLEND_DISABLED; |
| } |
| } |
| |
| static inline bool |
| radv_blend_factor_uses_dst(VkBlendFactor factor) |
| { |
| return factor == VK_BLEND_FACTOR_DST_COLOR || factor == VK_BLEND_FACTOR_DST_ALPHA || |
| factor == VK_BLEND_FACTOR_SRC_ALPHA_SATURATE || factor == VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA || |
| factor == VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; |
| } |
| |
| static inline bool |
| radv_is_dual_src(VkBlendFactor factor) |
| { |
| switch (factor) { |
| case VK_BLEND_FACTOR_SRC1_COLOR: |
| case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: |
| case VK_BLEND_FACTOR_SRC1_ALPHA: |
| case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| static ALWAYS_INLINE bool |
| radv_can_enable_dual_src(const struct vk_color_blend_attachment_state *att) |
| { |
| VkBlendOp eqRGB = att->color_blend_op; |
| VkBlendFactor srcRGB = att->src_color_blend_factor; |
| VkBlendFactor dstRGB = att->dst_color_blend_factor; |
| VkBlendOp eqA = att->alpha_blend_op; |
| VkBlendFactor srcA = att->src_alpha_blend_factor; |
| VkBlendFactor dstA = att->dst_alpha_blend_factor; |
| bool eqRGB_minmax = eqRGB == VK_BLEND_OP_MIN || eqRGB == VK_BLEND_OP_MAX; |
| bool eqA_minmax = eqA == VK_BLEND_OP_MIN || eqA == VK_BLEND_OP_MAX; |
| |
| if (!eqRGB_minmax && (radv_is_dual_src(srcRGB) || radv_is_dual_src(dstRGB))) |
| return true; |
| if (!eqA_minmax && (radv_is_dual_src(srcA) || radv_is_dual_src(dstA))) |
| return true; |
| return false; |
| } |
| |
| static inline void |
| radv_normalize_blend_factor(VkBlendOp op, VkBlendFactor *src_factor, VkBlendFactor *dst_factor) |
| { |
| if (op == VK_BLEND_OP_MIN || op == VK_BLEND_OP_MAX) { |
| *src_factor = VK_BLEND_FACTOR_ONE; |
| *dst_factor = VK_BLEND_FACTOR_ONE; |
| } |
| } |
| |
| void radv_blend_remove_dst(VkBlendOp *func, VkBlendFactor *src_factor, VkBlendFactor *dst_factor, |
| VkBlendFactor expected_dst, VkBlendFactor replacement_src); |
| |
| unsigned radv_format_meta_fs_key(struct radv_device *device, VkFormat format); |
| |
| struct radv_ia_multi_vgt_param_helpers radv_compute_ia_multi_vgt_param(const struct radv_device *device, |
| struct radv_shader *const *shaders); |
| |
| void radv_get_viewport_xform(const VkViewport *viewport, float scale[3], float translate[3]); |
| |
| struct radv_shader *radv_get_shader(struct radv_shader *const *shaders, gl_shader_stage stage); |
| |
| struct radv_ps_epilog_state { |
| uint8_t color_attachment_count; |
| VkFormat color_attachment_formats[MAX_RTS]; |
| uint8_t color_attachment_mappings[MAX_RTS]; |
| |
| uint32_t color_write_mask; |
| uint32_t color_blend_enable; |
| |
| uint32_t colors_written; |
| bool mrt0_is_dual_src; |
| bool export_depth; |
| bool export_stencil; |
| bool export_sample_mask; |
| bool alpha_to_coverage_via_mrtz; |
| bool alpha_to_one; |
| uint8_t need_src_alpha; |
| }; |
| |
| struct radv_ps_epilog_key radv_generate_ps_epilog_key(const struct radv_device *device, |
| const struct radv_ps_epilog_state *state); |
| |
| void radv_graphics_shaders_compile(struct radv_device *device, struct vk_pipeline_cache *cache, |
| struct radv_shader_stage *stages, const struct radv_graphics_state_key *gfx_state, |
| bool keep_executable_info, bool keep_statistic_info, bool is_internal, |
| bool skip_shaders_cache, struct radv_retained_shaders *retained_shaders, |
| bool noop_fs, struct radv_shader **shaders, struct radv_shader_binary **binaries, |
| struct radv_shader **gs_copy_shader, struct radv_shader_binary **gs_copy_binary); |
| |
| struct radv_vgt_shader_key { |
| uint8_t tess : 1; |
| uint8_t gs : 1; |
| uint8_t mesh_scratch_ring : 1; |
| uint8_t mesh : 1; |
| uint8_t ngg_passthrough : 1; |
| uint8_t ngg : 1; /* gfx10+ */ |
| uint8_t ngg_streamout : 1; |
| uint8_t hs_wave32 : 1; |
| uint8_t gs_wave32 : 1; |
| uint8_t vs_wave32 : 1; |
| }; |
| |
| struct radv_vgt_shader_key radv_get_vgt_shader_key(const struct radv_device *device, struct radv_shader **shaders, |
| const struct radv_shader *gs_copy_shader); |
| |
| uint32_t radv_get_vgt_gs_out(struct radv_shader **shaders, uint32_t primitive_topology, bool is_ngg); |
| |
| bool radv_needs_null_export_workaround(const struct radv_device *device, const struct radv_shader *ps, |
| unsigned custom_blend_mode); |
| |
| void radv_destroy_graphics_pipeline(struct radv_device *device, struct radv_graphics_pipeline *pipeline); |
| |
| void radv_destroy_graphics_lib_pipeline(struct radv_device *device, struct radv_graphics_lib_pipeline *pipeline); |
| |
| struct radv_graphics_pipeline_state { |
| struct vk_graphics_pipeline_state vk; |
| void *vk_data; |
| |
| bool compilation_required; |
| |
| struct radv_shader_stage *stages; |
| |
| struct radv_graphics_pipeline_key key; |
| |
| struct radv_pipeline_layout layout; |
| }; |
| |
| void radv_graphics_pipeline_hash(const struct radv_device *device, const struct radv_graphics_pipeline_state *gfx_state, |
| unsigned char *hash); |
| |
| VkResult radv_generate_graphics_pipeline_state(struct radv_device *device, |
| const VkGraphicsPipelineCreateInfo *pCreateInfo, |
| struct radv_graphics_pipeline_state *gfx_state); |
| |
| void radv_graphics_pipeline_state_finish(struct radv_device *device, struct radv_graphics_pipeline_state *gfx_state); |
| |
| #endif /* RADV_PIPELINE_GRAPHICS_H */ |