1*61046927SAndroid Build Coastguard Worker /* 2*61046927SAndroid Build Coastguard Worker * Copyright 2024 Alyssa Rosenzweig 3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT 4*61046927SAndroid Build Coastguard Worker */ 5*61046927SAndroid Build Coastguard Worker 6*61046927SAndroid Build Coastguard Worker #pragma once 7*61046927SAndroid Build Coastguard Worker 8*61046927SAndroid Build Coastguard Worker #include "agx_bo.h" 9*61046927SAndroid Build Coastguard Worker #include "agx_compile.h" 10*61046927SAndroid Build Coastguard Worker #include "agx_nir_lower_vbo.h" 11*61046927SAndroid Build Coastguard Worker #include "agx_pack.h" 12*61046927SAndroid Build Coastguard Worker #include "nir_lower_blend.h" 13*61046927SAndroid Build Coastguard Worker 14*61046927SAndroid Build Coastguard Worker struct agx_linked_shader { 15*61046927SAndroid Build Coastguard Worker /* Mapped executable memory */ 16*61046927SAndroid Build Coastguard Worker struct agx_bo *bo; 17*61046927SAndroid Build Coastguard Worker 18*61046927SAndroid Build Coastguard Worker /* Set if the linked SW vertex shader reads base vertex/instance. The VS 19*61046927SAndroid Build Coastguard Worker * prolog can read base instance even when the API VS does not, which is why 20*61046927SAndroid Build Coastguard Worker * this needs to be aggregated in the linker. 21*61046927SAndroid Build Coastguard Worker */ 22*61046927SAndroid Build Coastguard Worker bool uses_base_param; 23*61046927SAndroid Build Coastguard Worker 24*61046927SAndroid Build Coastguard Worker /* Set if the linked shader uses txf. The epilog may even if the main shader 25*61046927SAndroid Build Coastguard Worker * does not, in the case of spilled render targets. 26*61046927SAndroid Build Coastguard Worker */ 27*61046927SAndroid Build Coastguard Worker bool uses_txf; 28*61046927SAndroid Build Coastguard Worker 29*61046927SAndroid Build Coastguard Worker /* Coefficient register bindings */ 30*61046927SAndroid Build Coastguard Worker struct agx_varyings_fs cf; 31*61046927SAndroid Build Coastguard Worker 32*61046927SAndroid Build Coastguard Worker /* Data structures packed for the linked program */ 33*61046927SAndroid Build Coastguard Worker struct agx_usc_shader_packed shader; 34*61046927SAndroid Build Coastguard Worker struct agx_usc_registers_packed regs; 35*61046927SAndroid Build Coastguard Worker struct agx_usc_fragment_properties_packed fragment_props; 36*61046927SAndroid Build Coastguard Worker struct agx_output_select_packed osel; 37*61046927SAndroid Build Coastguard Worker struct agx_fragment_control_packed fragment_control; 38*61046927SAndroid Build Coastguard Worker }; 39*61046927SAndroid Build Coastguard Worker 40*61046927SAndroid Build Coastguard Worker void agx_fast_link(struct agx_linked_shader *linked, struct agx_device *dev, 41*61046927SAndroid Build Coastguard Worker bool fragment, struct agx_shader_part *main, 42*61046927SAndroid Build Coastguard Worker struct agx_shader_part *prolog, 43*61046927SAndroid Build Coastguard Worker struct agx_shader_part *epilog, unsigned nr_samples_shaded); 44*61046927SAndroid Build Coastguard Worker 45*61046927SAndroid Build Coastguard Worker /* These parts of the vertex element affect the generated code */ 46*61046927SAndroid Build Coastguard Worker struct agx_velem_key { 47*61046927SAndroid Build Coastguard Worker uint32_t divisor; 48*61046927SAndroid Build Coastguard Worker uint16_t stride; 49*61046927SAndroid Build Coastguard Worker uint8_t format; 50*61046927SAndroid Build Coastguard Worker bool instanced; 51*61046927SAndroid Build Coastguard Worker }; 52*61046927SAndroid Build Coastguard Worker 53*61046927SAndroid Build Coastguard Worker struct agx_vs_prolog_key { 54*61046927SAndroid Build Coastguard Worker struct agx_velem_key attribs[AGX_MAX_VBUFS]; 55*61046927SAndroid Build Coastguard Worker 56*61046927SAndroid Build Coastguard Worker /* Bit mask of attribute components to load */ 57*61046927SAndroid Build Coastguard Worker BITSET_DECLARE(component_mask, AGX_MAX_ATTRIBS * 4); 58*61046927SAndroid Build Coastguard Worker 59*61046927SAndroid Build Coastguard Worker /* Whether running as a hardware vertex shader (versus compute) */ 60*61046927SAndroid Build Coastguard Worker bool hw; 61*61046927SAndroid Build Coastguard Worker 62*61046927SAndroid Build Coastguard Worker /* If !hw and the draw call is indexed, the index size */ 63*61046927SAndroid Build Coastguard Worker uint8_t sw_index_size_B; 64*61046927SAndroid Build Coastguard Worker 65*61046927SAndroid Build Coastguard Worker /* Robustness settings for the vertex fetch */ 66*61046927SAndroid Build Coastguard Worker struct agx_robustness robustness; 67*61046927SAndroid Build Coastguard Worker }; 68*61046927SAndroid Build Coastguard Worker 69*61046927SAndroid Build Coastguard Worker struct agx_fs_prolog_key { 70*61046927SAndroid Build Coastguard Worker /* glSampleMask() mask */ 71*61046927SAndroid Build Coastguard Worker uint8_t api_sample_mask; 72*61046927SAndroid Build Coastguard Worker 73*61046927SAndroid Build Coastguard Worker /* Number of cull planes requiring lowering */ 74*61046927SAndroid Build Coastguard Worker uint8_t cull_distance_size; 75*61046927SAndroid Build Coastguard Worker 76*61046927SAndroid Build Coastguard Worker /* Need to count FRAGMENT_SHADER_INVOCATIONS */ 77*61046927SAndroid Build Coastguard Worker bool statistics; 78*61046927SAndroid Build Coastguard Worker 79*61046927SAndroid Build Coastguard Worker /* Need to lower desktop OpenGL polygon stipple */ 80*61046927SAndroid Build Coastguard Worker bool polygon_stipple; 81*61046927SAndroid Build Coastguard Worker 82*61046927SAndroid Build Coastguard Worker /* If we discard, whether we need to run Z/S tests */ 83*61046927SAndroid Build Coastguard Worker bool run_zs_tests; 84*61046927SAndroid Build Coastguard Worker 85*61046927SAndroid Build Coastguard Worker /* If we emulate cull distance, the base offset for our allocated coefficient 86*61046927SAndroid Build Coastguard Worker * registers so we don't interfere with the main shader. 87*61046927SAndroid Build Coastguard Worker */ 88*61046927SAndroid Build Coastguard Worker unsigned cf_base; 89*61046927SAndroid Build Coastguard Worker }; 90*61046927SAndroid Build Coastguard Worker 91*61046927SAndroid Build Coastguard Worker struct agx_blend_rt_key { 92*61046927SAndroid Build Coastguard Worker enum pipe_blend_func rgb_func : 3; 93*61046927SAndroid Build Coastguard Worker enum pipe_blendfactor rgb_src_factor : 5; 94*61046927SAndroid Build Coastguard Worker enum pipe_blendfactor rgb_dst_factor : 5; 95*61046927SAndroid Build Coastguard Worker enum pipe_blend_func alpha_func : 3; 96*61046927SAndroid Build Coastguard Worker enum pipe_blendfactor alpha_src_factor : 5; 97*61046927SAndroid Build Coastguard Worker enum pipe_blendfactor alpha_dst_factor : 5; 98*61046927SAndroid Build Coastguard Worker unsigned colormask : 4; 99*61046927SAndroid Build Coastguard Worker unsigned pad : 2; 100*61046927SAndroid Build Coastguard Worker }; 101*61046927SAndroid Build Coastguard Worker static_assert(sizeof(struct agx_blend_rt_key) == 4, "packed"); 102*61046927SAndroid Build Coastguard Worker 103*61046927SAndroid Build Coastguard Worker struct agx_blend_key { 104*61046927SAndroid Build Coastguard Worker struct agx_blend_rt_key rt[8]; 105*61046927SAndroid Build Coastguard Worker uint8_t logicop_func; 106*61046927SAndroid Build Coastguard Worker bool alpha_to_coverage, alpha_to_one; 107*61046927SAndroid Build Coastguard Worker bool padding; 108*61046927SAndroid Build Coastguard Worker }; 109*61046927SAndroid Build Coastguard Worker static_assert(sizeof(struct agx_blend_key) == 36, "packed"); 110*61046927SAndroid Build Coastguard Worker 111*61046927SAndroid Build Coastguard Worker struct agx_fs_epilog_link_info { 112*61046927SAndroid Build Coastguard Worker /* Base index of spilled render targets in the binding table */ 113*61046927SAndroid Build Coastguard Worker uint8_t rt_spill_base; 114*61046927SAndroid Build Coastguard Worker 115*61046927SAndroid Build Coastguard Worker /* Bit mask of the bit size written to each render target. Bit i set if RT i 116*61046927SAndroid Build Coastguard Worker * uses 32-bit registers, else 16-bit registers. 117*61046927SAndroid Build Coastguard Worker */ 118*61046927SAndroid Build Coastguard Worker uint8_t size_32; 119*61046927SAndroid Build Coastguard Worker 120*61046927SAndroid Build Coastguard Worker /* Mask of render targets written by the main shader */ 121*61046927SAndroid Build Coastguard Worker uint8_t rt_written; 122*61046927SAndroid Build Coastguard Worker 123*61046927SAndroid Build Coastguard Worker /* If set, the API fragment shader uses sample shading. This means the epilog 124*61046927SAndroid Build Coastguard Worker * will be invoked per-sample as well. 125*61046927SAndroid Build Coastguard Worker */ 126*61046927SAndroid Build Coastguard Worker unsigned sample_shading : 1; 127*61046927SAndroid Build Coastguard Worker 128*61046927SAndroid Build Coastguard Worker /* If set, broadcast the render target #0 value to all render targets. This 129*61046927SAndroid Build Coastguard Worker * implements gl_FragColor semantics. 130*61046927SAndroid Build Coastguard Worker */ 131*61046927SAndroid Build Coastguard Worker unsigned broadcast_rt0 : 1; 132*61046927SAndroid Build Coastguard Worker 133*61046927SAndroid Build Coastguard Worker /* If set, force render target 0's W channel to 1.0. This optimizes blending 134*61046927SAndroid Build Coastguard Worker * calculations in some applications. 135*61046927SAndroid Build Coastguard Worker */ 136*61046927SAndroid Build Coastguard Worker unsigned rt0_w_1 : 1; 137*61046927SAndroid Build Coastguard Worker 138*61046927SAndroid Build Coastguard Worker /* If set, the API fragment shader wants to write depth/stencil respectively. 139*61046927SAndroid Build Coastguard Worker * This happens in the epilog for correctness when the epilog discards. 140*61046927SAndroid Build Coastguard Worker */ 141*61046927SAndroid Build Coastguard Worker unsigned write_z : 1; 142*61046927SAndroid Build Coastguard Worker unsigned write_s : 1; 143*61046927SAndroid Build Coastguard Worker 144*61046927SAndroid Build Coastguard Worker /* Whether the fragment prolog or main fragment shader already ran tests due 145*61046927SAndroid Build Coastguard Worker * to early_fragment_tests. In this case, the epilog must not run tests. 146*61046927SAndroid Build Coastguard Worker */ 147*61046927SAndroid Build Coastguard Worker unsigned already_ran_zs : 1; 148*61046927SAndroid Build Coastguard Worker 149*61046927SAndroid Build Coastguard Worker /* Whether the main fragment shader ran tests before discards due to 150*61046927SAndroid Build Coastguard Worker * early_fragment_tests. In this case, the epilog must mask the stores in 151*61046927SAndroid Build Coastguard Worker * software instead. 152*61046927SAndroid Build Coastguard Worker */ 153*61046927SAndroid Build Coastguard Worker bool sample_mask_after_force_early : 1; 154*61046927SAndroid Build Coastguard Worker 155*61046927SAndroid Build Coastguard Worker unsigned padding : 1; 156*61046927SAndroid Build Coastguard Worker }; 157*61046927SAndroid Build Coastguard Worker static_assert(sizeof(struct agx_fs_epilog_link_info) == 4, "packed"); 158*61046927SAndroid Build Coastguard Worker 159*61046927SAndroid Build Coastguard Worker struct agx_fs_epilog_key { 160*61046927SAndroid Build Coastguard Worker struct agx_fs_epilog_link_info link; 161*61046927SAndroid Build Coastguard Worker 162*61046927SAndroid Build Coastguard Worker /* Blend state. Blending happens in the epilog. */ 163*61046927SAndroid Build Coastguard Worker struct agx_blend_key blend; 164*61046927SAndroid Build Coastguard Worker 165*61046927SAndroid Build Coastguard Worker /* Tilebuffer configuration */ 166*61046927SAndroid Build Coastguard Worker enum pipe_format rt_formats[8]; 167*61046927SAndroid Build Coastguard Worker uint8_t nr_samples; 168*61046927SAndroid Build Coastguard Worker bool force_small_tile; 169*61046927SAndroid Build Coastguard Worker }; 170*61046927SAndroid Build Coastguard Worker 171*61046927SAndroid Build Coastguard Worker void agx_nir_vs_prolog(struct nir_builder *b, const void *key_); 172*61046927SAndroid Build Coastguard Worker void agx_nir_fs_epilog(struct nir_builder *b, const void *key_); 173*61046927SAndroid Build Coastguard Worker void agx_nir_fs_prolog(struct nir_builder *b, const void *key_); 174*61046927SAndroid Build Coastguard Worker 175*61046927SAndroid Build Coastguard Worker bool agx_nir_lower_vs_input_to_prolog(nir_shader *s, 176*61046927SAndroid Build Coastguard Worker BITSET_WORD *attrib_components_read); 177*61046927SAndroid Build Coastguard Worker 178*61046927SAndroid Build Coastguard Worker bool agx_nir_lower_fs_output_to_epilog(nir_shader *s, 179*61046927SAndroid Build Coastguard Worker struct agx_fs_epilog_link_info *out); 180*61046927SAndroid Build Coastguard Worker 181*61046927SAndroid Build Coastguard Worker bool agx_nir_lower_fs_active_samples_to_register(nir_shader *s); 182