xref: /aosp_15_r20/external/mesa3d/src/broadcom/vulkan/v3dvx_pipeline.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2021 Raspberry Pi Ltd
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "v3dv_private.h"
25*61046927SAndroid Build Coastguard Worker #include "broadcom/common/v3d_macros.h"
26*61046927SAndroid Build Coastguard Worker #include "broadcom/cle/v3dx_pack.h"
27*61046927SAndroid Build Coastguard Worker #include "broadcom/compiler/v3d_compiler.h"
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker static uint8_t
blend_factor(VkBlendFactor factor,bool dst_alpha_one,bool * needs_constants)30*61046927SAndroid Build Coastguard Worker blend_factor(VkBlendFactor factor, bool dst_alpha_one, bool *needs_constants)
31*61046927SAndroid Build Coastguard Worker {
32*61046927SAndroid Build Coastguard Worker    switch (factor) {
33*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_ZERO:
34*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_ONE:
35*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_SRC_COLOR:
36*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR:
37*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_DST_COLOR:
38*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR:
39*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_SRC_ALPHA:
40*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA:
41*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE:
42*61046927SAndroid Build Coastguard Worker       return factor;
43*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_CONSTANT_COLOR:
44*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR:
45*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_CONSTANT_ALPHA:
46*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA:
47*61046927SAndroid Build Coastguard Worker       *needs_constants = true;
48*61046927SAndroid Build Coastguard Worker       return factor;
49*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_DST_ALPHA:
50*61046927SAndroid Build Coastguard Worker       return dst_alpha_one ? V3D_BLEND_FACTOR_ONE :
51*61046927SAndroid Build Coastguard Worker                              V3D_BLEND_FACTOR_DST_ALPHA;
52*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA:
53*61046927SAndroid Build Coastguard Worker       return dst_alpha_one ? V3D_BLEND_FACTOR_ZERO :
54*61046927SAndroid Build Coastguard Worker                              V3D_BLEND_FACTOR_INV_DST_ALPHA;
55*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_SRC1_COLOR:
56*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR:
57*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_SRC1_ALPHA:
58*61046927SAndroid Build Coastguard Worker    case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA:
59*61046927SAndroid Build Coastguard Worker       unreachable("Invalid blend factor: dual source blending not supported.");
60*61046927SAndroid Build Coastguard Worker    default:
61*61046927SAndroid Build Coastguard Worker       unreachable("Unknown blend factor.");
62*61046927SAndroid Build Coastguard Worker    }
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker 
65*61046927SAndroid Build Coastguard Worker static void
pack_blend(struct v3dv_pipeline * pipeline,const VkPipelineColorBlendStateCreateInfo * cb_info)66*61046927SAndroid Build Coastguard Worker pack_blend(struct v3dv_pipeline *pipeline,
67*61046927SAndroid Build Coastguard Worker            const VkPipelineColorBlendStateCreateInfo *cb_info)
68*61046927SAndroid Build Coastguard Worker {
69*61046927SAndroid Build Coastguard Worker    /* By default, we are not enabling blending and all color channel writes are
70*61046927SAndroid Build Coastguard Worker     * enabled. Color write enables are independent of whether blending is
71*61046927SAndroid Build Coastguard Worker     * enabled or not.
72*61046927SAndroid Build Coastguard Worker     *
73*61046927SAndroid Build Coastguard Worker     * Vulkan specifies color write masks so that bits set correspond to
74*61046927SAndroid Build Coastguard Worker     * enabled channels. Our hardware does it the other way around.
75*61046927SAndroid Build Coastguard Worker     */
76*61046927SAndroid Build Coastguard Worker    pipeline->blend.enables = 0;
77*61046927SAndroid Build Coastguard Worker    pipeline->blend.color_write_masks = 0; /* All channels enabled */
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker    if (!cb_info)
80*61046927SAndroid Build Coastguard Worker       return;
81*61046927SAndroid Build Coastguard Worker 
82*61046927SAndroid Build Coastguard Worker    const struct vk_render_pass_state *ri = &pipeline->rendering_info;
83*61046927SAndroid Build Coastguard Worker    if (ri->color_attachment_count == 0)
84*61046927SAndroid Build Coastguard Worker       return;
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker    assert(ri->color_attachment_count == cb_info->attachmentCount);
87*61046927SAndroid Build Coastguard Worker    pipeline->blend.needs_color_constants = false;
88*61046927SAndroid Build Coastguard Worker    uint32_t color_write_masks = 0;
89*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < ri->color_attachment_count; i++) {
90*61046927SAndroid Build Coastguard Worker       const VkPipelineColorBlendAttachmentState *b_state =
91*61046927SAndroid Build Coastguard Worker          &cb_info->pAttachments[i];
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker       const VkFormat vk_format = ri->color_attachment_formats[i];
94*61046927SAndroid Build Coastguard Worker       if (vk_format == VK_FORMAT_UNDEFINED)
95*61046927SAndroid Build Coastguard Worker          continue;
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker       color_write_masks |= (~b_state->colorWriteMask & 0xf) << (4 * i);
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker       if (!b_state->blendEnable)
100*61046927SAndroid Build Coastguard Worker          continue;
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker       const struct v3dv_format *format = v3dX(get_format)(vk_format);
103*61046927SAndroid Build Coastguard Worker 
104*61046927SAndroid Build Coastguard Worker       /* We only do blending with render pass attachments, so we should not have
105*61046927SAndroid Build Coastguard Worker        * multiplanar images here
106*61046927SAndroid Build Coastguard Worker        */
107*61046927SAndroid Build Coastguard Worker       assert(format->plane_count == 1);
108*61046927SAndroid Build Coastguard Worker       bool dst_alpha_one = (format->planes[0].swizzle[3] == PIPE_SWIZZLE_1);
109*61046927SAndroid Build Coastguard Worker 
110*61046927SAndroid Build Coastguard Worker       uint8_t rt_mask = 1 << i;
111*61046927SAndroid Build Coastguard Worker       pipeline->blend.enables |= rt_mask;
112*61046927SAndroid Build Coastguard Worker 
113*61046927SAndroid Build Coastguard Worker       v3dvx_pack(pipeline->blend.cfg[i], BLEND_CFG, config) {
114*61046927SAndroid Build Coastguard Worker          config.render_target_mask = rt_mask;
115*61046927SAndroid Build Coastguard Worker 
116*61046927SAndroid Build Coastguard Worker          config.color_blend_mode = b_state->colorBlendOp;
117*61046927SAndroid Build Coastguard Worker          config.color_blend_dst_factor =
118*61046927SAndroid Build Coastguard Worker             blend_factor(b_state->dstColorBlendFactor, dst_alpha_one,
119*61046927SAndroid Build Coastguard Worker                          &pipeline->blend.needs_color_constants);
120*61046927SAndroid Build Coastguard Worker          config.color_blend_src_factor =
121*61046927SAndroid Build Coastguard Worker             blend_factor(b_state->srcColorBlendFactor, dst_alpha_one,
122*61046927SAndroid Build Coastguard Worker                          &pipeline->blend.needs_color_constants);
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker          config.alpha_blend_mode = b_state->alphaBlendOp;
125*61046927SAndroid Build Coastguard Worker          config.alpha_blend_dst_factor =
126*61046927SAndroid Build Coastguard Worker             blend_factor(b_state->dstAlphaBlendFactor, dst_alpha_one,
127*61046927SAndroid Build Coastguard Worker                          &pipeline->blend.needs_color_constants);
128*61046927SAndroid Build Coastguard Worker          config.alpha_blend_src_factor =
129*61046927SAndroid Build Coastguard Worker             blend_factor(b_state->srcAlphaBlendFactor, dst_alpha_one,
130*61046927SAndroid Build Coastguard Worker                          &pipeline->blend.needs_color_constants);
131*61046927SAndroid Build Coastguard Worker       }
132*61046927SAndroid Build Coastguard Worker    }
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker    pipeline->blend.color_write_masks = color_write_masks;
135*61046927SAndroid Build Coastguard Worker }
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker /* This requires that pack_blend() had been called before so we can set
138*61046927SAndroid Build Coastguard Worker  * the overall blend enable bit in the CFG_BITS packet.
139*61046927SAndroid Build Coastguard Worker  */
140*61046927SAndroid Build Coastguard Worker static void
pack_cfg_bits(struct v3dv_pipeline * pipeline,const VkPipelineDepthStencilStateCreateInfo * ds_info,const VkPipelineRasterizationStateCreateInfo * rs_info,const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT * pv_info,const VkPipelineRasterizationLineStateCreateInfoEXT * ls_info,const VkPipelineMultisampleStateCreateInfo * ms_info)141*61046927SAndroid Build Coastguard Worker pack_cfg_bits(struct v3dv_pipeline *pipeline,
142*61046927SAndroid Build Coastguard Worker               const VkPipelineDepthStencilStateCreateInfo *ds_info,
143*61046927SAndroid Build Coastguard Worker               const VkPipelineRasterizationStateCreateInfo *rs_info,
144*61046927SAndroid Build Coastguard Worker               const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info,
145*61046927SAndroid Build Coastguard Worker               const VkPipelineRasterizationLineStateCreateInfoEXT *ls_info,
146*61046927SAndroid Build Coastguard Worker               const VkPipelineMultisampleStateCreateInfo *ms_info)
147*61046927SAndroid Build Coastguard Worker {
148*61046927SAndroid Build Coastguard Worker    assert(sizeof(pipeline->cfg_bits) == cl_packet_length(CFG_BITS));
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker    pipeline->msaa =
151*61046927SAndroid Build Coastguard Worker       ms_info && ms_info->rasterizationSamples > VK_SAMPLE_COUNT_1_BIT;
152*61046927SAndroid Build Coastguard Worker 
153*61046927SAndroid Build Coastguard Worker    v3dvx_pack(pipeline->cfg_bits, CFG_BITS, config) {
154*61046927SAndroid Build Coastguard Worker       /* This is required to pass line rasterization tests in CTS while
155*61046927SAndroid Build Coastguard Worker        * exposing, at least, a minimum of 4-bits of subpixel precision
156*61046927SAndroid Build Coastguard Worker        * (the minimum requirement).
157*61046927SAndroid Build Coastguard Worker        */
158*61046927SAndroid Build Coastguard Worker       if (ls_info &&
159*61046927SAndroid Build Coastguard Worker           ls_info->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT)
160*61046927SAndroid Build Coastguard Worker          config.line_rasterization = V3D_LINE_RASTERIZATION_DIAMOND_EXIT;
161*61046927SAndroid Build Coastguard Worker       else
162*61046927SAndroid Build Coastguard Worker          config.line_rasterization = V3D_LINE_RASTERIZATION_PERP_END_CAPS;
163*61046927SAndroid Build Coastguard Worker 
164*61046927SAndroid Build Coastguard Worker       if (rs_info && rs_info->polygonMode != VK_POLYGON_MODE_FILL) {
165*61046927SAndroid Build Coastguard Worker          config.direct3d_wireframe_triangles_mode = true;
166*61046927SAndroid Build Coastguard Worker          config.direct3d_point_fill_mode =
167*61046927SAndroid Build Coastguard Worker             rs_info->polygonMode == VK_POLYGON_MODE_POINT;
168*61046927SAndroid Build Coastguard Worker       }
169*61046927SAndroid Build Coastguard Worker 
170*61046927SAndroid Build Coastguard Worker       /* diamond-exit rasterization does not support oversample */
171*61046927SAndroid Build Coastguard Worker       config.rasterizer_oversample_mode =
172*61046927SAndroid Build Coastguard Worker          (config.line_rasterization == V3D_LINE_RASTERIZATION_PERP_END_CAPS &&
173*61046927SAndroid Build Coastguard Worker           pipeline->msaa) ? 1 : 0;
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker       /* From the Vulkan spec:
176*61046927SAndroid Build Coastguard Worker        *
177*61046927SAndroid Build Coastguard Worker        *   "Provoking Vertex:
178*61046927SAndroid Build Coastguard Worker        *
179*61046927SAndroid Build Coastguard Worker        *       The vertex in a primitive from which flat shaded attribute
180*61046927SAndroid Build Coastguard Worker        *       values are taken. This is generally the “first” vertex in the
181*61046927SAndroid Build Coastguard Worker        *       primitive, and depends on the primitive topology."
182*61046927SAndroid Build Coastguard Worker        *
183*61046927SAndroid Build Coastguard Worker        * First vertex is the Direct3D style for provoking vertex. OpenGL uses
184*61046927SAndroid Build Coastguard Worker        * the last vertex by default.
185*61046927SAndroid Build Coastguard Worker        */
186*61046927SAndroid Build Coastguard Worker       if (pv_info) {
187*61046927SAndroid Build Coastguard Worker          config.direct3d_provoking_vertex =
188*61046927SAndroid Build Coastguard Worker             pv_info->provokingVertexMode ==
189*61046927SAndroid Build Coastguard Worker                VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
190*61046927SAndroid Build Coastguard Worker       } else {
191*61046927SAndroid Build Coastguard Worker          config.direct3d_provoking_vertex = true;
192*61046927SAndroid Build Coastguard Worker       }
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker       config.blend_enable = pipeline->blend.enables != 0;
195*61046927SAndroid Build Coastguard Worker 
196*61046927SAndroid Build Coastguard Worker #if V3D_VERSION >= 71
197*61046927SAndroid Build Coastguard Worker       /* From the Vulkan spec:
198*61046927SAndroid Build Coastguard Worker        *
199*61046927SAndroid Build Coastguard Worker        *    "depthClampEnable controls whether to clamp the fragment’s depth
200*61046927SAndroid Build Coastguard Worker        *     values as described in Depth Test. If the pipeline is not created
201*61046927SAndroid Build Coastguard Worker        *     with VkPipelineRasterizationDepthClipStateCreateInfoEXT present
202*61046927SAndroid Build Coastguard Worker        *     then enabling depth clamp will also disable clipping primitives to
203*61046927SAndroid Build Coastguard Worker        *     the z planes of the frustrum as described in Primitive Clipping.
204*61046927SAndroid Build Coastguard Worker        *     Otherwise depth clipping is controlled by the state set in
205*61046927SAndroid Build Coastguard Worker        *     VkPipelineRasterizationDepthClipStateCreateInfoEXT."
206*61046927SAndroid Build Coastguard Worker        */
207*61046927SAndroid Build Coastguard Worker       bool z_clamp_enable = rs_info && rs_info->depthClampEnable;
208*61046927SAndroid Build Coastguard Worker       bool z_clip_enable = false;
209*61046927SAndroid Build Coastguard Worker       const VkPipelineRasterizationDepthClipStateCreateInfoEXT *clip_info =
210*61046927SAndroid Build Coastguard Worker          rs_info ? vk_find_struct_const(rs_info->pNext,
211*61046927SAndroid Build Coastguard Worker                                         PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT) :
212*61046927SAndroid Build Coastguard Worker                    NULL;
213*61046927SAndroid Build Coastguard Worker       if (clip_info)
214*61046927SAndroid Build Coastguard Worker          z_clip_enable = clip_info->depthClipEnable;
215*61046927SAndroid Build Coastguard Worker       else if (!z_clamp_enable)
216*61046927SAndroid Build Coastguard Worker          z_clip_enable = true;
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker       if (z_clip_enable) {
219*61046927SAndroid Build Coastguard Worker          config.z_clipping_mode = pipeline->negative_one_to_one ?
220*61046927SAndroid Build Coastguard Worker 	    V3D_Z_CLIP_MODE_MIN_ONE_TO_ONE : V3D_Z_CLIP_MODE_ZERO_TO_ONE;
221*61046927SAndroid Build Coastguard Worker       } else {
222*61046927SAndroid Build Coastguard Worker          config.z_clipping_mode = V3D_Z_CLIP_MODE_NONE;
223*61046927SAndroid Build Coastguard Worker       }
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker       config.z_clamp_mode = z_clamp_enable;
226*61046927SAndroid Build Coastguard Worker #endif
227*61046927SAndroid Build Coastguard Worker    };
228*61046927SAndroid Build Coastguard Worker }
229*61046927SAndroid Build Coastguard Worker 
230*61046927SAndroid Build Coastguard Worker uint32_t
v3dX(translate_stencil_op)231*61046927SAndroid Build Coastguard Worker v3dX(translate_stencil_op)(VkStencilOp op)
232*61046927SAndroid Build Coastguard Worker {
233*61046927SAndroid Build Coastguard Worker    switch (op) {
234*61046927SAndroid Build Coastguard Worker    case VK_STENCIL_OP_KEEP:
235*61046927SAndroid Build Coastguard Worker       return V3D_STENCIL_OP_KEEP;
236*61046927SAndroid Build Coastguard Worker    case VK_STENCIL_OP_ZERO:
237*61046927SAndroid Build Coastguard Worker       return V3D_STENCIL_OP_ZERO;
238*61046927SAndroid Build Coastguard Worker    case VK_STENCIL_OP_REPLACE:
239*61046927SAndroid Build Coastguard Worker       return V3D_STENCIL_OP_REPLACE;
240*61046927SAndroid Build Coastguard Worker    case VK_STENCIL_OP_INCREMENT_AND_CLAMP:
241*61046927SAndroid Build Coastguard Worker       return V3D_STENCIL_OP_INCR;
242*61046927SAndroid Build Coastguard Worker    case VK_STENCIL_OP_DECREMENT_AND_CLAMP:
243*61046927SAndroid Build Coastguard Worker       return V3D_STENCIL_OP_DECR;
244*61046927SAndroid Build Coastguard Worker    case VK_STENCIL_OP_INVERT:
245*61046927SAndroid Build Coastguard Worker       return V3D_STENCIL_OP_INVERT;
246*61046927SAndroid Build Coastguard Worker    case VK_STENCIL_OP_INCREMENT_AND_WRAP:
247*61046927SAndroid Build Coastguard Worker       return V3D_STENCIL_OP_INCWRAP;
248*61046927SAndroid Build Coastguard Worker    case VK_STENCIL_OP_DECREMENT_AND_WRAP:
249*61046927SAndroid Build Coastguard Worker       return V3D_STENCIL_OP_DECWRAP;
250*61046927SAndroid Build Coastguard Worker    default:
251*61046927SAndroid Build Coastguard Worker       unreachable("bad stencil op");
252*61046927SAndroid Build Coastguard Worker    }
253*61046927SAndroid Build Coastguard Worker }
254*61046927SAndroid Build Coastguard Worker 
255*61046927SAndroid Build Coastguard Worker static void
pack_single_stencil_cfg(struct v3dv_pipeline * pipeline,uint8_t * stencil_cfg,bool is_front,bool is_back,const VkStencilOpState * stencil_state,const struct vk_graphics_pipeline_state * state)256*61046927SAndroid Build Coastguard Worker pack_single_stencil_cfg(struct v3dv_pipeline *pipeline,
257*61046927SAndroid Build Coastguard Worker                         uint8_t *stencil_cfg,
258*61046927SAndroid Build Coastguard Worker                         bool is_front,
259*61046927SAndroid Build Coastguard Worker                         bool is_back,
260*61046927SAndroid Build Coastguard Worker                         const VkStencilOpState *stencil_state,
261*61046927SAndroid Build Coastguard Worker                         const struct vk_graphics_pipeline_state *state)
262*61046927SAndroid Build Coastguard Worker {
263*61046927SAndroid Build Coastguard Worker    /* From the Vulkan spec:
264*61046927SAndroid Build Coastguard Worker     *
265*61046927SAndroid Build Coastguard Worker     *   "Reference is an integer reference value that is used in the unsigned
266*61046927SAndroid Build Coastguard Worker     *    stencil comparison. The reference value used by stencil comparison
267*61046927SAndroid Build Coastguard Worker     *    must be within the range [0,2^s-1] , where s is the number of bits in
268*61046927SAndroid Build Coastguard Worker     *    the stencil framebuffer attachment, otherwise the reference value is
269*61046927SAndroid Build Coastguard Worker     *    considered undefined."
270*61046927SAndroid Build Coastguard Worker     *
271*61046927SAndroid Build Coastguard Worker     * In our case, 's' is always 8, so we clamp to that to prevent our packing
272*61046927SAndroid Build Coastguard Worker     * functions to assert in debug mode if they see larger values.
273*61046927SAndroid Build Coastguard Worker     */
274*61046927SAndroid Build Coastguard Worker    v3dvx_pack(stencil_cfg, STENCIL_CFG, config) {
275*61046927SAndroid Build Coastguard Worker       config.front_config = is_front;
276*61046927SAndroid Build Coastguard Worker       config.back_config = is_back;
277*61046927SAndroid Build Coastguard Worker       config.stencil_write_mask = stencil_state->writeMask & 0xff;
278*61046927SAndroid Build Coastguard Worker       config.stencil_test_mask = stencil_state->compareMask & 0xff;
279*61046927SAndroid Build Coastguard Worker       config.stencil_test_function = stencil_state->compareOp;
280*61046927SAndroid Build Coastguard Worker       config.stencil_pass_op =
281*61046927SAndroid Build Coastguard Worker          v3dX(translate_stencil_op)(stencil_state->passOp);
282*61046927SAndroid Build Coastguard Worker       config.depth_test_fail_op =
283*61046927SAndroid Build Coastguard Worker          v3dX(translate_stencil_op)(stencil_state->depthFailOp);
284*61046927SAndroid Build Coastguard Worker       config.stencil_test_fail_op =
285*61046927SAndroid Build Coastguard Worker          v3dX(translate_stencil_op)(stencil_state->failOp);
286*61046927SAndroid Build Coastguard Worker       config.stencil_ref_value = stencil_state->reference & 0xff;
287*61046927SAndroid Build Coastguard Worker    }
288*61046927SAndroid Build Coastguard Worker }
289*61046927SAndroid Build Coastguard Worker 
290*61046927SAndroid Build Coastguard Worker static void
pack_stencil_cfg(struct v3dv_pipeline * pipeline,const VkPipelineDepthStencilStateCreateInfo * ds_info,const struct vk_graphics_pipeline_state * state)291*61046927SAndroid Build Coastguard Worker pack_stencil_cfg(struct v3dv_pipeline *pipeline,
292*61046927SAndroid Build Coastguard Worker                  const VkPipelineDepthStencilStateCreateInfo *ds_info,
293*61046927SAndroid Build Coastguard Worker                  const struct vk_graphics_pipeline_state *state)
294*61046927SAndroid Build Coastguard Worker {
295*61046927SAndroid Build Coastguard Worker    assert(sizeof(pipeline->stencil_cfg) == 2 * cl_packet_length(STENCIL_CFG));
296*61046927SAndroid Build Coastguard Worker 
297*61046927SAndroid Build Coastguard Worker    if (!ds_info || !ds_info->stencilTestEnable)
298*61046927SAndroid Build Coastguard Worker       return;
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker    const struct vk_render_pass_state *ri = &pipeline->rendering_info;
301*61046927SAndroid Build Coastguard Worker    if (ri->stencil_attachment_format == VK_FORMAT_UNDEFINED)
302*61046927SAndroid Build Coastguard Worker       return;
303*61046927SAndroid Build Coastguard Worker 
304*61046927SAndroid Build Coastguard Worker    const bool any_dynamic_stencil_states =
305*61046927SAndroid Build Coastguard Worker       BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ||
306*61046927SAndroid Build Coastguard Worker       BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
307*61046927SAndroid Build Coastguard Worker       BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE) ||
308*61046927SAndroid Build Coastguard Worker       BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) ||
309*61046927SAndroid Build Coastguard Worker       BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_OP);
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker    /* If front != back or we have dynamic stencil state we can't emit a single
312*61046927SAndroid Build Coastguard Worker     * packet for both faces.
313*61046927SAndroid Build Coastguard Worker     */
314*61046927SAndroid Build Coastguard Worker    bool needs_front_and_back = false;
315*61046927SAndroid Build Coastguard Worker    if ((any_dynamic_stencil_states) ||
316*61046927SAndroid Build Coastguard Worker        memcmp(&ds_info->front, &ds_info->back, sizeof(ds_info->front))) {
317*61046927SAndroid Build Coastguard Worker       needs_front_and_back = true;
318*61046927SAndroid Build Coastguard Worker    }
319*61046927SAndroid Build Coastguard Worker 
320*61046927SAndroid Build Coastguard Worker    /* If the front and back configurations are the same we can emit both with
321*61046927SAndroid Build Coastguard Worker     * a single packet.
322*61046927SAndroid Build Coastguard Worker     */
323*61046927SAndroid Build Coastguard Worker    pipeline->emit_stencil_cfg[0] = true;
324*61046927SAndroid Build Coastguard Worker    if (!needs_front_and_back) {
325*61046927SAndroid Build Coastguard Worker       pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[0],
326*61046927SAndroid Build Coastguard Worker                               true, true, &ds_info->front, state);
327*61046927SAndroid Build Coastguard Worker    } else {
328*61046927SAndroid Build Coastguard Worker       pipeline->emit_stencil_cfg[1] = true;
329*61046927SAndroid Build Coastguard Worker       pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[0],
330*61046927SAndroid Build Coastguard Worker                               true, false, &ds_info->front, state);
331*61046927SAndroid Build Coastguard Worker       pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[1],
332*61046927SAndroid Build Coastguard Worker                               false, true, &ds_info->back, state);
333*61046927SAndroid Build Coastguard Worker    }
334*61046927SAndroid Build Coastguard Worker }
335*61046927SAndroid Build Coastguard Worker 
336*61046927SAndroid Build Coastguard Worker 
337*61046927SAndroid Build Coastguard Worker /* FIXME: Now that we are passing the vk_graphics_pipeline_state we could
338*61046927SAndroid Build Coastguard Worker  * avoid passing all those parameters. But doing that we would need to change
339*61046927SAndroid Build Coastguard Worker  * all the code that uses the VkXXX structures, and use instead the equivalent
340*61046927SAndroid Build Coastguard Worker  * vk_xxx
341*61046927SAndroid Build Coastguard Worker  */
342*61046927SAndroid Build Coastguard Worker void
v3dX(pipeline_pack_state)343*61046927SAndroid Build Coastguard Worker v3dX(pipeline_pack_state)(struct v3dv_pipeline *pipeline,
344*61046927SAndroid Build Coastguard Worker                           const VkPipelineColorBlendStateCreateInfo *cb_info,
345*61046927SAndroid Build Coastguard Worker                           const VkPipelineDepthStencilStateCreateInfo *ds_info,
346*61046927SAndroid Build Coastguard Worker                           const VkPipelineRasterizationStateCreateInfo *rs_info,
347*61046927SAndroid Build Coastguard Worker                           const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info,
348*61046927SAndroid Build Coastguard Worker                           const VkPipelineRasterizationLineStateCreateInfoEXT *ls_info,
349*61046927SAndroid Build Coastguard Worker                           const VkPipelineMultisampleStateCreateInfo *ms_info,
350*61046927SAndroid Build Coastguard Worker                           const struct vk_graphics_pipeline_state *state)
351*61046927SAndroid Build Coastguard Worker {
352*61046927SAndroid Build Coastguard Worker    pack_blend(pipeline, cb_info);
353*61046927SAndroid Build Coastguard Worker    pack_cfg_bits(pipeline, ds_info, rs_info, pv_info, ls_info, ms_info);
354*61046927SAndroid Build Coastguard Worker    pack_stencil_cfg(pipeline, ds_info, state);
355*61046927SAndroid Build Coastguard Worker }
356*61046927SAndroid Build Coastguard Worker 
357*61046927SAndroid Build Coastguard Worker static void
pack_shader_state_record(struct v3dv_pipeline * pipeline)358*61046927SAndroid Build Coastguard Worker pack_shader_state_record(struct v3dv_pipeline *pipeline)
359*61046927SAndroid Build Coastguard Worker {
360*61046927SAndroid Build Coastguard Worker    /* To siplify the code we ignore here GL_SHADER_STATE_RECORD_DRAW_INDEX
361*61046927SAndroid Build Coastguard Worker     * used with 2712D0, since we know that has the same size as the regular
362*61046927SAndroid Build Coastguard Worker     * version.
363*61046927SAndroid Build Coastguard Worker     */
364*61046927SAndroid Build Coastguard Worker    assert(sizeof(pipeline->shader_state_record) >=
365*61046927SAndroid Build Coastguard Worker           cl_packet_length(GL_SHADER_STATE_RECORD));
366*61046927SAndroid Build Coastguard Worker 
367*61046927SAndroid Build Coastguard Worker    struct v3d_fs_prog_data *prog_data_fs =
368*61046927SAndroid Build Coastguard Worker       pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT]->prog_data.fs;
369*61046927SAndroid Build Coastguard Worker 
370*61046927SAndroid Build Coastguard Worker    struct v3d_vs_prog_data *prog_data_vs =
371*61046927SAndroid Build Coastguard Worker       pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX]->prog_data.vs;
372*61046927SAndroid Build Coastguard Worker 
373*61046927SAndroid Build Coastguard Worker    struct v3d_vs_prog_data *prog_data_vs_bin =
374*61046927SAndroid Build Coastguard Worker       pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX_BIN]->prog_data.vs;
375*61046927SAndroid Build Coastguard Worker 
376*61046927SAndroid Build Coastguard Worker    bool point_size_in_shaded_vertex_data;
377*61046927SAndroid Build Coastguard Worker    if (!pipeline->has_gs) {
378*61046927SAndroid Build Coastguard Worker       struct v3d_vs_prog_data *prog_data_vs =
379*61046927SAndroid Build Coastguard Worker          pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX]->prog_data.vs;
380*61046927SAndroid Build Coastguard Worker          point_size_in_shaded_vertex_data = prog_data_vs->writes_psiz;
381*61046927SAndroid Build Coastguard Worker    } else {
382*61046927SAndroid Build Coastguard Worker       struct v3d_gs_prog_data *prog_data_gs =
383*61046927SAndroid Build Coastguard Worker          pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY]->prog_data.gs;
384*61046927SAndroid Build Coastguard Worker          point_size_in_shaded_vertex_data = prog_data_gs->writes_psiz;
385*61046927SAndroid Build Coastguard Worker    }
386*61046927SAndroid Build Coastguard Worker 
387*61046927SAndroid Build Coastguard Worker    /* Note: we are not packing addresses, as we need the job (see
388*61046927SAndroid Build Coastguard Worker     * cl_pack_emit_reloc). Additionally uniforms can't be filled up at this
389*61046927SAndroid Build Coastguard Worker     * point as they depend on dynamic info that can be set after create the
390*61046927SAndroid Build Coastguard Worker     * pipeline (like viewport), . Would need to be filled later, so we are
391*61046927SAndroid Build Coastguard Worker     * doing a partial prepacking.
392*61046927SAndroid Build Coastguard Worker     */
393*61046927SAndroid Build Coastguard Worker #if V3D_VERSION >= 71
394*61046927SAndroid Build Coastguard Worker    /* 2712D0 (V3D 7.1.10) has included draw index and base vertex, shuffling all
395*61046927SAndroid Build Coastguard Worker     * the fields in the packet. Since the versioning framework doesn't handle
396*61046927SAndroid Build Coastguard Worker     * revision numbers, the XML has a different shader state record packet
397*61046927SAndroid Build Coastguard Worker     * including the new fields and we device at run time which packet we need
398*61046927SAndroid Build Coastguard Worker     * to emit.
399*61046927SAndroid Build Coastguard Worker     */
400*61046927SAndroid Build Coastguard Worker    if (v3d_device_has_draw_index(&pipeline->device->devinfo)) {
401*61046927SAndroid Build Coastguard Worker       v3dvx_pack(pipeline->shader_state_record, GL_SHADER_STATE_RECORD_DRAW_INDEX, shader) {
402*61046927SAndroid Build Coastguard Worker          shader.enable_clipping = true;
403*61046927SAndroid Build Coastguard Worker          shader.point_size_in_shaded_vertex_data = point_size_in_shaded_vertex_data;
404*61046927SAndroid Build Coastguard Worker          shader.fragment_shader_does_z_writes = prog_data_fs->writes_z;
405*61046927SAndroid Build Coastguard Worker          shader.turn_off_early_z_test = prog_data_fs->disable_ez;
406*61046927SAndroid Build Coastguard Worker          shader.fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2 =
407*61046927SAndroid Build Coastguard Worker             prog_data_fs->uses_center_w;
408*61046927SAndroid Build Coastguard Worker          shader.enable_sample_rate_shading =
409*61046927SAndroid Build Coastguard Worker             pipeline->sample_rate_shading ||
410*61046927SAndroid Build Coastguard Worker             (pipeline->msaa && prog_data_fs->force_per_sample_msaa);
411*61046927SAndroid Build Coastguard Worker          shader.any_shader_reads_hardware_written_primitive_id = false;
412*61046927SAndroid Build Coastguard Worker          shader.do_scoreboard_wait_on_first_thread_switch =
413*61046927SAndroid Build Coastguard Worker             prog_data_fs->lock_scoreboard_on_first_thrsw;
414*61046927SAndroid Build Coastguard Worker          shader.disable_implicit_point_line_varyings =
415*61046927SAndroid Build Coastguard Worker             !prog_data_fs->uses_implicit_point_line_varyings;
416*61046927SAndroid Build Coastguard Worker          shader.number_of_varyings_in_fragment_shader = prog_data_fs->num_inputs;
417*61046927SAndroid Build Coastguard Worker          shader.coordinate_shader_input_vpm_segment_size = prog_data_vs_bin->vpm_input_size;
418*61046927SAndroid Build Coastguard Worker          shader.vertex_shader_input_vpm_segment_size = prog_data_vs->vpm_input_size;
419*61046927SAndroid Build Coastguard Worker          shader.coordinate_shader_output_vpm_segment_size = prog_data_vs_bin->vpm_output_size;
420*61046927SAndroid Build Coastguard Worker          shader.vertex_shader_output_vpm_segment_size = prog_data_vs->vpm_output_size;
421*61046927SAndroid Build Coastguard Worker          shader.min_coord_shader_input_segments_required_in_play =
422*61046927SAndroid Build Coastguard Worker             pipeline->vpm_cfg_bin.As;
423*61046927SAndroid Build Coastguard Worker          shader.min_vertex_shader_input_segments_required_in_play =
424*61046927SAndroid Build Coastguard Worker             pipeline->vpm_cfg.As;
425*61046927SAndroid Build Coastguard Worker          shader.min_coord_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size =
426*61046927SAndroid Build Coastguard Worker             pipeline->vpm_cfg_bin.Ve;
427*61046927SAndroid Build Coastguard Worker          shader.min_vertex_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size =
428*61046927SAndroid Build Coastguard Worker             pipeline->vpm_cfg.Ve;
429*61046927SAndroid Build Coastguard Worker          shader.coordinate_shader_4_way_threadable = prog_data_vs_bin->base.threads == 4;
430*61046927SAndroid Build Coastguard Worker          shader.vertex_shader_4_way_threadable = prog_data_vs->base.threads == 4;
431*61046927SAndroid Build Coastguard Worker          shader.fragment_shader_4_way_threadable = prog_data_fs->base.threads == 4;
432*61046927SAndroid Build Coastguard Worker          shader.coordinate_shader_start_in_final_thread_section = prog_data_vs_bin->base.single_seg;
433*61046927SAndroid Build Coastguard Worker          shader.vertex_shader_start_in_final_thread_section = prog_data_vs->base.single_seg;
434*61046927SAndroid Build Coastguard Worker          shader.fragment_shader_start_in_final_thread_section = prog_data_fs->base.single_seg;
435*61046927SAndroid Build Coastguard Worker          shader.vertex_id_read_by_coordinate_shader = prog_data_vs_bin->uses_vid;
436*61046927SAndroid Build Coastguard Worker          shader.base_instance_id_read_by_coordinate_shader = prog_data_vs_bin->uses_biid;
437*61046927SAndroid Build Coastguard Worker          shader.instance_id_read_by_coordinate_shader = prog_data_vs_bin->uses_iid;
438*61046927SAndroid Build Coastguard Worker          shader.vertex_id_read_by_vertex_shader = prog_data_vs->uses_vid;
439*61046927SAndroid Build Coastguard Worker          shader.base_instance_id_read_by_vertex_shader = prog_data_vs->uses_biid;
440*61046927SAndroid Build Coastguard Worker          shader.instance_id_read_by_vertex_shader = prog_data_vs->uses_iid;
441*61046927SAndroid Build Coastguard Worker       }
442*61046927SAndroid Build Coastguard Worker       return;
443*61046927SAndroid Build Coastguard Worker    }
444*61046927SAndroid Build Coastguard Worker #endif
445*61046927SAndroid Build Coastguard Worker 
446*61046927SAndroid Build Coastguard Worker    v3dvx_pack(pipeline->shader_state_record, GL_SHADER_STATE_RECORD, shader) {
447*61046927SAndroid Build Coastguard Worker       shader.enable_clipping = true;
448*61046927SAndroid Build Coastguard Worker       shader.point_size_in_shaded_vertex_data = point_size_in_shaded_vertex_data;
449*61046927SAndroid Build Coastguard Worker 
450*61046927SAndroid Build Coastguard Worker       /* Must be set if the shader modifies Z, discards, or modifies
451*61046927SAndroid Build Coastguard Worker        * the sample mask.  For any of these cases, the fragment
452*61046927SAndroid Build Coastguard Worker        * shader needs to write the Z value (even just discards).
453*61046927SAndroid Build Coastguard Worker        */
454*61046927SAndroid Build Coastguard Worker       shader.fragment_shader_does_z_writes = prog_data_fs->writes_z;
455*61046927SAndroid Build Coastguard Worker 
456*61046927SAndroid Build Coastguard Worker       /* Set if the EZ test must be disabled (due to shader side
457*61046927SAndroid Build Coastguard Worker        * effects and the early_z flag not being present in the
458*61046927SAndroid Build Coastguard Worker        * shader).
459*61046927SAndroid Build Coastguard Worker        */
460*61046927SAndroid Build Coastguard Worker       shader.turn_off_early_z_test = prog_data_fs->disable_ez;
461*61046927SAndroid Build Coastguard Worker 
462*61046927SAndroid Build Coastguard Worker       shader.fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2 =
463*61046927SAndroid Build Coastguard Worker          prog_data_fs->uses_center_w;
464*61046927SAndroid Build Coastguard Worker 
465*61046927SAndroid Build Coastguard Worker       /* The description for gl_SampleID states that if a fragment shader reads
466*61046927SAndroid Build Coastguard Worker        * it, then we should automatically activate per-sample shading. However,
467*61046927SAndroid Build Coastguard Worker        * the Vulkan spec also states that if a framebuffer has no attachments:
468*61046927SAndroid Build Coastguard Worker        *
469*61046927SAndroid Build Coastguard Worker        *    "The subpass continues to use the width, height, and layers of the
470*61046927SAndroid Build Coastguard Worker        *     framebuffer to define the dimensions of the rendering area, and the
471*61046927SAndroid Build Coastguard Worker        *     rasterizationSamples from each pipeline’s
472*61046927SAndroid Build Coastguard Worker        *     VkPipelineMultisampleStateCreateInfo to define the number of
473*61046927SAndroid Build Coastguard Worker        *     samples used in rasterization multisample rasterization."
474*61046927SAndroid Build Coastguard Worker        *
475*61046927SAndroid Build Coastguard Worker        * So in this scenario, if the pipeline doesn't enable multiple samples
476*61046927SAndroid Build Coastguard Worker        * but the fragment shader accesses gl_SampleID we would be requested
477*61046927SAndroid Build Coastguard Worker        * to do per-sample shading in single sample rasterization mode, which
478*61046927SAndroid Build Coastguard Worker        * is pointless, so just disable it in that case.
479*61046927SAndroid Build Coastguard Worker        */
480*61046927SAndroid Build Coastguard Worker       shader.enable_sample_rate_shading =
481*61046927SAndroid Build Coastguard Worker          pipeline->sample_rate_shading ||
482*61046927SAndroid Build Coastguard Worker          (pipeline->msaa && prog_data_fs->force_per_sample_msaa);
483*61046927SAndroid Build Coastguard Worker 
484*61046927SAndroid Build Coastguard Worker       shader.any_shader_reads_hardware_written_primitive_id = false;
485*61046927SAndroid Build Coastguard Worker 
486*61046927SAndroid Build Coastguard Worker       shader.do_scoreboard_wait_on_first_thread_switch =
487*61046927SAndroid Build Coastguard Worker          prog_data_fs->lock_scoreboard_on_first_thrsw;
488*61046927SAndroid Build Coastguard Worker       shader.disable_implicit_point_line_varyings =
489*61046927SAndroid Build Coastguard Worker          !prog_data_fs->uses_implicit_point_line_varyings;
490*61046927SAndroid Build Coastguard Worker 
491*61046927SAndroid Build Coastguard Worker       shader.number_of_varyings_in_fragment_shader =
492*61046927SAndroid Build Coastguard Worker          prog_data_fs->num_inputs;
493*61046927SAndroid Build Coastguard Worker 
494*61046927SAndroid Build Coastguard Worker       /* Note: see previous note about addresses */
495*61046927SAndroid Build Coastguard Worker       /* shader.coordinate_shader_code_address */
496*61046927SAndroid Build Coastguard Worker       /* shader.vertex_shader_code_address */
497*61046927SAndroid Build Coastguard Worker       /* shader.fragment_shader_code_address */
498*61046927SAndroid Build Coastguard Worker 
499*61046927SAndroid Build Coastguard Worker #if V3D_VERSION == 42
500*61046927SAndroid Build Coastguard Worker       shader.coordinate_shader_propagate_nans = true;
501*61046927SAndroid Build Coastguard Worker       shader.vertex_shader_propagate_nans = true;
502*61046927SAndroid Build Coastguard Worker       shader.fragment_shader_propagate_nans = true;
503*61046927SAndroid Build Coastguard Worker 
504*61046927SAndroid Build Coastguard Worker       /* FIXME: Use combined input/output size flag in the common case (also
505*61046927SAndroid Build Coastguard Worker        * on v3d, see v3dx_draw).
506*61046927SAndroid Build Coastguard Worker        */
507*61046927SAndroid Build Coastguard Worker       shader.coordinate_shader_has_separate_input_and_output_vpm_blocks =
508*61046927SAndroid Build Coastguard Worker          prog_data_vs_bin->separate_segments;
509*61046927SAndroid Build Coastguard Worker       shader.vertex_shader_has_separate_input_and_output_vpm_blocks =
510*61046927SAndroid Build Coastguard Worker          prog_data_vs->separate_segments;
511*61046927SAndroid Build Coastguard Worker       shader.coordinate_shader_input_vpm_segment_size =
512*61046927SAndroid Build Coastguard Worker          prog_data_vs_bin->separate_segments ?
513*61046927SAndroid Build Coastguard Worker          prog_data_vs_bin->vpm_input_size : 1;
514*61046927SAndroid Build Coastguard Worker       shader.vertex_shader_input_vpm_segment_size =
515*61046927SAndroid Build Coastguard Worker          prog_data_vs->separate_segments ?
516*61046927SAndroid Build Coastguard Worker          prog_data_vs->vpm_input_size : 1;
517*61046927SAndroid Build Coastguard Worker #endif
518*61046927SAndroid Build Coastguard Worker 
519*61046927SAndroid Build Coastguard Worker       /* On V3D 7.1 there isn't a specific flag to set if we are using
520*61046927SAndroid Build Coastguard Worker        * shared/separate segments or not. We just set the value of
521*61046927SAndroid Build Coastguard Worker        * vpm_input_size to 0, and set output to the max needed. That should be
522*61046927SAndroid Build Coastguard Worker        * already properly set on prog_data_vs_bin
523*61046927SAndroid Build Coastguard Worker        */
524*61046927SAndroid Build Coastguard Worker #if V3D_VERSION == 71
525*61046927SAndroid Build Coastguard Worker       shader.coordinate_shader_input_vpm_segment_size =
526*61046927SAndroid Build Coastguard Worker          prog_data_vs_bin->vpm_input_size;
527*61046927SAndroid Build Coastguard Worker       shader.vertex_shader_input_vpm_segment_size =
528*61046927SAndroid Build Coastguard Worker          prog_data_vs->vpm_input_size;
529*61046927SAndroid Build Coastguard Worker #endif
530*61046927SAndroid Build Coastguard Worker 
531*61046927SAndroid Build Coastguard Worker       shader.coordinate_shader_output_vpm_segment_size =
532*61046927SAndroid Build Coastguard Worker          prog_data_vs_bin->vpm_output_size;
533*61046927SAndroid Build Coastguard Worker       shader.vertex_shader_output_vpm_segment_size =
534*61046927SAndroid Build Coastguard Worker          prog_data_vs->vpm_output_size;
535*61046927SAndroid Build Coastguard Worker 
536*61046927SAndroid Build Coastguard Worker       /* Note: see previous note about addresses */
537*61046927SAndroid Build Coastguard Worker       /* shader.coordinate_shader_uniforms_address */
538*61046927SAndroid Build Coastguard Worker       /* shader.vertex_shader_uniforms_address */
539*61046927SAndroid Build Coastguard Worker       /* shader.fragment_shader_uniforms_address */
540*61046927SAndroid Build Coastguard Worker 
541*61046927SAndroid Build Coastguard Worker       shader.min_coord_shader_input_segments_required_in_play =
542*61046927SAndroid Build Coastguard Worker          pipeline->vpm_cfg_bin.As;
543*61046927SAndroid Build Coastguard Worker       shader.min_vertex_shader_input_segments_required_in_play =
544*61046927SAndroid Build Coastguard Worker          pipeline->vpm_cfg.As;
545*61046927SAndroid Build Coastguard Worker 
546*61046927SAndroid Build Coastguard Worker       shader.min_coord_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size =
547*61046927SAndroid Build Coastguard Worker          pipeline->vpm_cfg_bin.Ve;
548*61046927SAndroid Build Coastguard Worker       shader.min_vertex_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size =
549*61046927SAndroid Build Coastguard Worker          pipeline->vpm_cfg.Ve;
550*61046927SAndroid Build Coastguard Worker 
551*61046927SAndroid Build Coastguard Worker       shader.coordinate_shader_4_way_threadable =
552*61046927SAndroid Build Coastguard Worker          prog_data_vs_bin->base.threads == 4;
553*61046927SAndroid Build Coastguard Worker       shader.vertex_shader_4_way_threadable =
554*61046927SAndroid Build Coastguard Worker          prog_data_vs->base.threads == 4;
555*61046927SAndroid Build Coastguard Worker       shader.fragment_shader_4_way_threadable =
556*61046927SAndroid Build Coastguard Worker          prog_data_fs->base.threads == 4;
557*61046927SAndroid Build Coastguard Worker 
558*61046927SAndroid Build Coastguard Worker       shader.coordinate_shader_start_in_final_thread_section =
559*61046927SAndroid Build Coastguard Worker          prog_data_vs_bin->base.single_seg;
560*61046927SAndroid Build Coastguard Worker       shader.vertex_shader_start_in_final_thread_section =
561*61046927SAndroid Build Coastguard Worker          prog_data_vs->base.single_seg;
562*61046927SAndroid Build Coastguard Worker       shader.fragment_shader_start_in_final_thread_section =
563*61046927SAndroid Build Coastguard Worker          prog_data_fs->base.single_seg;
564*61046927SAndroid Build Coastguard Worker 
565*61046927SAndroid Build Coastguard Worker       shader.vertex_id_read_by_coordinate_shader =
566*61046927SAndroid Build Coastguard Worker          prog_data_vs_bin->uses_vid;
567*61046927SAndroid Build Coastguard Worker       shader.base_instance_id_read_by_coordinate_shader =
568*61046927SAndroid Build Coastguard Worker          prog_data_vs_bin->uses_biid;
569*61046927SAndroid Build Coastguard Worker       shader.instance_id_read_by_coordinate_shader =
570*61046927SAndroid Build Coastguard Worker          prog_data_vs_bin->uses_iid;
571*61046927SAndroid Build Coastguard Worker       shader.vertex_id_read_by_vertex_shader =
572*61046927SAndroid Build Coastguard Worker          prog_data_vs->uses_vid;
573*61046927SAndroid Build Coastguard Worker       shader.base_instance_id_read_by_vertex_shader =
574*61046927SAndroid Build Coastguard Worker          prog_data_vs->uses_biid;
575*61046927SAndroid Build Coastguard Worker       shader.instance_id_read_by_vertex_shader =
576*61046927SAndroid Build Coastguard Worker          prog_data_vs->uses_iid;
577*61046927SAndroid Build Coastguard Worker 
578*61046927SAndroid Build Coastguard Worker       /* Note: see previous note about addresses */
579*61046927SAndroid Build Coastguard Worker       /* shader.address_of_default_attribute_values */
580*61046927SAndroid Build Coastguard Worker    }
581*61046927SAndroid Build Coastguard Worker }
582*61046927SAndroid Build Coastguard Worker 
583*61046927SAndroid Build Coastguard Worker static void
pack_vcm_cache_size(struct v3dv_pipeline * pipeline)584*61046927SAndroid Build Coastguard Worker pack_vcm_cache_size(struct v3dv_pipeline *pipeline)
585*61046927SAndroid Build Coastguard Worker {
586*61046927SAndroid Build Coastguard Worker    assert(sizeof(pipeline->vcm_cache_size) ==
587*61046927SAndroid Build Coastguard Worker           cl_packet_length(VCM_CACHE_SIZE));
588*61046927SAndroid Build Coastguard Worker 
589*61046927SAndroid Build Coastguard Worker    v3dvx_pack(pipeline->vcm_cache_size, VCM_CACHE_SIZE, vcm) {
590*61046927SAndroid Build Coastguard Worker       vcm.number_of_16_vertex_batches_for_binning = pipeline->vpm_cfg_bin.Vc;
591*61046927SAndroid Build Coastguard Worker       vcm.number_of_16_vertex_batches_for_rendering = pipeline->vpm_cfg.Vc;
592*61046927SAndroid Build Coastguard Worker    }
593*61046927SAndroid Build Coastguard Worker }
594*61046927SAndroid Build Coastguard Worker 
595*61046927SAndroid Build Coastguard Worker /* As defined on the GL_SHADER_STATE_ATTRIBUTE_RECORD */
596*61046927SAndroid Build Coastguard Worker static uint8_t
get_attr_type(const struct util_format_description * desc)597*61046927SAndroid Build Coastguard Worker get_attr_type(const struct util_format_description *desc)
598*61046927SAndroid Build Coastguard Worker {
599*61046927SAndroid Build Coastguard Worker    uint32_t r_size = desc->channel[0].size;
600*61046927SAndroid Build Coastguard Worker    uint8_t attr_type = ATTRIBUTE_FLOAT;
601*61046927SAndroid Build Coastguard Worker 
602*61046927SAndroid Build Coastguard Worker    switch (desc->channel[0].type) {
603*61046927SAndroid Build Coastguard Worker    case UTIL_FORMAT_TYPE_FLOAT:
604*61046927SAndroid Build Coastguard Worker       if (r_size == 32) {
605*61046927SAndroid Build Coastguard Worker          attr_type = ATTRIBUTE_FLOAT;
606*61046927SAndroid Build Coastguard Worker       } else {
607*61046927SAndroid Build Coastguard Worker          assert(r_size == 16);
608*61046927SAndroid Build Coastguard Worker          attr_type = ATTRIBUTE_HALF_FLOAT;
609*61046927SAndroid Build Coastguard Worker       }
610*61046927SAndroid Build Coastguard Worker       break;
611*61046927SAndroid Build Coastguard Worker 
612*61046927SAndroid Build Coastguard Worker    case UTIL_FORMAT_TYPE_SIGNED:
613*61046927SAndroid Build Coastguard Worker    case UTIL_FORMAT_TYPE_UNSIGNED:
614*61046927SAndroid Build Coastguard Worker       switch (r_size) {
615*61046927SAndroid Build Coastguard Worker       case 32:
616*61046927SAndroid Build Coastguard Worker          attr_type = ATTRIBUTE_INT;
617*61046927SAndroid Build Coastguard Worker          break;
618*61046927SAndroid Build Coastguard Worker       case 16:
619*61046927SAndroid Build Coastguard Worker          attr_type = ATTRIBUTE_SHORT;
620*61046927SAndroid Build Coastguard Worker          break;
621*61046927SAndroid Build Coastguard Worker       case 10:
622*61046927SAndroid Build Coastguard Worker          attr_type = ATTRIBUTE_INT2_10_10_10;
623*61046927SAndroid Build Coastguard Worker          break;
624*61046927SAndroid Build Coastguard Worker       case 8:
625*61046927SAndroid Build Coastguard Worker          attr_type = ATTRIBUTE_BYTE;
626*61046927SAndroid Build Coastguard Worker          break;
627*61046927SAndroid Build Coastguard Worker       default:
628*61046927SAndroid Build Coastguard Worker          fprintf(stderr,
629*61046927SAndroid Build Coastguard Worker                  "format %s unsupported\n",
630*61046927SAndroid Build Coastguard Worker                  desc->name);
631*61046927SAndroid Build Coastguard Worker          attr_type = ATTRIBUTE_BYTE;
632*61046927SAndroid Build Coastguard Worker          abort();
633*61046927SAndroid Build Coastguard Worker       }
634*61046927SAndroid Build Coastguard Worker       break;
635*61046927SAndroid Build Coastguard Worker 
636*61046927SAndroid Build Coastguard Worker    default:
637*61046927SAndroid Build Coastguard Worker       fprintf(stderr,
638*61046927SAndroid Build Coastguard Worker               "format %s unsupported\n",
639*61046927SAndroid Build Coastguard Worker               desc->name);
640*61046927SAndroid Build Coastguard Worker       abort();
641*61046927SAndroid Build Coastguard Worker    }
642*61046927SAndroid Build Coastguard Worker 
643*61046927SAndroid Build Coastguard Worker    return attr_type;
644*61046927SAndroid Build Coastguard Worker }
645*61046927SAndroid Build Coastguard Worker 
646*61046927SAndroid Build Coastguard Worker static void
pack_shader_state_attribute_record(struct v3dv_pipeline * pipeline,uint32_t index,const VkVertexInputAttributeDescription * vi_desc)647*61046927SAndroid Build Coastguard Worker pack_shader_state_attribute_record(struct v3dv_pipeline *pipeline,
648*61046927SAndroid Build Coastguard Worker                                    uint32_t index,
649*61046927SAndroid Build Coastguard Worker                                    const VkVertexInputAttributeDescription *vi_desc)
650*61046927SAndroid Build Coastguard Worker {
651*61046927SAndroid Build Coastguard Worker    const uint32_t packet_length =
652*61046927SAndroid Build Coastguard Worker       cl_packet_length(GL_SHADER_STATE_ATTRIBUTE_RECORD);
653*61046927SAndroid Build Coastguard Worker 
654*61046927SAndroid Build Coastguard Worker    const struct util_format_description *desc =
655*61046927SAndroid Build Coastguard Worker       vk_format_description(vi_desc->format);
656*61046927SAndroid Build Coastguard Worker 
657*61046927SAndroid Build Coastguard Worker    uint32_t binding = vi_desc->binding;
658*61046927SAndroid Build Coastguard Worker 
659*61046927SAndroid Build Coastguard Worker    v3dvx_pack(&pipeline->vertex_attrs[index * packet_length],
660*61046927SAndroid Build Coastguard Worker              GL_SHADER_STATE_ATTRIBUTE_RECORD, attr) {
661*61046927SAndroid Build Coastguard Worker 
662*61046927SAndroid Build Coastguard Worker       /* vec_size == 0 means 4 */
663*61046927SAndroid Build Coastguard Worker       attr.vec_size = desc->nr_channels & 3;
664*61046927SAndroid Build Coastguard Worker       attr.signed_int_type = (desc->channel[0].type ==
665*61046927SAndroid Build Coastguard Worker                               UTIL_FORMAT_TYPE_SIGNED);
666*61046927SAndroid Build Coastguard Worker       attr.normalized_int_type = desc->channel[0].normalized;
667*61046927SAndroid Build Coastguard Worker       attr.read_as_int_uint = desc->channel[0].pure_integer;
668*61046927SAndroid Build Coastguard Worker 
669*61046927SAndroid Build Coastguard Worker       attr.instance_divisor = MIN2(pipeline->vb[binding].instance_divisor,
670*61046927SAndroid Build Coastguard Worker                                    V3D_MAX_VERTEX_ATTRIB_DIVISOR);
671*61046927SAndroid Build Coastguard Worker       attr.type = get_attr_type(desc);
672*61046927SAndroid Build Coastguard Worker    }
673*61046927SAndroid Build Coastguard Worker }
674*61046927SAndroid Build Coastguard Worker 
675*61046927SAndroid Build Coastguard Worker void
v3dX(pipeline_pack_compile_state)676*61046927SAndroid Build Coastguard Worker v3dX(pipeline_pack_compile_state)(struct v3dv_pipeline *pipeline,
677*61046927SAndroid Build Coastguard Worker                                   const VkPipelineVertexInputStateCreateInfo *vi_info,
678*61046927SAndroid Build Coastguard Worker                                   const VkPipelineVertexInputDivisorStateCreateInfoEXT *vd_info)
679*61046927SAndroid Build Coastguard Worker {
680*61046927SAndroid Build Coastguard Worker    pack_shader_state_record(pipeline);
681*61046927SAndroid Build Coastguard Worker    pack_vcm_cache_size(pipeline);
682*61046927SAndroid Build Coastguard Worker 
683*61046927SAndroid Build Coastguard Worker    pipeline->vb_count = vi_info->vertexBindingDescriptionCount;
684*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < vi_info->vertexBindingDescriptionCount; i++) {
685*61046927SAndroid Build Coastguard Worker       const VkVertexInputBindingDescription *desc =
686*61046927SAndroid Build Coastguard Worker          &vi_info->pVertexBindingDescriptions[i];
687*61046927SAndroid Build Coastguard Worker 
688*61046927SAndroid Build Coastguard Worker       pipeline->vb[desc->binding].instance_divisor = desc->inputRate;
689*61046927SAndroid Build Coastguard Worker    }
690*61046927SAndroid Build Coastguard Worker 
691*61046927SAndroid Build Coastguard Worker    if (vd_info) {
692*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < vd_info->vertexBindingDivisorCount; i++) {
693*61046927SAndroid Build Coastguard Worker          const VkVertexInputBindingDivisorDescriptionEXT *desc =
694*61046927SAndroid Build Coastguard Worker             &vd_info->pVertexBindingDivisors[i];
695*61046927SAndroid Build Coastguard Worker 
696*61046927SAndroid Build Coastguard Worker          pipeline->vb[desc->binding].instance_divisor = desc->divisor;
697*61046927SAndroid Build Coastguard Worker       }
698*61046927SAndroid Build Coastguard Worker    }
699*61046927SAndroid Build Coastguard Worker 
700*61046927SAndroid Build Coastguard Worker    pipeline->va_count = 0;
701*61046927SAndroid Build Coastguard Worker    struct v3d_vs_prog_data *prog_data_vs =
702*61046927SAndroid Build Coastguard Worker       pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX]->prog_data.vs;
703*61046927SAndroid Build Coastguard Worker 
704*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) {
705*61046927SAndroid Build Coastguard Worker       const VkVertexInputAttributeDescription *desc =
706*61046927SAndroid Build Coastguard Worker          &vi_info->pVertexAttributeDescriptions[i];
707*61046927SAndroid Build Coastguard Worker       uint32_t location = desc->location + VERT_ATTRIB_GENERIC0;
708*61046927SAndroid Build Coastguard Worker 
709*61046927SAndroid Build Coastguard Worker       /* We use a custom driver_location_map instead of
710*61046927SAndroid Build Coastguard Worker        * nir_find_variable_with_location because if we were able to get the
711*61046927SAndroid Build Coastguard Worker        * shader variant from the cache, we would not have the nir shader
712*61046927SAndroid Build Coastguard Worker        * available.
713*61046927SAndroid Build Coastguard Worker        */
714*61046927SAndroid Build Coastguard Worker       uint32_t driver_location =
715*61046927SAndroid Build Coastguard Worker          prog_data_vs->driver_location_map[location];
716*61046927SAndroid Build Coastguard Worker 
717*61046927SAndroid Build Coastguard Worker       if (driver_location != -1) {
718*61046927SAndroid Build Coastguard Worker          assert(driver_location < MAX_VERTEX_ATTRIBS);
719*61046927SAndroid Build Coastguard Worker          pipeline->va[driver_location].offset = desc->offset;
720*61046927SAndroid Build Coastguard Worker          pipeline->va[driver_location].binding = desc->binding;
721*61046927SAndroid Build Coastguard Worker          pipeline->va[driver_location].vk_format = desc->format;
722*61046927SAndroid Build Coastguard Worker 
723*61046927SAndroid Build Coastguard Worker          pack_shader_state_attribute_record(pipeline, driver_location, desc);
724*61046927SAndroid Build Coastguard Worker 
725*61046927SAndroid Build Coastguard Worker          pipeline->va_count++;
726*61046927SAndroid Build Coastguard Worker       }
727*61046927SAndroid Build Coastguard Worker    }
728*61046927SAndroid Build Coastguard Worker }
729*61046927SAndroid Build Coastguard Worker 
730*61046927SAndroid Build Coastguard Worker #if V3D_VERSION == 42
731*61046927SAndroid Build Coastguard Worker static bool
pipeline_has_integer_vertex_attrib(struct v3dv_pipeline * pipeline)732*61046927SAndroid Build Coastguard Worker pipeline_has_integer_vertex_attrib(struct v3dv_pipeline *pipeline)
733*61046927SAndroid Build Coastguard Worker {
734*61046927SAndroid Build Coastguard Worker    for (uint8_t i = 0; i < pipeline->va_count; i++) {
735*61046927SAndroid Build Coastguard Worker       if (vk_format_is_int(pipeline->va[i].vk_format))
736*61046927SAndroid Build Coastguard Worker          return true;
737*61046927SAndroid Build Coastguard Worker    }
738*61046927SAndroid Build Coastguard Worker    return false;
739*61046927SAndroid Build Coastguard Worker }
740*61046927SAndroid Build Coastguard Worker #endif
741*61046927SAndroid Build Coastguard Worker 
742*61046927SAndroid Build Coastguard Worker bool
v3dX(pipeline_needs_default_attribute_values)743*61046927SAndroid Build Coastguard Worker v3dX(pipeline_needs_default_attribute_values)(struct v3dv_pipeline *pipeline)
744*61046927SAndroid Build Coastguard Worker {
745*61046927SAndroid Build Coastguard Worker #if V3D_VERSION == 42
746*61046927SAndroid Build Coastguard Worker    return pipeline_has_integer_vertex_attrib(pipeline);
747*61046927SAndroid Build Coastguard Worker #endif
748*61046927SAndroid Build Coastguard Worker 
749*61046927SAndroid Build Coastguard Worker    return false;
750*61046927SAndroid Build Coastguard Worker }
751*61046927SAndroid Build Coastguard Worker 
752*61046927SAndroid Build Coastguard Worker /* @pipeline can be NULL. In that case we assume the most common case. For
753*61046927SAndroid Build Coastguard Worker  * example, for v42 we assume in that case that all the attributes have a
754*61046927SAndroid Build Coastguard Worker  * float format (we only create an all-float BO once and we reuse it with all
755*61046927SAndroid Build Coastguard Worker  * float pipelines), otherwise we look at the actual type of each attribute
756*61046927SAndroid Build Coastguard Worker  * used with the specific pipeline passed in.
757*61046927SAndroid Build Coastguard Worker  */
758*61046927SAndroid Build Coastguard Worker struct v3dv_bo *
v3dX(create_default_attribute_values)759*61046927SAndroid Build Coastguard Worker v3dX(create_default_attribute_values)(struct v3dv_device *device,
760*61046927SAndroid Build Coastguard Worker                                       struct v3dv_pipeline *pipeline)
761*61046927SAndroid Build Coastguard Worker {
762*61046927SAndroid Build Coastguard Worker #if V3D_VERSION >= 71
763*61046927SAndroid Build Coastguard Worker    return NULL;
764*61046927SAndroid Build Coastguard Worker #endif
765*61046927SAndroid Build Coastguard Worker 
766*61046927SAndroid Build Coastguard Worker    uint32_t size = MAX_VERTEX_ATTRIBS * sizeof(float) * 4;
767*61046927SAndroid Build Coastguard Worker    struct v3dv_bo *bo;
768*61046927SAndroid Build Coastguard Worker 
769*61046927SAndroid Build Coastguard Worker    bo = v3dv_bo_alloc(device, size, "default_vi_attributes", true);
770*61046927SAndroid Build Coastguard Worker 
771*61046927SAndroid Build Coastguard Worker    if (!bo) {
772*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "failed to allocate memory for the default "
773*61046927SAndroid Build Coastguard Worker               "attribute values\n");
774*61046927SAndroid Build Coastguard Worker       return NULL;
775*61046927SAndroid Build Coastguard Worker    }
776*61046927SAndroid Build Coastguard Worker 
777*61046927SAndroid Build Coastguard Worker    bool ok = v3dv_bo_map(device, bo, size);
778*61046927SAndroid Build Coastguard Worker    if (!ok) {
779*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "failed to map default attribute values buffer\n");
780*61046927SAndroid Build Coastguard Worker       return NULL;
781*61046927SAndroid Build Coastguard Worker    }
782*61046927SAndroid Build Coastguard Worker 
783*61046927SAndroid Build Coastguard Worker    uint32_t *attrs = bo->map;
784*61046927SAndroid Build Coastguard Worker    uint8_t va_count = pipeline != NULL ? pipeline->va_count : 0;
785*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) {
786*61046927SAndroid Build Coastguard Worker       attrs[i * 4 + 0] = 0;
787*61046927SAndroid Build Coastguard Worker       attrs[i * 4 + 1] = 0;
788*61046927SAndroid Build Coastguard Worker       attrs[i * 4 + 2] = 0;
789*61046927SAndroid Build Coastguard Worker       VkFormat attr_format =
790*61046927SAndroid Build Coastguard Worker          pipeline != NULL ? pipeline->va[i].vk_format : VK_FORMAT_UNDEFINED;
791*61046927SAndroid Build Coastguard Worker       if (i < va_count && vk_format_is_int(attr_format)) {
792*61046927SAndroid Build Coastguard Worker          attrs[i * 4 + 3] = 1;
793*61046927SAndroid Build Coastguard Worker       } else {
794*61046927SAndroid Build Coastguard Worker          attrs[i * 4 + 3] = fui(1.0);
795*61046927SAndroid Build Coastguard Worker       }
796*61046927SAndroid Build Coastguard Worker    }
797*61046927SAndroid Build Coastguard Worker 
798*61046927SAndroid Build Coastguard Worker    v3dv_bo_unmap(device, bo);
799*61046927SAndroid Build Coastguard Worker 
800*61046927SAndroid Build Coastguard Worker    return bo;
801*61046927SAndroid Build Coastguard Worker }
802