Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/intel/vulkan/genX_blorp_exec.c
4547 views
1
/*
2
* Copyright © 2016 Intel Corporation
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include <assert.h>
25
26
#include "anv_private.h"
27
#include "anv_measure.h"
28
29
/* These are defined in anv_private.h and blorp_genX_exec.h */
30
#undef __gen_address_type
31
#undef __gen_user_data
32
#undef __gen_combine_address
33
34
#include "common/intel_l3_config.h"
35
#include "blorp/blorp_genX_exec.h"
36
37
static void blorp_measure_start(struct blorp_batch *_batch,
38
const struct blorp_params *params)
39
{
40
struct anv_cmd_buffer *cmd_buffer = _batch->driver_batch;
41
anv_measure_snapshot(cmd_buffer,
42
params->snapshot_type,
43
NULL, 0);
44
}
45
46
static void *
47
blorp_emit_dwords(struct blorp_batch *batch, unsigned n)
48
{
49
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
50
return anv_batch_emit_dwords(&cmd_buffer->batch, n);
51
}
52
53
static uint64_t
54
blorp_emit_reloc(struct blorp_batch *batch,
55
void *location, struct blorp_address address, uint32_t delta)
56
{
57
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
58
assert(cmd_buffer->batch.start <= location &&
59
location < cmd_buffer->batch.end);
60
return anv_batch_emit_reloc(&cmd_buffer->batch, location,
61
address.buffer, address.offset + delta);
62
}
63
64
static void
65
blorp_surface_reloc(struct blorp_batch *batch, uint32_t ss_offset,
66
struct blorp_address address, uint32_t delta)
67
{
68
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
69
VkResult result;
70
71
if (ANV_ALWAYS_SOFTPIN) {
72
result = anv_reloc_list_add_bo(&cmd_buffer->surface_relocs,
73
&cmd_buffer->pool->alloc,
74
address.buffer);
75
if (unlikely(result != VK_SUCCESS))
76
anv_batch_set_error(&cmd_buffer->batch, result);
77
return;
78
}
79
80
uint64_t address_u64 = 0;
81
result = anv_reloc_list_add(&cmd_buffer->surface_relocs,
82
&cmd_buffer->pool->alloc,
83
ss_offset, address.buffer,
84
address.offset + delta,
85
&address_u64);
86
if (result != VK_SUCCESS)
87
anv_batch_set_error(&cmd_buffer->batch, result);
88
89
void *dest = anv_block_pool_map(
90
&cmd_buffer->device->surface_state_pool.block_pool, ss_offset, 8);
91
write_reloc(cmd_buffer->device, dest, address_u64, false);
92
}
93
94
static uint64_t
95
blorp_get_surface_address(struct blorp_batch *blorp_batch,
96
struct blorp_address address)
97
{
98
if (ANV_ALWAYS_SOFTPIN) {
99
struct anv_address anv_addr = {
100
.bo = address.buffer,
101
.offset = address.offset,
102
};
103
return anv_address_physical(anv_addr);
104
} else {
105
/* We'll let blorp_surface_reloc write the address. */
106
return 0;
107
}
108
}
109
110
#if GFX_VER >= 7 && GFX_VER < 10
111
static struct blorp_address
112
blorp_get_surface_base_address(struct blorp_batch *batch)
113
{
114
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
115
return (struct blorp_address) {
116
.buffer = cmd_buffer->device->surface_state_pool.block_pool.bo,
117
.offset = 0,
118
};
119
}
120
#endif
121
122
static void *
123
blorp_alloc_dynamic_state(struct blorp_batch *batch,
124
uint32_t size,
125
uint32_t alignment,
126
uint32_t *offset)
127
{
128
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
129
130
struct anv_state state =
131
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);
132
133
*offset = state.offset;
134
return state.map;
135
}
136
137
static void
138
blorp_alloc_binding_table(struct blorp_batch *batch, unsigned num_entries,
139
unsigned state_size, unsigned state_alignment,
140
uint32_t *bt_offset,
141
uint32_t *surface_offsets, void **surface_maps)
142
{
143
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
144
145
uint32_t state_offset;
146
struct anv_state bt_state;
147
148
VkResult result =
149
anv_cmd_buffer_alloc_blorp_binding_table(cmd_buffer, num_entries,
150
&state_offset, &bt_state);
151
if (result != VK_SUCCESS)
152
return;
153
154
uint32_t *bt_map = bt_state.map;
155
*bt_offset = bt_state.offset;
156
157
for (unsigned i = 0; i < num_entries; i++) {
158
struct anv_state surface_state =
159
anv_cmd_buffer_alloc_surface_state(cmd_buffer);
160
bt_map[i] = surface_state.offset + state_offset;
161
surface_offsets[i] = surface_state.offset;
162
surface_maps[i] = surface_state.map;
163
}
164
}
165
166
static void *
167
blorp_alloc_vertex_buffer(struct blorp_batch *batch, uint32_t size,
168
struct blorp_address *addr)
169
{
170
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
171
struct anv_state vb_state =
172
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, 64);
173
174
*addr = (struct blorp_address) {
175
.buffer = cmd_buffer->device->dynamic_state_pool.block_pool.bo,
176
.offset = vb_state.offset,
177
.mocs = isl_mocs(&cmd_buffer->device->isl_dev,
178
ISL_SURF_USAGE_VERTEX_BUFFER_BIT, false),
179
};
180
181
return vb_state.map;
182
}
183
184
static void
185
blorp_vf_invalidate_for_vb_48b_transitions(struct blorp_batch *batch,
186
const struct blorp_address *addrs,
187
uint32_t *sizes,
188
unsigned num_vbs)
189
{
190
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
191
192
for (unsigned i = 0; i < num_vbs; i++) {
193
struct anv_address anv_addr = {
194
.bo = addrs[i].buffer,
195
.offset = addrs[i].offset,
196
};
197
genX(cmd_buffer_set_binding_for_gfx8_vb_flush)(cmd_buffer,
198
i, anv_addr, sizes[i]);
199
}
200
201
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
202
203
/* Technically, we should call this *after* 3DPRIMITIVE but it doesn't
204
* really matter for blorp because we never call apply_pipe_flushes after
205
* this point.
206
*/
207
genX(cmd_buffer_update_dirty_vbs_for_gfx8_vb_flush)(cmd_buffer, SEQUENTIAL,
208
(1 << num_vbs) - 1);
209
}
210
211
UNUSED static struct blorp_address
212
blorp_get_workaround_address(struct blorp_batch *batch)
213
{
214
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
215
216
return (struct blorp_address) {
217
.buffer = cmd_buffer->device->workaround_address.bo,
218
.offset = cmd_buffer->device->workaround_address.offset,
219
};
220
}
221
222
static void
223
blorp_flush_range(struct blorp_batch *batch, void *start, size_t size)
224
{
225
/* We don't need to flush states anymore, since everything will be snooped.
226
*/
227
}
228
229
static const struct intel_l3_config *
230
blorp_get_l3_config(struct blorp_batch *batch)
231
{
232
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
233
return cmd_buffer->state.current_l3_config;
234
}
235
236
void
237
genX(blorp_exec)(struct blorp_batch *batch,
238
const struct blorp_params *params)
239
{
240
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
241
242
if (!cmd_buffer->state.current_l3_config) {
243
const struct intel_l3_config *cfg =
244
intel_get_default_l3_config(&cmd_buffer->device->info);
245
genX(cmd_buffer_config_l3)(cmd_buffer, cfg);
246
}
247
248
const unsigned scale = params->fast_clear_op ? UINT_MAX : 1;
249
genX(cmd_buffer_emit_hashing_mode)(cmd_buffer, params->x1 - params->x0,
250
params->y1 - params->y0, scale);
251
252
#if GFX_VER >= 11
253
/* The PIPE_CONTROL command description says:
254
*
255
* "Whenever a Binding Table Index (BTI) used by a Render Taget Message
256
* points to a different RENDER_SURFACE_STATE, SW must issue a Render
257
* Target Cache Flush by enabling this bit. When render target flush
258
* is set due to new association of BTI, PS Scoreboard Stall bit must
259
* be set in this packet."
260
*/
261
anv_add_pending_pipe_bits(cmd_buffer,
262
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |
263
ANV_PIPE_STALL_AT_SCOREBOARD_BIT,
264
"before blorp BTI change");
265
#endif
266
267
#if GFX_VERx10 == 120
268
if (!(batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL)) {
269
/* Wa_14010455700
270
*
271
* ISL will change some CHICKEN registers depending on the depth surface
272
* format, along with emitting the depth and stencil packets. In that
273
* case, we want to do a depth flush and stall, so the pipeline is not
274
* using these settings while we change the registers.
275
*/
276
cmd_buffer->state.pending_pipe_bits |=
277
ANV_PIPE_DEPTH_CACHE_FLUSH_BIT |
278
ANV_PIPE_DEPTH_STALL_BIT |
279
ANV_PIPE_END_OF_PIPE_SYNC_BIT;
280
}
281
#endif
282
283
#if GFX_VER == 7
284
/* The MI_LOAD/STORE_REGISTER_MEM commands which BLORP uses to implement
285
* indirect fast-clear colors can cause GPU hangs if we don't stall first.
286
* See genX(cmd_buffer_mi_memcpy) for more details.
287
*/
288
if (params->src.clear_color_addr.buffer ||
289
params->dst.clear_color_addr.buffer) {
290
anv_add_pending_pipe_bits(cmd_buffer,
291
ANV_PIPE_CS_STALL_BIT,
292
"before blorp prep fast clear");
293
}
294
#endif
295
296
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
297
298
genX(flush_pipeline_select_3d)(cmd_buffer);
299
300
genX(cmd_buffer_emit_gfx7_depth_flush)(cmd_buffer);
301
302
/* BLORP doesn't do anything fancy with depth such as discards, so we want
303
* the PMA fix off. Also, off is always the safe option.
304
*/
305
genX(cmd_buffer_enable_pma_fix)(cmd_buffer, false);
306
307
blorp_exec(batch, params);
308
309
#if GFX_VER >= 11
310
/* The PIPE_CONTROL command description says:
311
*
312
* "Whenever a Binding Table Index (BTI) used by a Render Taget Message
313
* points to a different RENDER_SURFACE_STATE, SW must issue a Render
314
* Target Cache Flush by enabling this bit. When render target flush
315
* is set due to new association of BTI, PS Scoreboard Stall bit must
316
* be set in this packet."
317
*/
318
anv_add_pending_pipe_bits(cmd_buffer,
319
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |
320
ANV_PIPE_STALL_AT_SCOREBOARD_BIT,
321
"after blorp BTI change");
322
#endif
323
324
cmd_buffer->state.gfx.vb_dirty = ~0;
325
cmd_buffer->state.gfx.dirty = ~0;
326
cmd_buffer->state.push_constants_dirty = ~0;
327
}
328
329