1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2016 Red Hat
3bf215546Sopenharmony_ci * based on intel anv code:
4bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
12bf215546Sopenharmony_ci *
13bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
14bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
15bf215546Sopenharmony_ci * Software.
16bf215546Sopenharmony_ci *
17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23bf215546Sopenharmony_ci * IN THE SOFTWARE.
24bf215546Sopenharmony_ci */
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include "radv_meta.h"
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "vk_util.h"
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include <fcntl.h>
31bf215546Sopenharmony_ci#include <limits.h>
32bf215546Sopenharmony_ci#ifndef _WIN32
33bf215546Sopenharmony_ci#include <pwd.h>
34bf215546Sopenharmony_ci#endif
35bf215546Sopenharmony_ci#include <sys/stat.h>
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_cistatic void
38bf215546Sopenharmony_ciradv_suspend_queries(struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_buffer)
39bf215546Sopenharmony_ci{
40bf215546Sopenharmony_ci   /* Pipeline statistics queries. */
41bf215546Sopenharmony_ci   if (cmd_buffer->state.active_pipeline_queries > 0) {
42bf215546Sopenharmony_ci      cmd_buffer->state.flush_bits &= ~RADV_CMD_FLAG_START_PIPELINE_STATS;
43bf215546Sopenharmony_ci      cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_STOP_PIPELINE_STATS;
44bf215546Sopenharmony_ci   }
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci   /* Occlusion queries. */
47bf215546Sopenharmony_ci   if (cmd_buffer->state.active_occlusion_queries > 0) {
48bf215546Sopenharmony_ci      radv_set_db_count_control(cmd_buffer, false);
49bf215546Sopenharmony_ci   }
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci   /* Primitives generated queries. */
52bf215546Sopenharmony_ci   if (cmd_buffer->state.prims_gen_query_enabled) {
53bf215546Sopenharmony_ci      cmd_buffer->state.suspend_streamout = true;
54bf215546Sopenharmony_ci      radv_emit_streamout_enable(cmd_buffer);
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci      /* Save the number of active GDS queries and reset it to make sure internal operations won't
57bf215546Sopenharmony_ci       * increment the counters via GDS.
58bf215546Sopenharmony_ci       */
59bf215546Sopenharmony_ci      state->active_pipeline_gds_queries = cmd_buffer->state.active_pipeline_gds_queries;
60bf215546Sopenharmony_ci      cmd_buffer->state.active_pipeline_gds_queries = 0;
61bf215546Sopenharmony_ci   }
62bf215546Sopenharmony_ci}
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_cistatic void
65bf215546Sopenharmony_ciradv_resume_queries(const struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_buffer)
66bf215546Sopenharmony_ci{
67bf215546Sopenharmony_ci   /* Pipeline statistics queries. */
68bf215546Sopenharmony_ci   if (cmd_buffer->state.active_pipeline_queries > 0) {
69bf215546Sopenharmony_ci      cmd_buffer->state.flush_bits &= ~RADV_CMD_FLAG_STOP_PIPELINE_STATS;
70bf215546Sopenharmony_ci      cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_START_PIPELINE_STATS;
71bf215546Sopenharmony_ci   }
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci   /* Occlusion queries. */
74bf215546Sopenharmony_ci   if (cmd_buffer->state.active_occlusion_queries > 0) {
75bf215546Sopenharmony_ci      radv_set_db_count_control(cmd_buffer, true);
76bf215546Sopenharmony_ci   }
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ci   /* Primitives generated queries. */
79bf215546Sopenharmony_ci   if (cmd_buffer->state.prims_gen_query_enabled) {
80bf215546Sopenharmony_ci      cmd_buffer->state.suspend_streamout = false;
81bf215546Sopenharmony_ci      radv_emit_streamout_enable(cmd_buffer);
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci      /* Restore the number of active GDS queries to resume counting. */
84bf215546Sopenharmony_ci      cmd_buffer->state.active_pipeline_gds_queries = state->active_pipeline_gds_queries;
85bf215546Sopenharmony_ci   }
86bf215546Sopenharmony_ci}
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_civoid
89bf215546Sopenharmony_ciradv_meta_save(struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_buffer,
90bf215546Sopenharmony_ci               uint32_t flags)
91bf215546Sopenharmony_ci{
92bf215546Sopenharmony_ci   VkPipelineBindPoint bind_point = flags & RADV_META_SAVE_GRAPHICS_PIPELINE
93bf215546Sopenharmony_ci                                       ? VK_PIPELINE_BIND_POINT_GRAPHICS
94bf215546Sopenharmony_ci                                       : VK_PIPELINE_BIND_POINT_COMPUTE;
95bf215546Sopenharmony_ci   struct radv_descriptor_state *descriptors_state =
96bf215546Sopenharmony_ci      radv_get_descriptors_state(cmd_buffer, bind_point);
97bf215546Sopenharmony_ci
98bf215546Sopenharmony_ci   assert(flags & (RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_COMPUTE_PIPELINE));
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_ci   state->flags = flags;
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE) {
103bf215546Sopenharmony_ci      assert(!(state->flags & RADV_META_SAVE_COMPUTE_PIPELINE));
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci      state->old_graphics_pipeline = cmd_buffer->state.graphics_pipeline;
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci      /* Save all viewports. */
108bf215546Sopenharmony_ci      state->dynamic.viewport.count = cmd_buffer->state.dynamic.viewport.count;
109bf215546Sopenharmony_ci      typed_memcpy(state->dynamic.viewport.viewports, cmd_buffer->state.dynamic.viewport.viewports,
110bf215546Sopenharmony_ci                   MAX_VIEWPORTS);
111bf215546Sopenharmony_ci      typed_memcpy(state->dynamic.viewport.xform, cmd_buffer->state.dynamic.viewport.xform,
112bf215546Sopenharmony_ci                   MAX_VIEWPORTS);
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci      /* Save all scissors. */
115bf215546Sopenharmony_ci      state->dynamic.scissor.count = cmd_buffer->state.dynamic.scissor.count;
116bf215546Sopenharmony_ci      typed_memcpy(state->dynamic.scissor.scissors, cmd_buffer->state.dynamic.scissor.scissors,
117bf215546Sopenharmony_ci                   MAX_SCISSORS);
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ci      state->dynamic.line_stipple.factor = cmd_buffer->state.dynamic.line_stipple.factor;
120bf215546Sopenharmony_ci      state->dynamic.line_stipple.pattern = cmd_buffer->state.dynamic.line_stipple.pattern;
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_ci      state->dynamic.cull_mode = cmd_buffer->state.dynamic.cull_mode;
123bf215546Sopenharmony_ci      state->dynamic.front_face = cmd_buffer->state.dynamic.front_face;
124bf215546Sopenharmony_ci
125bf215546Sopenharmony_ci      state->dynamic.primitive_topology = cmd_buffer->state.dynamic.primitive_topology;
126bf215546Sopenharmony_ci
127bf215546Sopenharmony_ci      state->dynamic.depth_test_enable = cmd_buffer->state.dynamic.depth_test_enable;
128bf215546Sopenharmony_ci      state->dynamic.depth_write_enable = cmd_buffer->state.dynamic.depth_write_enable;
129bf215546Sopenharmony_ci      state->dynamic.depth_compare_op = cmd_buffer->state.dynamic.depth_compare_op;
130bf215546Sopenharmony_ci      state->dynamic.depth_bounds_test_enable = cmd_buffer->state.dynamic.depth_bounds_test_enable;
131bf215546Sopenharmony_ci      state->dynamic.stencil_test_enable = cmd_buffer->state.dynamic.stencil_test_enable;
132bf215546Sopenharmony_ci
133bf215546Sopenharmony_ci      state->dynamic.stencil_op.front.compare_op = cmd_buffer->state.dynamic.stencil_op.front.compare_op;
134bf215546Sopenharmony_ci      state->dynamic.stencil_op.front.fail_op = cmd_buffer->state.dynamic.stencil_op.front.fail_op;
135bf215546Sopenharmony_ci      state->dynamic.stencil_op.front.pass_op = cmd_buffer->state.dynamic.stencil_op.front.pass_op;
136bf215546Sopenharmony_ci      state->dynamic.stencil_op.front.depth_fail_op =
137bf215546Sopenharmony_ci         cmd_buffer->state.dynamic.stencil_op.front.depth_fail_op;
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci      state->dynamic.stencil_op.back.compare_op = cmd_buffer->state.dynamic.stencil_op.back.compare_op;
140bf215546Sopenharmony_ci      state->dynamic.stencil_op.back.fail_op = cmd_buffer->state.dynamic.stencil_op.back.fail_op;
141bf215546Sopenharmony_ci      state->dynamic.stencil_op.back.pass_op = cmd_buffer->state.dynamic.stencil_op.back.pass_op;
142bf215546Sopenharmony_ci      state->dynamic.stencil_op.back.depth_fail_op =
143bf215546Sopenharmony_ci         cmd_buffer->state.dynamic.stencil_op.back.depth_fail_op;
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci      state->dynamic.line_width = cmd_buffer->state.dynamic.line_width;
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci      state->dynamic.depth_bias.bias = cmd_buffer->state.dynamic.depth_bias.bias;
148bf215546Sopenharmony_ci      state->dynamic.depth_bias.clamp = cmd_buffer->state.dynamic.depth_bias.clamp;
149bf215546Sopenharmony_ci      state->dynamic.depth_bias.slope = cmd_buffer->state.dynamic.depth_bias.slope;
150bf215546Sopenharmony_ci
151bf215546Sopenharmony_ci      memcpy(state->dynamic.blend_constants, cmd_buffer->state.dynamic.blend_constants,
152bf215546Sopenharmony_ci             sizeof(state->dynamic.blend_constants));
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_ci      state->dynamic.depth_bounds.min = cmd_buffer->state.dynamic.depth_bounds.min;
155bf215546Sopenharmony_ci      state->dynamic.depth_bounds.max = cmd_buffer->state.dynamic.depth_bounds.max;
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci      state->dynamic.stencil_compare_mask.front = cmd_buffer->state.dynamic.stencil_compare_mask.front;
158bf215546Sopenharmony_ci      state->dynamic.stencil_compare_mask.back = cmd_buffer->state.dynamic.stencil_compare_mask.back;
159bf215546Sopenharmony_ci
160bf215546Sopenharmony_ci      state->dynamic.stencil_write_mask.front = cmd_buffer->state.dynamic.stencil_write_mask.front;
161bf215546Sopenharmony_ci      state->dynamic.stencil_write_mask.back = cmd_buffer->state.dynamic.stencil_write_mask.back;
162bf215546Sopenharmony_ci
163bf215546Sopenharmony_ci      state->dynamic.stencil_reference.front = cmd_buffer->state.dynamic.stencil_reference.front;
164bf215546Sopenharmony_ci      state->dynamic.stencil_reference.back = cmd_buffer->state.dynamic.stencil_reference.back;
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci      state->dynamic.fragment_shading_rate.size = cmd_buffer->state.dynamic.fragment_shading_rate.size;
167bf215546Sopenharmony_ci      state->dynamic.fragment_shading_rate.combiner_ops[0] =
168bf215546Sopenharmony_ci         cmd_buffer->state.dynamic.fragment_shading_rate.combiner_ops[0];
169bf215546Sopenharmony_ci      state->dynamic.fragment_shading_rate.combiner_ops[1] =
170bf215546Sopenharmony_ci         cmd_buffer->state.dynamic.fragment_shading_rate.combiner_ops[1];
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci      state->dynamic.depth_bias_enable = cmd_buffer->state.dynamic.depth_bias_enable;
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_ci      state->dynamic.primitive_restart_enable = cmd_buffer->state.dynamic.primitive_restart_enable;
175bf215546Sopenharmony_ci
176bf215546Sopenharmony_ci      state->dynamic.rasterizer_discard_enable = cmd_buffer->state.dynamic.rasterizer_discard_enable;
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci      state->dynamic.logic_op = cmd_buffer->state.dynamic.logic_op;
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ci      state->dynamic.color_write_enable = cmd_buffer->state.dynamic.color_write_enable;
181bf215546Sopenharmony_ci
182bf215546Sopenharmony_ci      state->dynamic.discard_rectangle.count = cmd_buffer->state.dynamic.discard_rectangle.count;
183bf215546Sopenharmony_ci      typed_memcpy(state->dynamic.discard_rectangle.rectangles,
184bf215546Sopenharmony_ci                   cmd_buffer->state.dynamic.discard_rectangle.rectangles,
185bf215546Sopenharmony_ci                   MAX_DISCARD_RECTANGLES);
186bf215546Sopenharmony_ci   }
187bf215546Sopenharmony_ci
188bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
189bf215546Sopenharmony_ci      typed_memcpy(&state->dynamic.sample_location, &cmd_buffer->state.dynamic.sample_location, 1);
190bf215546Sopenharmony_ci   }
191bf215546Sopenharmony_ci
192bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_COMPUTE_PIPELINE) {
193bf215546Sopenharmony_ci      assert(!(state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE));
194bf215546Sopenharmony_ci
195bf215546Sopenharmony_ci      state->old_compute_pipeline = cmd_buffer->state.compute_pipeline;
196bf215546Sopenharmony_ci   }
197bf215546Sopenharmony_ci
198bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_DESCRIPTORS) {
199bf215546Sopenharmony_ci      state->old_descriptor_set0 = descriptors_state->sets[0];
200bf215546Sopenharmony_ci      if (!(descriptors_state->valid & 1) || !state->old_descriptor_set0)
201bf215546Sopenharmony_ci         state->flags &= ~RADV_META_SAVE_DESCRIPTORS;
202bf215546Sopenharmony_ci   }
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_CONSTANTS) {
205bf215546Sopenharmony_ci      memcpy(state->push_constants, cmd_buffer->push_constants, MAX_PUSH_CONSTANTS_SIZE);
206bf215546Sopenharmony_ci   }
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_PASS) {
209bf215546Sopenharmony_ci      state->pass = cmd_buffer->state.pass;
210bf215546Sopenharmony_ci      state->subpass = cmd_buffer->state.subpass;
211bf215546Sopenharmony_ci      state->framebuffer = cmd_buffer->state.framebuffer;
212bf215546Sopenharmony_ci      state->attachments = cmd_buffer->state.attachments;
213bf215546Sopenharmony_ci      state->render_area = cmd_buffer->state.render_area;
214bf215546Sopenharmony_ci   }
215bf215546Sopenharmony_ci
216bf215546Sopenharmony_ci   if (state->flags & RADV_META_SUSPEND_PREDICATING) {
217bf215546Sopenharmony_ci      state->predicating = cmd_buffer->state.predicating;
218bf215546Sopenharmony_ci      cmd_buffer->state.predicating = false;
219bf215546Sopenharmony_ci   }
220bf215546Sopenharmony_ci
221bf215546Sopenharmony_ci   radv_suspend_queries(state, cmd_buffer);
222bf215546Sopenharmony_ci}
223bf215546Sopenharmony_ci
224bf215546Sopenharmony_civoid
225bf215546Sopenharmony_ciradv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_buffer)
226bf215546Sopenharmony_ci{
227bf215546Sopenharmony_ci   VkPipelineBindPoint bind_point = state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE
228bf215546Sopenharmony_ci                                       ? VK_PIPELINE_BIND_POINT_GRAPHICS
229bf215546Sopenharmony_ci                                       : VK_PIPELINE_BIND_POINT_COMPUTE;
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE) {
232bf215546Sopenharmony_ci      radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
233bf215546Sopenharmony_ci                           radv_pipeline_to_handle(&state->old_graphics_pipeline->base));
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_ci      cmd_buffer->state.dirty |= RADV_CMD_DIRTY_PIPELINE;
236bf215546Sopenharmony_ci
237bf215546Sopenharmony_ci      /* Restore all viewports. */
238bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.viewport.count = state->dynamic.viewport.count;
239bf215546Sopenharmony_ci      typed_memcpy(cmd_buffer->state.dynamic.viewport.viewports, state->dynamic.viewport.viewports,
240bf215546Sopenharmony_ci                   MAX_VIEWPORTS);
241bf215546Sopenharmony_ci      typed_memcpy(cmd_buffer->state.dynamic.viewport.xform, state->dynamic.viewport.xform,
242bf215546Sopenharmony_ci                   MAX_VIEWPORTS);
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci      /* Restore all scissors. */
245bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.scissor.count = state->dynamic.scissor.count;
246bf215546Sopenharmony_ci      typed_memcpy(cmd_buffer->state.dynamic.scissor.scissors, state->dynamic.scissor.scissors,
247bf215546Sopenharmony_ci                   MAX_SCISSORS);
248bf215546Sopenharmony_ci
249bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.line_stipple.factor = state->dynamic.line_stipple.factor;
250bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.line_stipple.pattern = state->dynamic.line_stipple.pattern;
251bf215546Sopenharmony_ci
252bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.cull_mode = state->dynamic.cull_mode;
253bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.front_face = state->dynamic.front_face;
254bf215546Sopenharmony_ci
255bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.primitive_topology = state->dynamic.primitive_topology;
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.depth_test_enable = state->dynamic.depth_test_enable;
258bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.depth_write_enable = state->dynamic.depth_write_enable;
259bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.depth_compare_op = state->dynamic.depth_compare_op;
260bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.depth_bounds_test_enable = state->dynamic.depth_bounds_test_enable;
261bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_test_enable = state->dynamic.stencil_test_enable;
262bf215546Sopenharmony_ci
263bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_op.front.compare_op = state->dynamic.stencil_op.front.compare_op;
264bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_op.front.fail_op = state->dynamic.stencil_op.front.fail_op;
265bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_op.front.pass_op = state->dynamic.stencil_op.front.pass_op;
266bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_op.front.depth_fail_op =
267bf215546Sopenharmony_ci         state->dynamic.stencil_op.front.depth_fail_op;
268bf215546Sopenharmony_ci
269bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_op.back.compare_op = state->dynamic.stencil_op.back.compare_op;
270bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_op.back.fail_op = state->dynamic.stencil_op.back.fail_op;
271bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_op.back.pass_op = state->dynamic.stencil_op.back.pass_op;
272bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_op.back.depth_fail_op =
273bf215546Sopenharmony_ci         state->dynamic.stencil_op.back.depth_fail_op;
274bf215546Sopenharmony_ci
275bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.line_width = state->dynamic.line_width;
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.depth_bias.bias = state->dynamic.depth_bias.bias;
278bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.depth_bias.clamp = state->dynamic.depth_bias.clamp;
279bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.depth_bias.slope = state->dynamic.depth_bias.slope;
280bf215546Sopenharmony_ci
281bf215546Sopenharmony_ci      memcpy(cmd_buffer->state.dynamic.blend_constants, state->dynamic.blend_constants,
282bf215546Sopenharmony_ci             sizeof(state->dynamic.blend_constants));
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.depth_bounds.min = state->dynamic.depth_bounds.min;
285bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.depth_bounds.max = state->dynamic.depth_bounds.max;
286bf215546Sopenharmony_ci
287bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_compare_mask.front = state->dynamic.stencil_compare_mask.front;
288bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_compare_mask.back = state->dynamic.stencil_compare_mask.back;
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_write_mask.front = state->dynamic.stencil_write_mask.front;
291bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_write_mask.back = state->dynamic.stencil_write_mask.back;
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_reference.front = state->dynamic.stencil_reference.front;
294bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.stencil_reference.back = state->dynamic.stencil_reference.back;
295bf215546Sopenharmony_ci
296bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.fragment_shading_rate.size = state->dynamic.fragment_shading_rate.size;
297bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.fragment_shading_rate.combiner_ops[0] =
298bf215546Sopenharmony_ci         state->dynamic.fragment_shading_rate.combiner_ops[0];
299bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.fragment_shading_rate.combiner_ops[1] =
300bf215546Sopenharmony_ci         state->dynamic.fragment_shading_rate.combiner_ops[1];
301bf215546Sopenharmony_ci
302bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.depth_bias_enable = state->dynamic.depth_bias_enable;
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.primitive_restart_enable = state->dynamic.primitive_restart_enable;
305bf215546Sopenharmony_ci
306bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.rasterizer_discard_enable = state->dynamic.rasterizer_discard_enable;
307bf215546Sopenharmony_ci
308bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.logic_op = state->dynamic.logic_op;
309bf215546Sopenharmony_ci
310bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.color_write_enable = state->dynamic.color_write_enable;
311bf215546Sopenharmony_ci
312bf215546Sopenharmony_ci      cmd_buffer->state.dynamic.discard_rectangle.count = state->dynamic.discard_rectangle.count;
313bf215546Sopenharmony_ci      typed_memcpy(cmd_buffer->state.dynamic.discard_rectangle.rectangles,
314bf215546Sopenharmony_ci                   state->dynamic.discard_rectangle.rectangles,
315bf215546Sopenharmony_ci                   MAX_DISCARD_RECTANGLES);
316bf215546Sopenharmony_ci
317bf215546Sopenharmony_ci      cmd_buffer->state.dirty |=
318bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_VIEWPORT | RADV_CMD_DIRTY_DYNAMIC_SCISSOR |
319bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_CULL_MODE | RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
320bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY | RADV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE |
321bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP |
322bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE |
323bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE | RADV_CMD_DIRTY_DYNAMIC_STENCIL_OP |
324bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK | RADV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE |
325bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE |
326bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE |
327bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE | RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP |
328bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_COLOR_WRITE_ENABLE | RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE |
329bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS |
330bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS | RADV_CMD_DIRTY_DYNAMIC_LINE_WIDTH |
331bf215546Sopenharmony_ci         RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS | RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE;
332bf215546Sopenharmony_ci   }
333bf215546Sopenharmony_ci
334bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
335bf215546Sopenharmony_ci      typed_memcpy(&cmd_buffer->state.dynamic.sample_location.locations,
336bf215546Sopenharmony_ci                   &state->dynamic.sample_location.locations, 1);
337bf215546Sopenharmony_ci
338bf215546Sopenharmony_ci      cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
339bf215546Sopenharmony_ci   }
340bf215546Sopenharmony_ci
341bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_COMPUTE_PIPELINE) {
342bf215546Sopenharmony_ci      if (state->old_compute_pipeline) {
343bf215546Sopenharmony_ci         radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE,
344bf215546Sopenharmony_ci                              radv_pipeline_to_handle(&state->old_compute_pipeline->base));
345bf215546Sopenharmony_ci      }
346bf215546Sopenharmony_ci   }
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_DESCRIPTORS) {
349bf215546Sopenharmony_ci      radv_set_descriptor_set(cmd_buffer, bind_point, state->old_descriptor_set0, 0);
350bf215546Sopenharmony_ci   }
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_CONSTANTS) {
353bf215546Sopenharmony_ci      VkShaderStageFlags stages = VK_SHADER_STAGE_COMPUTE_BIT;
354bf215546Sopenharmony_ci
355bf215546Sopenharmony_ci      if (state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE)
356bf215546Sopenharmony_ci         stages |= VK_SHADER_STAGE_ALL_GRAPHICS;
357bf215546Sopenharmony_ci
358bf215546Sopenharmony_ci      radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), VK_NULL_HANDLE, stages, 0,
359bf215546Sopenharmony_ci                            MAX_PUSH_CONSTANTS_SIZE, state->push_constants);
360bf215546Sopenharmony_ci   }
361bf215546Sopenharmony_ci
362bf215546Sopenharmony_ci   if (state->flags & RADV_META_SAVE_PASS) {
363bf215546Sopenharmony_ci      cmd_buffer->state.pass = state->pass;
364bf215546Sopenharmony_ci      cmd_buffer->state.subpass = state->subpass;
365bf215546Sopenharmony_ci      cmd_buffer->state.framebuffer = state->framebuffer;
366bf215546Sopenharmony_ci      cmd_buffer->state.attachments = state->attachments;
367bf215546Sopenharmony_ci      cmd_buffer->state.render_area = state->render_area;
368bf215546Sopenharmony_ci      if (state->subpass)
369bf215546Sopenharmony_ci         cmd_buffer->state.dirty |= RADV_CMD_DIRTY_FRAMEBUFFER;
370bf215546Sopenharmony_ci   }
371bf215546Sopenharmony_ci
372bf215546Sopenharmony_ci   if (state->flags & RADV_META_SUSPEND_PREDICATING)
373bf215546Sopenharmony_ci      cmd_buffer->state.predicating = state->predicating;
374bf215546Sopenharmony_ci
375bf215546Sopenharmony_ci   radv_resume_queries(state, cmd_buffer);
376bf215546Sopenharmony_ci}
377bf215546Sopenharmony_ci
378bf215546Sopenharmony_ciVkImageViewType
379bf215546Sopenharmony_ciradv_meta_get_view_type(const struct radv_image *image)
380bf215546Sopenharmony_ci{
381bf215546Sopenharmony_ci   switch (image->vk.image_type) {
382bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_1D:
383bf215546Sopenharmony_ci      return VK_IMAGE_VIEW_TYPE_1D;
384bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_2D:
385bf215546Sopenharmony_ci      return VK_IMAGE_VIEW_TYPE_2D;
386bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_3D:
387bf215546Sopenharmony_ci      return VK_IMAGE_VIEW_TYPE_3D;
388bf215546Sopenharmony_ci   default:
389bf215546Sopenharmony_ci      unreachable("bad VkImageViewType");
390bf215546Sopenharmony_ci   }
391bf215546Sopenharmony_ci}
392bf215546Sopenharmony_ci
393bf215546Sopenharmony_ci/**
394bf215546Sopenharmony_ci * When creating a destination VkImageView, this function provides the needed
395bf215546Sopenharmony_ci * VkImageViewCreateInfo::subresourceRange::baseArrayLayer.
396bf215546Sopenharmony_ci */
397bf215546Sopenharmony_ciuint32_t
398bf215546Sopenharmony_ciradv_meta_get_iview_layer(const struct radv_image *dest_image,
399bf215546Sopenharmony_ci                          const VkImageSubresourceLayers *dest_subresource,
400bf215546Sopenharmony_ci                          const VkOffset3D *dest_offset)
401bf215546Sopenharmony_ci{
402bf215546Sopenharmony_ci   switch (dest_image->vk.image_type) {
403bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_1D:
404bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_2D:
405bf215546Sopenharmony_ci      return dest_subresource->baseArrayLayer;
406bf215546Sopenharmony_ci   case VK_IMAGE_TYPE_3D:
407bf215546Sopenharmony_ci      /* HACK: Vulkan does not allow attaching a 3D image to a framebuffer,
408bf215546Sopenharmony_ci       * but meta does it anyway. When doing so, we translate the
409bf215546Sopenharmony_ci       * destination's z offset into an array offset.
410bf215546Sopenharmony_ci       */
411bf215546Sopenharmony_ci      return dest_offset->z;
412bf215546Sopenharmony_ci   default:
413bf215546Sopenharmony_ci      assert(!"bad VkImageType");
414bf215546Sopenharmony_ci      return 0;
415bf215546Sopenharmony_ci   }
416bf215546Sopenharmony_ci}
417bf215546Sopenharmony_ci
418bf215546Sopenharmony_cistatic VKAPI_ATTR void * VKAPI_CALL
419bf215546Sopenharmony_cimeta_alloc(void *_device, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
420bf215546Sopenharmony_ci{
421bf215546Sopenharmony_ci   struct radv_device *device = _device;
422bf215546Sopenharmony_ci   return device->vk.alloc.pfnAllocation(device->vk.alloc.pUserData, size, alignment,
423bf215546Sopenharmony_ci                                         VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
424bf215546Sopenharmony_ci}
425bf215546Sopenharmony_ci
426bf215546Sopenharmony_cistatic VKAPI_ATTR void * VKAPI_CALL
427bf215546Sopenharmony_cimeta_realloc(void *_device, void *original, size_t size, size_t alignment,
428bf215546Sopenharmony_ci             VkSystemAllocationScope allocationScope)
429bf215546Sopenharmony_ci{
430bf215546Sopenharmony_ci   struct radv_device *device = _device;
431bf215546Sopenharmony_ci   return device->vk.alloc.pfnReallocation(device->vk.alloc.pUserData, original, size, alignment,
432bf215546Sopenharmony_ci                                           VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
433bf215546Sopenharmony_ci}
434bf215546Sopenharmony_ci
435bf215546Sopenharmony_cistatic VKAPI_ATTR void VKAPI_CALL
436bf215546Sopenharmony_cimeta_free(void *_device, void *data)
437bf215546Sopenharmony_ci{
438bf215546Sopenharmony_ci   struct radv_device *device = _device;
439bf215546Sopenharmony_ci   device->vk.alloc.pfnFree(device->vk.alloc.pUserData, data);
440bf215546Sopenharmony_ci}
441bf215546Sopenharmony_ci
442bf215546Sopenharmony_ci#ifndef _WIN32
443bf215546Sopenharmony_cistatic bool
444bf215546Sopenharmony_ciradv_builtin_cache_path(char *path)
445bf215546Sopenharmony_ci{
446bf215546Sopenharmony_ci   char *xdg_cache_home = getenv("XDG_CACHE_HOME");
447bf215546Sopenharmony_ci   const char *suffix = "/radv_builtin_shaders";
448bf215546Sopenharmony_ci   const char *suffix2 = "/.cache/radv_builtin_shaders";
449bf215546Sopenharmony_ci   struct passwd pwd, *result;
450bf215546Sopenharmony_ci   char path2[PATH_MAX + 1]; /* PATH_MAX is not a real max,but suffices here. */
451bf215546Sopenharmony_ci   int ret;
452bf215546Sopenharmony_ci
453bf215546Sopenharmony_ci   if (xdg_cache_home) {
454bf215546Sopenharmony_ci      ret = snprintf(path, PATH_MAX + 1, "%s%s%zd", xdg_cache_home, suffix, sizeof(void *) * 8);
455bf215546Sopenharmony_ci      return ret > 0 && ret < PATH_MAX + 1;
456bf215546Sopenharmony_ci   }
457bf215546Sopenharmony_ci
458bf215546Sopenharmony_ci   getpwuid_r(getuid(), &pwd, path2, PATH_MAX - strlen(suffix2), &result);
459bf215546Sopenharmony_ci   if (!result)
460bf215546Sopenharmony_ci      return false;
461bf215546Sopenharmony_ci
462bf215546Sopenharmony_ci   strcpy(path, pwd.pw_dir);
463bf215546Sopenharmony_ci   strcat(path, "/.cache");
464bf215546Sopenharmony_ci   if (mkdir(path, 0755) && errno != EEXIST)
465bf215546Sopenharmony_ci      return false;
466bf215546Sopenharmony_ci
467bf215546Sopenharmony_ci   ret = snprintf(path, PATH_MAX + 1, "%s%s%zd", pwd.pw_dir, suffix2, sizeof(void *) * 8);
468bf215546Sopenharmony_ci   return ret > 0 && ret < PATH_MAX + 1;
469bf215546Sopenharmony_ci}
470bf215546Sopenharmony_ci#endif
471bf215546Sopenharmony_ci
472bf215546Sopenharmony_cistatic bool
473bf215546Sopenharmony_ciradv_load_meta_pipeline(struct radv_device *device)
474bf215546Sopenharmony_ci{
475bf215546Sopenharmony_ci#ifdef _WIN32
476bf215546Sopenharmony_ci   return false;
477bf215546Sopenharmony_ci#else
478bf215546Sopenharmony_ci   char path[PATH_MAX + 1];
479bf215546Sopenharmony_ci   struct stat st;
480bf215546Sopenharmony_ci   void *data = NULL;
481bf215546Sopenharmony_ci   bool ret = false;
482bf215546Sopenharmony_ci
483bf215546Sopenharmony_ci   if (!radv_builtin_cache_path(path))
484bf215546Sopenharmony_ci      return false;
485bf215546Sopenharmony_ci
486bf215546Sopenharmony_ci   int fd = open(path, O_RDONLY);
487bf215546Sopenharmony_ci   if (fd < 0)
488bf215546Sopenharmony_ci      return false;
489bf215546Sopenharmony_ci   if (fstat(fd, &st))
490bf215546Sopenharmony_ci      goto fail;
491bf215546Sopenharmony_ci   data = malloc(st.st_size);
492bf215546Sopenharmony_ci   if (!data)
493bf215546Sopenharmony_ci      goto fail;
494bf215546Sopenharmony_ci   if (read(fd, data, st.st_size) == -1)
495bf215546Sopenharmony_ci      goto fail;
496bf215546Sopenharmony_ci
497bf215546Sopenharmony_ci   ret = radv_pipeline_cache_load(&device->meta_state.cache, data, st.st_size);
498bf215546Sopenharmony_cifail:
499bf215546Sopenharmony_ci   free(data);
500bf215546Sopenharmony_ci   close(fd);
501bf215546Sopenharmony_ci   return ret;
502bf215546Sopenharmony_ci#endif
503bf215546Sopenharmony_ci}
504bf215546Sopenharmony_ci
505bf215546Sopenharmony_cistatic void
506bf215546Sopenharmony_ciradv_store_meta_pipeline(struct radv_device *device)
507bf215546Sopenharmony_ci{
508bf215546Sopenharmony_ci#ifndef _WIN32
509bf215546Sopenharmony_ci   char path[PATH_MAX + 1], path2[PATH_MAX + 7];
510bf215546Sopenharmony_ci   size_t size;
511bf215546Sopenharmony_ci   void *data = NULL;
512bf215546Sopenharmony_ci
513bf215546Sopenharmony_ci   if (!device->meta_state.cache.modified)
514bf215546Sopenharmony_ci      return;
515bf215546Sopenharmony_ci
516bf215546Sopenharmony_ci   if (radv_GetPipelineCacheData(radv_device_to_handle(device),
517bf215546Sopenharmony_ci                                 radv_pipeline_cache_to_handle(&device->meta_state.cache), &size,
518bf215546Sopenharmony_ci                                 NULL))
519bf215546Sopenharmony_ci      return;
520bf215546Sopenharmony_ci
521bf215546Sopenharmony_ci   if (!radv_builtin_cache_path(path))
522bf215546Sopenharmony_ci      return;
523bf215546Sopenharmony_ci
524bf215546Sopenharmony_ci   strcpy(path2, path);
525bf215546Sopenharmony_ci   strcat(path2, "XXXXXX");
526bf215546Sopenharmony_ci   int fd = mkstemp(path2); // open(path, O_WRONLY | O_CREAT, 0600);
527bf215546Sopenharmony_ci   if (fd < 0)
528bf215546Sopenharmony_ci      return;
529bf215546Sopenharmony_ci   data = malloc(size);
530bf215546Sopenharmony_ci   if (!data)
531bf215546Sopenharmony_ci      goto fail;
532bf215546Sopenharmony_ci
533bf215546Sopenharmony_ci   if (radv_GetPipelineCacheData(radv_device_to_handle(device),
534bf215546Sopenharmony_ci                                 radv_pipeline_cache_to_handle(&device->meta_state.cache), &size,
535bf215546Sopenharmony_ci                                 data))
536bf215546Sopenharmony_ci      goto fail;
537bf215546Sopenharmony_ci   if (write(fd, data, size) == -1)
538bf215546Sopenharmony_ci      goto fail;
539bf215546Sopenharmony_ci
540bf215546Sopenharmony_ci   rename(path2, path);
541bf215546Sopenharmony_cifail:
542bf215546Sopenharmony_ci   free(data);
543bf215546Sopenharmony_ci   close(fd);
544bf215546Sopenharmony_ci   unlink(path2);
545bf215546Sopenharmony_ci#endif
546bf215546Sopenharmony_ci}
547bf215546Sopenharmony_ci
548bf215546Sopenharmony_ciVkResult
549bf215546Sopenharmony_ciradv_device_init_meta(struct radv_device *device)
550bf215546Sopenharmony_ci{
551bf215546Sopenharmony_ci   VkResult result;
552bf215546Sopenharmony_ci
553bf215546Sopenharmony_ci   memset(&device->meta_state, 0, sizeof(device->meta_state));
554bf215546Sopenharmony_ci
555bf215546Sopenharmony_ci   device->meta_state.alloc = (VkAllocationCallbacks){
556bf215546Sopenharmony_ci      .pUserData = device,
557bf215546Sopenharmony_ci      .pfnAllocation = meta_alloc,
558bf215546Sopenharmony_ci      .pfnReallocation = meta_realloc,
559bf215546Sopenharmony_ci      .pfnFree = meta_free,
560bf215546Sopenharmony_ci   };
561bf215546Sopenharmony_ci
562bf215546Sopenharmony_ci   device->meta_state.cache.alloc = device->meta_state.alloc;
563bf215546Sopenharmony_ci   radv_pipeline_cache_init(&device->meta_state.cache, device);
564bf215546Sopenharmony_ci   bool loaded_cache = radv_load_meta_pipeline(device);
565bf215546Sopenharmony_ci   bool on_demand = !loaded_cache;
566bf215546Sopenharmony_ci
567bf215546Sopenharmony_ci   mtx_init(&device->meta_state.mtx, mtx_plain);
568bf215546Sopenharmony_ci
569bf215546Sopenharmony_ci   device->app_shaders_internal = true;
570bf215546Sopenharmony_ci
571bf215546Sopenharmony_ci   result = radv_device_init_meta_clear_state(device, on_demand);
572bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
573bf215546Sopenharmony_ci      goto fail_clear;
574bf215546Sopenharmony_ci
575bf215546Sopenharmony_ci   result = radv_device_init_meta_resolve_state(device, on_demand);
576bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
577bf215546Sopenharmony_ci      goto fail_resolve;
578bf215546Sopenharmony_ci
579bf215546Sopenharmony_ci   result = radv_device_init_meta_blit_state(device, on_demand);
580bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
581bf215546Sopenharmony_ci      goto fail_blit;
582bf215546Sopenharmony_ci
583bf215546Sopenharmony_ci   result = radv_device_init_meta_blit2d_state(device, on_demand);
584bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
585bf215546Sopenharmony_ci      goto fail_blit2d;
586bf215546Sopenharmony_ci
587bf215546Sopenharmony_ci   result = radv_device_init_meta_bufimage_state(device);
588bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
589bf215546Sopenharmony_ci      goto fail_bufimage;
590bf215546Sopenharmony_ci
591bf215546Sopenharmony_ci   result = radv_device_init_meta_depth_decomp_state(device, on_demand);
592bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
593bf215546Sopenharmony_ci      goto fail_depth_decomp;
594bf215546Sopenharmony_ci
595bf215546Sopenharmony_ci   result = radv_device_init_meta_buffer_state(device);
596bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
597bf215546Sopenharmony_ci      goto fail_buffer;
598bf215546Sopenharmony_ci
599bf215546Sopenharmony_ci   result = radv_device_init_meta_query_state(device, on_demand);
600bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
601bf215546Sopenharmony_ci      goto fail_query;
602bf215546Sopenharmony_ci
603bf215546Sopenharmony_ci   result = radv_device_init_meta_fast_clear_flush_state(device, on_demand);
604bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
605bf215546Sopenharmony_ci      goto fail_fast_clear;
606bf215546Sopenharmony_ci
607bf215546Sopenharmony_ci   result = radv_device_init_meta_resolve_compute_state(device, on_demand);
608bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
609bf215546Sopenharmony_ci      goto fail_resolve_compute;
610bf215546Sopenharmony_ci
611bf215546Sopenharmony_ci   result = radv_device_init_meta_resolve_fragment_state(device, on_demand);
612bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
613bf215546Sopenharmony_ci      goto fail_resolve_fragment;
614bf215546Sopenharmony_ci
615bf215546Sopenharmony_ci   result = radv_device_init_meta_fmask_expand_state(device);
616bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
617bf215546Sopenharmony_ci      goto fail_fmask_expand;
618bf215546Sopenharmony_ci
619bf215546Sopenharmony_ci   if (radv_enable_rt(device->physical_device, false)) {
620bf215546Sopenharmony_ci      result = radv_device_init_accel_struct_build_state(device);
621bf215546Sopenharmony_ci      if (result != VK_SUCCESS)
622bf215546Sopenharmony_ci         goto fail_accel_struct_build;
623bf215546Sopenharmony_ci   }
624bf215546Sopenharmony_ci
625bf215546Sopenharmony_ci   result = radv_device_init_meta_fmask_copy_state(device);
626bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
627bf215546Sopenharmony_ci      goto fail_fmask_copy;
628bf215546Sopenharmony_ci
629bf215546Sopenharmony_ci   result = radv_device_init_meta_etc_decode_state(device, on_demand);
630bf215546Sopenharmony_ci   if (result != VK_SUCCESS)
631bf215546Sopenharmony_ci      goto fail_etc_decode;
632bf215546Sopenharmony_ci
633bf215546Sopenharmony_ci   if (device->uses_device_generated_commands) {
634bf215546Sopenharmony_ci      result = radv_device_init_dgc_prepare_state(device);
635bf215546Sopenharmony_ci      if (result != VK_SUCCESS)
636bf215546Sopenharmony_ci         goto fail_dgc;
637bf215546Sopenharmony_ci   }
638bf215546Sopenharmony_ci
639bf215546Sopenharmony_ci   device->app_shaders_internal = false;
640bf215546Sopenharmony_ci
641bf215546Sopenharmony_ci   return VK_SUCCESS;
642bf215546Sopenharmony_ci
643bf215546Sopenharmony_cifail_dgc:
644bf215546Sopenharmony_ci   radv_device_finish_dgc_prepare_state(device);
645bf215546Sopenharmony_cifail_etc_decode:
646bf215546Sopenharmony_ci   radv_device_finish_meta_etc_decode_state(device);
647bf215546Sopenharmony_cifail_fmask_copy:
648bf215546Sopenharmony_ci   radv_device_finish_meta_fmask_copy_state(device);
649bf215546Sopenharmony_cifail_accel_struct_build:
650bf215546Sopenharmony_ci   radv_device_finish_accel_struct_build_state(device);
651bf215546Sopenharmony_cifail_fmask_expand:
652bf215546Sopenharmony_ci   radv_device_finish_meta_fmask_expand_state(device);
653bf215546Sopenharmony_cifail_resolve_fragment:
654bf215546Sopenharmony_ci   radv_device_finish_meta_resolve_fragment_state(device);
655bf215546Sopenharmony_cifail_resolve_compute:
656bf215546Sopenharmony_ci   radv_device_finish_meta_resolve_compute_state(device);
657bf215546Sopenharmony_cifail_fast_clear:
658bf215546Sopenharmony_ci   radv_device_finish_meta_fast_clear_flush_state(device);
659bf215546Sopenharmony_cifail_query:
660bf215546Sopenharmony_ci   radv_device_finish_meta_query_state(device);
661bf215546Sopenharmony_cifail_buffer:
662bf215546Sopenharmony_ci   radv_device_finish_meta_buffer_state(device);
663bf215546Sopenharmony_cifail_depth_decomp:
664bf215546Sopenharmony_ci   radv_device_finish_meta_depth_decomp_state(device);
665bf215546Sopenharmony_cifail_bufimage:
666bf215546Sopenharmony_ci   radv_device_finish_meta_bufimage_state(device);
667bf215546Sopenharmony_cifail_blit2d:
668bf215546Sopenharmony_ci   radv_device_finish_meta_blit2d_state(device);
669bf215546Sopenharmony_cifail_blit:
670bf215546Sopenharmony_ci   radv_device_finish_meta_blit_state(device);
671bf215546Sopenharmony_cifail_resolve:
672bf215546Sopenharmony_ci   radv_device_finish_meta_resolve_state(device);
673bf215546Sopenharmony_cifail_clear:
674bf215546Sopenharmony_ci   radv_device_finish_meta_clear_state(device);
675bf215546Sopenharmony_ci
676bf215546Sopenharmony_ci   mtx_destroy(&device->meta_state.mtx);
677bf215546Sopenharmony_ci   radv_pipeline_cache_finish(&device->meta_state.cache);
678bf215546Sopenharmony_ci   return result;
679bf215546Sopenharmony_ci}
680bf215546Sopenharmony_ci
681bf215546Sopenharmony_civoid
682bf215546Sopenharmony_ciradv_device_finish_meta(struct radv_device *device)
683bf215546Sopenharmony_ci{
684bf215546Sopenharmony_ci   radv_device_finish_dgc_prepare_state(device);
685bf215546Sopenharmony_ci   radv_device_finish_meta_etc_decode_state(device);
686bf215546Sopenharmony_ci   radv_device_finish_accel_struct_build_state(device);
687bf215546Sopenharmony_ci   radv_device_finish_meta_clear_state(device);
688bf215546Sopenharmony_ci   radv_device_finish_meta_resolve_state(device);
689bf215546Sopenharmony_ci   radv_device_finish_meta_blit_state(device);
690bf215546Sopenharmony_ci   radv_device_finish_meta_blit2d_state(device);
691bf215546Sopenharmony_ci   radv_device_finish_meta_bufimage_state(device);
692bf215546Sopenharmony_ci   radv_device_finish_meta_depth_decomp_state(device);
693bf215546Sopenharmony_ci   radv_device_finish_meta_query_state(device);
694bf215546Sopenharmony_ci   radv_device_finish_meta_buffer_state(device);
695bf215546Sopenharmony_ci   radv_device_finish_meta_fast_clear_flush_state(device);
696bf215546Sopenharmony_ci   radv_device_finish_meta_resolve_compute_state(device);
697bf215546Sopenharmony_ci   radv_device_finish_meta_resolve_fragment_state(device);
698bf215546Sopenharmony_ci   radv_device_finish_meta_fmask_expand_state(device);
699bf215546Sopenharmony_ci   radv_device_finish_meta_dcc_retile_state(device);
700bf215546Sopenharmony_ci   radv_device_finish_meta_copy_vrs_htile_state(device);
701bf215546Sopenharmony_ci   radv_device_finish_meta_fmask_copy_state(device);
702bf215546Sopenharmony_ci
703bf215546Sopenharmony_ci   radv_store_meta_pipeline(device);
704bf215546Sopenharmony_ci   radv_pipeline_cache_finish(&device->meta_state.cache);
705bf215546Sopenharmony_ci   mtx_destroy(&device->meta_state.mtx);
706bf215546Sopenharmony_ci}
707bf215546Sopenharmony_ci
708bf215546Sopenharmony_cinir_builder PRINTFLIKE(3, 4)
709bf215546Sopenharmony_ci   radv_meta_init_shader(struct radv_device *dev, gl_shader_stage stage, const char *name, ...)
710bf215546Sopenharmony_ci{
711bf215546Sopenharmony_ci   nir_builder b = nir_builder_init_simple_shader(stage, NULL, NULL);
712bf215546Sopenharmony_ci   if (name) {
713bf215546Sopenharmony_ci      va_list args;
714bf215546Sopenharmony_ci      va_start(args, name);
715bf215546Sopenharmony_ci      b.shader->info.name = ralloc_vasprintf(b.shader, name, args);
716bf215546Sopenharmony_ci      va_end(args);
717bf215546Sopenharmony_ci   }
718bf215546Sopenharmony_ci
719bf215546Sopenharmony_ci   b.shader->options = &dev->physical_device->nir_options[stage];
720bf215546Sopenharmony_ci   b.shader->info.workgroup_size[0] = 1;
721bf215546Sopenharmony_ci   b.shader->info.workgroup_size[1] = 1;
722bf215546Sopenharmony_ci   b.shader->info.workgroup_size[2] = 1;
723bf215546Sopenharmony_ci
724bf215546Sopenharmony_ci   return b;
725bf215546Sopenharmony_ci}
726bf215546Sopenharmony_ci
727bf215546Sopenharmony_ci/* vertex shader that generates vertices */
728bf215546Sopenharmony_cinir_shader *
729bf215546Sopenharmony_ciradv_meta_build_nir_vs_generate_vertices(struct radv_device *dev)
730bf215546Sopenharmony_ci{
731bf215546Sopenharmony_ci   const struct glsl_type *vec4 = glsl_vec4_type();
732bf215546Sopenharmony_ci
733bf215546Sopenharmony_ci   nir_variable *v_position;
734bf215546Sopenharmony_ci
735bf215546Sopenharmony_ci   nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_VERTEX, "meta_vs_gen_verts");
736bf215546Sopenharmony_ci
737bf215546Sopenharmony_ci   nir_ssa_def *outvec = nir_gen_rect_vertices(&b, NULL, NULL);
738bf215546Sopenharmony_ci
739bf215546Sopenharmony_ci   v_position = nir_variable_create(b.shader, nir_var_shader_out, vec4, "gl_Position");
740bf215546Sopenharmony_ci   v_position->data.location = VARYING_SLOT_POS;
741bf215546Sopenharmony_ci
742bf215546Sopenharmony_ci   nir_store_var(&b, v_position, outvec, 0xf);
743bf215546Sopenharmony_ci
744bf215546Sopenharmony_ci   return b.shader;
745bf215546Sopenharmony_ci}
746bf215546Sopenharmony_ci
747bf215546Sopenharmony_cinir_shader *
748bf215546Sopenharmony_ciradv_meta_build_nir_fs_noop(struct radv_device *dev)
749bf215546Sopenharmony_ci{
750bf215546Sopenharmony_ci   return radv_meta_init_shader(dev, MESA_SHADER_FRAGMENT, "meta_noop_fs").shader;
751bf215546Sopenharmony_ci}
752bf215546Sopenharmony_ci
753bf215546Sopenharmony_civoid
754bf215546Sopenharmony_ciradv_meta_build_resolve_shader_core(nir_builder *b, bool is_integer, int samples,
755bf215546Sopenharmony_ci                                    nir_variable *input_img, nir_variable *color,
756bf215546Sopenharmony_ci                                    nir_ssa_def *img_coord)
757bf215546Sopenharmony_ci{
758bf215546Sopenharmony_ci   /* do a txf_ms on each sample */
759bf215546Sopenharmony_ci   nir_ssa_def *tmp;
760bf215546Sopenharmony_ci   bool inserted_if = false;
761bf215546Sopenharmony_ci
762bf215546Sopenharmony_ci   nir_ssa_def *input_img_deref = &nir_build_deref_var(b, input_img)->dest.ssa;
763bf215546Sopenharmony_ci
764bf215546Sopenharmony_ci   nir_tex_instr *tex = nir_tex_instr_create(b->shader, 3);
765bf215546Sopenharmony_ci   tex->sampler_dim = GLSL_SAMPLER_DIM_MS;
766bf215546Sopenharmony_ci   tex->op = nir_texop_txf_ms;
767bf215546Sopenharmony_ci   tex->src[0].src_type = nir_tex_src_coord;
768bf215546Sopenharmony_ci   tex->src[0].src = nir_src_for_ssa(img_coord);
769bf215546Sopenharmony_ci   tex->src[1].src_type = nir_tex_src_ms_index;
770bf215546Sopenharmony_ci   tex->src[1].src = nir_src_for_ssa(nir_imm_int(b, 0));
771bf215546Sopenharmony_ci   tex->src[2].src_type = nir_tex_src_texture_deref;
772bf215546Sopenharmony_ci   tex->src[2].src = nir_src_for_ssa(input_img_deref);
773bf215546Sopenharmony_ci   tex->dest_type = nir_get_nir_type_for_glsl_base_type(glsl_get_sampler_result_type(input_img->type));
774bf215546Sopenharmony_ci   tex->is_array = false;
775bf215546Sopenharmony_ci   tex->coord_components = 2;
776bf215546Sopenharmony_ci
777bf215546Sopenharmony_ci   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
778bf215546Sopenharmony_ci   nir_builder_instr_insert(b, &tex->instr);
779bf215546Sopenharmony_ci
780bf215546Sopenharmony_ci   tmp = &tex->dest.ssa;
781bf215546Sopenharmony_ci
782bf215546Sopenharmony_ci   if (!is_integer && samples > 1) {
783bf215546Sopenharmony_ci      nir_tex_instr *tex_all_same = nir_tex_instr_create(b->shader, 2);
784bf215546Sopenharmony_ci      tex_all_same->sampler_dim = GLSL_SAMPLER_DIM_MS;
785bf215546Sopenharmony_ci      tex_all_same->op = nir_texop_samples_identical;
786bf215546Sopenharmony_ci      tex_all_same->src[0].src_type = nir_tex_src_coord;
787bf215546Sopenharmony_ci      tex_all_same->src[0].src = nir_src_for_ssa(img_coord);
788bf215546Sopenharmony_ci      tex_all_same->src[1].src_type = nir_tex_src_texture_deref;
789bf215546Sopenharmony_ci      tex_all_same->src[1].src = nir_src_for_ssa(input_img_deref);
790bf215546Sopenharmony_ci      tex_all_same->dest_type = nir_type_bool1;
791bf215546Sopenharmony_ci      tex_all_same->is_array = false;
792bf215546Sopenharmony_ci      tex_all_same->coord_components = 2;
793bf215546Sopenharmony_ci
794bf215546Sopenharmony_ci      nir_ssa_dest_init(&tex_all_same->instr, &tex_all_same->dest, 1, 1, "tex");
795bf215546Sopenharmony_ci      nir_builder_instr_insert(b, &tex_all_same->instr);
796bf215546Sopenharmony_ci
797bf215546Sopenharmony_ci      nir_ssa_def *not_all_same = nir_inot(b, &tex_all_same->dest.ssa);
798bf215546Sopenharmony_ci      nir_push_if(b, not_all_same);
799bf215546Sopenharmony_ci      for (int i = 1; i < samples; i++) {
800bf215546Sopenharmony_ci         nir_tex_instr *tex_add = nir_tex_instr_create(b->shader, 3);
801bf215546Sopenharmony_ci         tex_add->sampler_dim = GLSL_SAMPLER_DIM_MS;
802bf215546Sopenharmony_ci         tex_add->op = nir_texop_txf_ms;
803bf215546Sopenharmony_ci         tex_add->src[0].src_type = nir_tex_src_coord;
804bf215546Sopenharmony_ci         tex_add->src[0].src = nir_src_for_ssa(img_coord);
805bf215546Sopenharmony_ci         tex_add->src[1].src_type = nir_tex_src_ms_index;
806bf215546Sopenharmony_ci         tex_add->src[1].src = nir_src_for_ssa(nir_imm_int(b, i));
807bf215546Sopenharmony_ci         tex_add->src[2].src_type = nir_tex_src_texture_deref;
808bf215546Sopenharmony_ci         tex_add->src[2].src = nir_src_for_ssa(input_img_deref);
809bf215546Sopenharmony_ci         tex_add->dest_type = nir_type_float32;
810bf215546Sopenharmony_ci         tex_add->is_array = false;
811bf215546Sopenharmony_ci         tex_add->coord_components = 2;
812bf215546Sopenharmony_ci
813bf215546Sopenharmony_ci         nir_ssa_dest_init(&tex_add->instr, &tex_add->dest, 4, 32, "tex");
814bf215546Sopenharmony_ci         nir_builder_instr_insert(b, &tex_add->instr);
815bf215546Sopenharmony_ci
816bf215546Sopenharmony_ci         tmp = nir_fadd(b, tmp, &tex_add->dest.ssa);
817bf215546Sopenharmony_ci      }
818bf215546Sopenharmony_ci
819bf215546Sopenharmony_ci      tmp = nir_fdiv(b, tmp, nir_imm_float(b, samples));
820bf215546Sopenharmony_ci      nir_store_var(b, color, tmp, 0xf);
821bf215546Sopenharmony_ci      nir_push_else(b, NULL);
822bf215546Sopenharmony_ci      inserted_if = true;
823bf215546Sopenharmony_ci   }
824bf215546Sopenharmony_ci   nir_store_var(b, color, &tex->dest.ssa, 0xf);
825bf215546Sopenharmony_ci
826bf215546Sopenharmony_ci   if (inserted_if)
827bf215546Sopenharmony_ci      nir_pop_if(b, NULL);
828bf215546Sopenharmony_ci}
829bf215546Sopenharmony_ci
830bf215546Sopenharmony_cinir_ssa_def *
831bf215546Sopenharmony_ciradv_meta_load_descriptor(nir_builder *b, unsigned desc_set, unsigned binding)
832bf215546Sopenharmony_ci{
833bf215546Sopenharmony_ci   nir_ssa_def *rsrc = nir_vulkan_resource_index(b, 3, 32, nir_imm_int(b, 0), .desc_set = desc_set,
834bf215546Sopenharmony_ci                                                 .binding = binding);
835bf215546Sopenharmony_ci   return nir_channels(b, rsrc, 0x3);
836bf215546Sopenharmony_ci}
837bf215546Sopenharmony_ci
838bf215546Sopenharmony_cinir_ssa_def *
839bf215546Sopenharmony_ciget_global_ids(nir_builder *b, unsigned num_components)
840bf215546Sopenharmony_ci{
841bf215546Sopenharmony_ci   unsigned mask = BITFIELD_MASK(num_components);
842bf215546Sopenharmony_ci
843bf215546Sopenharmony_ci   nir_ssa_def *local_ids = nir_channels(b, nir_load_local_invocation_id(b), mask);
844bf215546Sopenharmony_ci   nir_ssa_def *block_ids = nir_channels(b, nir_load_workgroup_id(b, 32), mask);
845bf215546Sopenharmony_ci   nir_ssa_def *block_size = nir_channels(
846bf215546Sopenharmony_ci      b,
847bf215546Sopenharmony_ci      nir_imm_ivec4(b, b->shader->info.workgroup_size[0], b->shader->info.workgroup_size[1],
848bf215546Sopenharmony_ci                    b->shader->info.workgroup_size[2], 0),
849bf215546Sopenharmony_ci      mask);
850bf215546Sopenharmony_ci
851bf215546Sopenharmony_ci   return nir_iadd(b, nir_imul(b, block_ids, block_size), local_ids);
852bf215546Sopenharmony_ci}
853bf215546Sopenharmony_ci
854bf215546Sopenharmony_civoid
855bf215546Sopenharmony_ciradv_break_on_count(nir_builder *b, nir_variable *var, nir_ssa_def *count)
856bf215546Sopenharmony_ci{
857bf215546Sopenharmony_ci   nir_ssa_def *counter = nir_load_var(b, var);
858bf215546Sopenharmony_ci
859bf215546Sopenharmony_ci   nir_push_if(b, nir_uge(b, counter, count));
860bf215546Sopenharmony_ci   nir_jump(b, nir_jump_break);
861bf215546Sopenharmony_ci   nir_pop_if(b, NULL);
862bf215546Sopenharmony_ci
863bf215546Sopenharmony_ci   counter = nir_iadd_imm(b, counter, 1);
864bf215546Sopenharmony_ci   nir_store_var(b, var, counter, 0x1);
865bf215546Sopenharmony_ci}
866