| /* |
| * Copyright 2020 Valve Corporation |
| * SPDX-License-Identifier: MIT |
| * |
| * Authors: |
| * Jonathan Marek <jonathan@marek.ca> |
| */ |
| |
| #ifndef TU_UTIL_H |
| #define TU_UTIL_H |
| |
| #include <assert.h> |
| #include <stdint.h> |
| |
| #include "util/macros.h" |
| #include "util/u_math.h" |
| #include "compiler/shader_enums.h" |
| |
| #include "adreno_common.xml.h" |
| #include "adreno_pm4.xml.h" |
| #include "a6xx.xml.h" |
| |
| #include <vulkan/vulkan.h> |
| |
| static inline gl_shader_stage |
| vk_to_mesa_shader_stage(VkShaderStageFlagBits vk_stage) |
| { |
| assert(__builtin_popcount(vk_stage) == 1); |
| return util_logbase2(vk_stage); |
| } |
| |
| static inline VkShaderStageFlagBits |
| mesa_to_vk_shader_stage(gl_shader_stage mesa_stage) |
| { |
| return 1 << mesa_stage; |
| } |
| |
| #define TU_STAGE_MASK ((1 << MESA_SHADER_STAGES) - 1) |
| |
| #define tu_foreach_stage(stage, stage_bits) \ |
| for (gl_shader_stage stage, \ |
| __tmp = (gl_shader_stage)((stage_bits) &TU_STAGE_MASK); \ |
| stage = __builtin_ffs(__tmp) - 1, __tmp; __tmp &= ~(1 << (stage))) |
| |
| static inline enum a3xx_msaa_samples |
| tu_msaa_samples(VkSampleCountFlagBits samples) |
| { |
| assert(__builtin_popcount(samples) == 1); |
| return util_logbase2(samples); |
| } |
| |
| static inline uint32_t |
| tu6_stage2opcode(gl_shader_stage stage) |
| { |
| if (stage == MESA_SHADER_FRAGMENT || stage == MESA_SHADER_COMPUTE) |
| return CP_LOAD_STATE6_FRAG; |
| return CP_LOAD_STATE6_GEOM; |
| } |
| |
| static inline enum a6xx_state_block |
| tu6_stage2texsb(gl_shader_stage stage) |
| { |
| return SB6_VS_TEX + stage; |
| } |
| |
| static inline enum a6xx_state_block |
| tu6_stage2shadersb(gl_shader_stage stage) |
| { |
| return SB6_VS_SHADER + stage; |
| } |
| |
| static inline enum a3xx_rop_code |
| tu6_rop(VkLogicOp op) |
| { |
| /* note: hw enum matches the VK enum, but with the 4 bits reversed */ |
| static const uint8_t lookup[] = { |
| [VK_LOGIC_OP_CLEAR] = ROP_CLEAR, |
| [VK_LOGIC_OP_AND] = ROP_AND, |
| [VK_LOGIC_OP_AND_REVERSE] = ROP_AND_REVERSE, |
| [VK_LOGIC_OP_COPY] = ROP_COPY, |
| [VK_LOGIC_OP_AND_INVERTED] = ROP_AND_INVERTED, |
| [VK_LOGIC_OP_NO_OP] = ROP_NOOP, |
| [VK_LOGIC_OP_XOR] = ROP_XOR, |
| [VK_LOGIC_OP_OR] = ROP_OR, |
| [VK_LOGIC_OP_NOR] = ROP_NOR, |
| [VK_LOGIC_OP_EQUIVALENT] = ROP_EQUIV, |
| [VK_LOGIC_OP_INVERT] = ROP_INVERT, |
| [VK_LOGIC_OP_OR_REVERSE] = ROP_OR_REVERSE, |
| [VK_LOGIC_OP_COPY_INVERTED] = ROP_COPY_INVERTED, |
| [VK_LOGIC_OP_OR_INVERTED] = ROP_OR_INVERTED, |
| [VK_LOGIC_OP_NAND] = ROP_NAND, |
| [VK_LOGIC_OP_SET] = ROP_SET, |
| }; |
| assert(op < ARRAY_SIZE(lookup)); |
| return lookup[op]; |
| } |
| |
| static inline enum pc_di_primtype |
| tu6_primtype(VkPrimitiveTopology topology) |
| { |
| static const uint8_t lookup[] = { |
| [VK_PRIMITIVE_TOPOLOGY_POINT_LIST] = DI_PT_POINTLIST, |
| [VK_PRIMITIVE_TOPOLOGY_LINE_LIST] = DI_PT_LINELIST, |
| [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP] = DI_PT_LINESTRIP, |
| [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST] = DI_PT_TRILIST, |
| [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP] = DI_PT_TRISTRIP, |
| [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN] = DI_PT_TRIFAN, |
| [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY] = DI_PT_LINE_ADJ, |
| [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY] = DI_PT_LINESTRIP_ADJ, |
| [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY] = DI_PT_TRI_ADJ, |
| [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY] = DI_PT_TRISTRIP_ADJ, |
| /* Return PATCH0 and update in tu_pipeline_builder_parse_tessellation */ |
| [VK_PRIMITIVE_TOPOLOGY_PATCH_LIST] = DI_PT_PATCHES0, |
| }; |
| assert(topology < ARRAY_SIZE(lookup)); |
| return lookup[topology]; |
| } |
| |
| static inline enum adreno_compare_func |
| tu6_compare_func(VkCompareOp op) |
| { |
| return (enum adreno_compare_func) op; |
| } |
| |
| static inline enum adreno_stencil_op |
| tu6_stencil_op(VkStencilOp op) |
| { |
| return (enum adreno_stencil_op) op; |
| } |
| |
| static inline enum adreno_rb_blend_factor |
| tu6_blend_factor(VkBlendFactor factor) |
| { |
| static const uint8_t lookup[] = { |
| [VK_BLEND_FACTOR_ZERO] = FACTOR_ZERO, |
| [VK_BLEND_FACTOR_ONE] = FACTOR_ONE, |
| [VK_BLEND_FACTOR_SRC_COLOR] = FACTOR_SRC_COLOR, |
| [VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR] = FACTOR_ONE_MINUS_SRC_COLOR, |
| [VK_BLEND_FACTOR_DST_COLOR] = FACTOR_DST_COLOR, |
| [VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR] = FACTOR_ONE_MINUS_DST_COLOR, |
| [VK_BLEND_FACTOR_SRC_ALPHA] = FACTOR_SRC_ALPHA, |
| [VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA] = FACTOR_ONE_MINUS_SRC_ALPHA, |
| [VK_BLEND_FACTOR_DST_ALPHA] = FACTOR_DST_ALPHA, |
| [VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA] = FACTOR_ONE_MINUS_DST_ALPHA, |
| [VK_BLEND_FACTOR_CONSTANT_COLOR] = FACTOR_CONSTANT_COLOR, |
| [VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR]= FACTOR_ONE_MINUS_CONSTANT_COLOR, |
| [VK_BLEND_FACTOR_CONSTANT_ALPHA] = FACTOR_CONSTANT_ALPHA, |
| [VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA]= FACTOR_ONE_MINUS_CONSTANT_ALPHA, |
| [VK_BLEND_FACTOR_SRC_ALPHA_SATURATE] = FACTOR_SRC_ALPHA_SATURATE, |
| [VK_BLEND_FACTOR_SRC1_COLOR] = FACTOR_SRC1_COLOR, |
| [VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR] = FACTOR_ONE_MINUS_SRC1_COLOR, |
| [VK_BLEND_FACTOR_SRC1_ALPHA] = FACTOR_SRC1_ALPHA, |
| [VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA] = FACTOR_ONE_MINUS_SRC1_ALPHA, |
| }; |
| assert(factor < ARRAY_SIZE(lookup)); |
| return lookup[factor]; |
| } |
| |
| static inline enum a3xx_rb_blend_opcode |
| tu6_blend_op(VkBlendOp op) |
| { |
| return (enum a3xx_rb_blend_opcode) op; |
| } |
| |
| static inline enum a6xx_tex_type |
| tu6_tex_type(VkImageViewType type, bool storage) |
| { |
| switch (type) { |
| default: |
| case VK_IMAGE_VIEW_TYPE_1D: |
| case VK_IMAGE_VIEW_TYPE_1D_ARRAY: |
| return A6XX_TEX_1D; |
| case VK_IMAGE_VIEW_TYPE_2D: |
| case VK_IMAGE_VIEW_TYPE_2D_ARRAY: |
| return A6XX_TEX_2D; |
| case VK_IMAGE_VIEW_TYPE_3D: |
| return A6XX_TEX_3D; |
| case VK_IMAGE_VIEW_TYPE_CUBE: |
| case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: |
| return storage ? A6XX_TEX_2D : A6XX_TEX_CUBE; |
| } |
| } |
| |
| static inline enum a6xx_tex_clamp |
| tu6_tex_wrap(VkSamplerAddressMode address_mode) |
| { |
| uint8_t lookup[] = { |
| [VK_SAMPLER_ADDRESS_MODE_REPEAT] = A6XX_TEX_REPEAT, |
| [VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT] = A6XX_TEX_MIRROR_REPEAT, |
| [VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE] = A6XX_TEX_CLAMP_TO_EDGE, |
| [VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER] = A6XX_TEX_CLAMP_TO_BORDER, |
| [VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE] = A6XX_TEX_MIRROR_CLAMP, |
| }; |
| assert(address_mode < ARRAY_SIZE(lookup)); |
| return lookup[address_mode]; |
| } |
| |
| static inline enum a6xx_tex_filter |
| tu6_tex_filter(VkFilter filter, unsigned aniso) |
| { |
| switch (filter) { |
| case VK_FILTER_NEAREST: |
| return A6XX_TEX_NEAREST; |
| case VK_FILTER_LINEAR: |
| return aniso ? A6XX_TEX_ANISO : A6XX_TEX_LINEAR; |
| case VK_FILTER_CUBIC_EXT: |
| return A6XX_TEX_CUBIC; |
| default: |
| unreachable("illegal texture filter"); |
| break; |
| } |
| } |
| |
| static inline enum a6xx_reduction_mode |
| tu6_reduction_mode(VkSamplerReductionMode reduction_mode) |
| { |
| return (enum a6xx_reduction_mode) reduction_mode; |
| } |
| |
| static inline enum a6xx_depth_format |
| tu6_pipe2depth(VkFormat format) |
| { |
| switch (format) { |
| case VK_FORMAT_D16_UNORM: |
| return DEPTH6_16; |
| case VK_FORMAT_X8_D24_UNORM_PACK32: |
| case VK_FORMAT_D24_UNORM_S8_UINT: |
| return DEPTH6_24_8; |
| case VK_FORMAT_D32_SFLOAT: |
| case VK_FORMAT_S8_UINT: |
| return DEPTH6_32; |
| default: |
| return ~0; |
| } |
| } |
| |
| #endif /* TU_UTIL_H */ |