Home | History | Annotate | Line # | Download | only in vulkan
      1 /*
      2  * Copyright 2020 Valve Corporation
      3  * SPDX-License-Identifier: MIT
      4  *
      5  * Authors:
      6  *    Jonathan Marek <jonathan (at) marek.ca>
      7  */
      8 
      9 #ifndef TU_UTIL_H
     10 #define TU_UTIL_H
     11 
     12 #include <assert.h>
     13 #include <stdint.h>
     14 
     15 #include "util/macros.h"
     16 #include "util/u_math.h"
     17 #include "util/format/u_format_pack.h"
     18 #include "util/format/u_format_zs.h"
     19 #include "compiler/shader_enums.h"
     20 
     21 #include "adreno_common.xml.h"
     22 #include "adreno_pm4.xml.h"
     23 #include "a6xx.xml.h"
     24 
     25 #include <vulkan/vulkan.h>
     26 #include "vk_util.h"
     27 
     28 #define TU_STAGE_MASK ((1 << MESA_SHADER_STAGES) - 1)
     29 
     30 #define tu_foreach_stage(stage, stage_bits)                                  \
     31    for (gl_shader_stage stage,                                               \
     32         __tmp = (gl_shader_stage)((stage_bits) &TU_STAGE_MASK);              \
     33         stage = __builtin_ffs(__tmp) - 1, __tmp; __tmp &= ~(1 << (stage)))
     34 
     35 static inline enum a3xx_msaa_samples
     36 tu_msaa_samples(uint32_t samples)
     37 {
     38    assert(__builtin_popcount(samples) == 1);
     39    return util_logbase2(samples);
     40 }
     41 
     42 static inline uint32_t
     43 tu6_stage2opcode(gl_shader_stage stage)
     44 {
     45    if (stage == MESA_SHADER_FRAGMENT || stage == MESA_SHADER_COMPUTE)
     46       return CP_LOAD_STATE6_FRAG;
     47    return CP_LOAD_STATE6_GEOM;
     48 }
     49 
     50 static inline enum a6xx_state_block
     51 tu6_stage2texsb(gl_shader_stage stage)
     52 {
     53    return SB6_VS_TEX + stage;
     54 }
     55 
     56 static inline enum a6xx_state_block
     57 tu6_stage2shadersb(gl_shader_stage stage)
     58 {
     59    return SB6_VS_SHADER + stage;
     60 }
     61 
     62 static inline enum a3xx_rop_code
     63 tu6_rop(VkLogicOp op)
     64 {
     65    /* note: hw enum matches the VK enum, but with the 4 bits reversed */
     66    static const uint8_t lookup[] = {
     67       [VK_LOGIC_OP_CLEAR]           = ROP_CLEAR,
     68       [VK_LOGIC_OP_AND]             = ROP_AND,
     69       [VK_LOGIC_OP_AND_REVERSE]     = ROP_AND_REVERSE,
     70       [VK_LOGIC_OP_COPY]            = ROP_COPY,
     71       [VK_LOGIC_OP_AND_INVERTED]    = ROP_AND_INVERTED,
     72       [VK_LOGIC_OP_NO_OP]           = ROP_NOOP,
     73       [VK_LOGIC_OP_XOR]             = ROP_XOR,
     74       [VK_LOGIC_OP_OR]              = ROP_OR,
     75       [VK_LOGIC_OP_NOR]             = ROP_NOR,
     76       [VK_LOGIC_OP_EQUIVALENT]      = ROP_EQUIV,
     77       [VK_LOGIC_OP_INVERT]          = ROP_INVERT,
     78       [VK_LOGIC_OP_OR_REVERSE]      = ROP_OR_REVERSE,
     79       [VK_LOGIC_OP_COPY_INVERTED]   = ROP_COPY_INVERTED,
     80       [VK_LOGIC_OP_OR_INVERTED]     = ROP_OR_INVERTED,
     81       [VK_LOGIC_OP_NAND]            = ROP_NAND,
     82       [VK_LOGIC_OP_SET]             = ROP_SET,
     83    };
     84    assert(op < ARRAY_SIZE(lookup));
     85    return lookup[op];
     86 }
     87 
     88 static inline bool
     89 tu6_primtype_line(enum pc_di_primtype type)
     90 {
     91     switch(type) {
     92     case DI_PT_LINELIST:
     93     case DI_PT_LINESTRIP:
     94     case DI_PT_LINE_ADJ:
     95     case DI_PT_LINESTRIP_ADJ:
     96        return true;
     97     default:
     98        return false;
     99     }
    100 }
    101 
    102 static inline enum pc_di_primtype
    103 tu6_primtype(VkPrimitiveTopology topology)
    104 {
    105    static const uint8_t lookup[] = {
    106       [VK_PRIMITIVE_TOPOLOGY_POINT_LIST]                    = DI_PT_POINTLIST,
    107       [VK_PRIMITIVE_TOPOLOGY_LINE_LIST]                     = DI_PT_LINELIST,
    108       [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP]                    = DI_PT_LINESTRIP,
    109       [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST]                 = DI_PT_TRILIST,
    110       [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP]                = DI_PT_TRISTRIP,
    111       [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN]                  = DI_PT_TRIFAN,
    112       [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY]      = DI_PT_LINE_ADJ,
    113       [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY]     = DI_PT_LINESTRIP_ADJ,
    114       [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY]  = DI_PT_TRI_ADJ,
    115       [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY] = DI_PT_TRISTRIP_ADJ,
    116       /* Return PATCH0 and update in tu_pipeline_builder_parse_tessellation */
    117       [VK_PRIMITIVE_TOPOLOGY_PATCH_LIST]                    = DI_PT_PATCHES0,
    118    };
    119    assert(topology < ARRAY_SIZE(lookup));
    120    return lookup[topology];
    121 }
    122 
    123 static inline enum adreno_compare_func
    124 tu6_compare_func(VkCompareOp op)
    125 {
    126    return (enum adreno_compare_func) op;
    127 }
    128 
    129 static inline enum adreno_stencil_op
    130 tu6_stencil_op(VkStencilOp op)
    131 {
    132    return (enum adreno_stencil_op) op;
    133 }
    134 
    135 static inline enum adreno_rb_blend_factor
    136 tu6_blend_factor(VkBlendFactor factor)
    137 {
    138    static const uint8_t lookup[] = {
    139       [VK_BLEND_FACTOR_ZERO]                    = FACTOR_ZERO,
    140       [VK_BLEND_FACTOR_ONE]                     = FACTOR_ONE,
    141       [VK_BLEND_FACTOR_SRC_COLOR]               = FACTOR_SRC_COLOR,
    142       [VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR]     = FACTOR_ONE_MINUS_SRC_COLOR,
    143       [VK_BLEND_FACTOR_DST_COLOR]               = FACTOR_DST_COLOR,
    144       [VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR]     = FACTOR_ONE_MINUS_DST_COLOR,
    145       [VK_BLEND_FACTOR_SRC_ALPHA]               = FACTOR_SRC_ALPHA,
    146       [VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA]     = FACTOR_ONE_MINUS_SRC_ALPHA,
    147       [VK_BLEND_FACTOR_DST_ALPHA]               = FACTOR_DST_ALPHA,
    148       [VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA]     = FACTOR_ONE_MINUS_DST_ALPHA,
    149       [VK_BLEND_FACTOR_CONSTANT_COLOR]          = FACTOR_CONSTANT_COLOR,
    150       [VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR]= FACTOR_ONE_MINUS_CONSTANT_COLOR,
    151       [VK_BLEND_FACTOR_CONSTANT_ALPHA]          = FACTOR_CONSTANT_ALPHA,
    152       [VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA]= FACTOR_ONE_MINUS_CONSTANT_ALPHA,
    153       [VK_BLEND_FACTOR_SRC_ALPHA_SATURATE]      = FACTOR_SRC_ALPHA_SATURATE,
    154       [VK_BLEND_FACTOR_SRC1_COLOR]              = FACTOR_SRC1_COLOR,
    155       [VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR]    = FACTOR_ONE_MINUS_SRC1_COLOR,
    156       [VK_BLEND_FACTOR_SRC1_ALPHA]              = FACTOR_SRC1_ALPHA,
    157       [VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA]    = FACTOR_ONE_MINUS_SRC1_ALPHA,
    158    };
    159    assert(factor < ARRAY_SIZE(lookup));
    160    return lookup[factor];
    161 }
    162 
    163 static inline enum a3xx_rb_blend_opcode
    164 tu6_blend_op(VkBlendOp op)
    165 {
    166    return (enum a3xx_rb_blend_opcode) op;
    167 }
    168 
    169 static inline enum a6xx_tex_type
    170 tu6_tex_type(VkImageViewType type, bool storage)
    171 {
    172    switch (type) {
    173    default:
    174    case VK_IMAGE_VIEW_TYPE_1D:
    175    case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
    176       return A6XX_TEX_1D;
    177    case VK_IMAGE_VIEW_TYPE_2D:
    178    case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
    179       return A6XX_TEX_2D;
    180    case VK_IMAGE_VIEW_TYPE_3D:
    181       return A6XX_TEX_3D;
    182    case VK_IMAGE_VIEW_TYPE_CUBE:
    183    case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
    184       return storage ? A6XX_TEX_2D : A6XX_TEX_CUBE;
    185    }
    186 }
    187 
    188 static inline enum a6xx_tex_clamp
    189 tu6_tex_wrap(VkSamplerAddressMode address_mode)
    190 {
    191    uint8_t lookup[] = {
    192       [VK_SAMPLER_ADDRESS_MODE_REPEAT]                = A6XX_TEX_REPEAT,
    193       [VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT]       = A6XX_TEX_MIRROR_REPEAT,
    194       [VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE]         = A6XX_TEX_CLAMP_TO_EDGE,
    195       [VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER]       = A6XX_TEX_CLAMP_TO_BORDER,
    196       [VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE]  = A6XX_TEX_MIRROR_CLAMP,
    197    };
    198    assert(address_mode < ARRAY_SIZE(lookup));
    199    return lookup[address_mode];
    200 }
    201 
    202 static inline enum a6xx_tex_filter
    203 tu6_tex_filter(VkFilter filter, unsigned aniso)
    204 {
    205    switch (filter) {
    206    case VK_FILTER_NEAREST:
    207       return A6XX_TEX_NEAREST;
    208    case VK_FILTER_LINEAR:
    209       return aniso ? A6XX_TEX_ANISO : A6XX_TEX_LINEAR;
    210    case VK_FILTER_CUBIC_EXT:
    211       return A6XX_TEX_CUBIC;
    212    default:
    213       unreachable("illegal texture filter");
    214       break;
    215    }
    216 }
    217 
    218 static inline enum a6xx_reduction_mode
    219 tu6_reduction_mode(VkSamplerReductionMode reduction_mode)
    220 {
    221    return (enum a6xx_reduction_mode) reduction_mode;
    222 }
    223 
    224 static inline enum a6xx_depth_format
    225 tu6_pipe2depth(VkFormat format)
    226 {
    227    switch (format) {
    228    case VK_FORMAT_D16_UNORM:
    229       return DEPTH6_16;
    230    case VK_FORMAT_X8_D24_UNORM_PACK32:
    231    case VK_FORMAT_D24_UNORM_S8_UINT:
    232       return DEPTH6_24_8;
    233    case VK_FORMAT_D32_SFLOAT:
    234    case VK_FORMAT_D32_SFLOAT_S8_UINT:
    235    case VK_FORMAT_S8_UINT:
    236       return DEPTH6_32;
    237    default:
    238       return ~0;
    239    }
    240 }
    241 
    242 static inline enum a6xx_polygon_mode
    243 tu6_polygon_mode(VkPolygonMode mode)
    244 {
    245    switch (mode) {
    246    case VK_POLYGON_MODE_POINT:
    247       return POLYMODE6_POINTS;
    248    case VK_POLYGON_MODE_LINE:
    249       return POLYMODE6_LINES;
    250    case VK_POLYGON_MODE_FILL:
    251       return POLYMODE6_TRIANGLES;
    252    default:
    253       unreachable("bad polygon mode");
    254    }
    255 }
    256 
    257 struct bcolor_entry {
    258    uint32_t fp32[4];
    259    uint64_t ui16;
    260    uint64_t si16;
    261    uint64_t fp16;
    262    uint16_t rgb565;
    263    uint16_t rgb5a1;
    264    uint16_t rgba4;
    265    uint8_t __pad0[2];
    266    uint32_t ui8;
    267    uint32_t si8;
    268    uint32_t rgb10a2;
    269    uint32_t z24; /* also s8? */
    270    uint64_t srgb;
    271    uint8_t  __pad1[56];
    272 } __attribute__((aligned(128)));
    273 
    274 /* vulkan does not want clamping of integer clear values, differs from u_format
    275  * see spec for VkClearColorValue
    276  */
    277 static inline void
    278 pack_int8(uint32_t *dst, const uint32_t *val)
    279 {
    280    *dst = (val[0] & 0xff) |
    281           (val[1] & 0xff) << 8 |
    282           (val[2] & 0xff) << 16 |
    283           (val[3] & 0xff) << 24;
    284 }
    285 
    286 static inline void
    287 pack_int10_2(uint32_t *dst, const uint32_t *val)
    288 {
    289    *dst = (val[0] & 0x3ff) |
    290           (val[1] & 0x3ff) << 10 |
    291           (val[2] & 0x3ff) << 20 |
    292           (val[3] & 0x3)   << 30;
    293 }
    294 
    295 static inline void
    296 pack_int16(uint32_t *dst, const uint32_t *val)
    297 {
    298    dst[0] = (val[0] & 0xffff) |
    299             (val[1] & 0xffff) << 16;
    300    dst[1] = (val[2] & 0xffff) |
    301             (val[3] & 0xffff) << 16;
    302 }
    303 
    304 static inline void
    305 tu6_pack_border_color(struct bcolor_entry *bcolor, const VkClearColorValue *val, bool is_int)
    306 {
    307    memcpy(bcolor->fp32, val, 4 * sizeof(float));
    308    if (is_int) {
    309       pack_int16((uint32_t*) &bcolor->fp16, val->uint32);
    310       return;
    311    }
    312 #define PACK_F(x, type) util_format_##type##_pack_rgba_float \
    313    ( (uint8_t*) (&bcolor->x), 0, val->float32, 0, 1, 1)
    314    PACK_F(ui16, r16g16b16a16_unorm);
    315    PACK_F(si16, r16g16b16a16_snorm);
    316    PACK_F(fp16, r16g16b16a16_float);
    317    PACK_F(rgb565, r5g6b5_unorm);
    318    PACK_F(rgb5a1, r5g5b5a1_unorm);
    319    PACK_F(rgba4, r4g4b4a4_unorm);
    320    PACK_F(ui8, r8g8b8a8_unorm);
    321    PACK_F(si8, r8g8b8a8_snorm);
    322    PACK_F(rgb10a2, r10g10b10a2_unorm);
    323    util_format_x8z24_unorm_pack_z_float((uint8_t*) &bcolor->z24,
    324                                         0, val->float32, 0, 1, 1);
    325    PACK_F(srgb, r16g16b16a16_float); /* TODO: clamp? */
    326 #undef PACK_F
    327 }
    328 
    329 #endif /* TU_UTIL_H */
    330