zink: Use optimal layout instead of general. Reduces valid layer warnings. Fixes...
[mesa.git] / src / gallium / drivers / zink / zink_context.c
1 /*
2 * Copyright 2018 Collabora Ltd.
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "zink_context.h"
25
26 #include "zink_batch.h"
27 #include "zink_compiler.h"
28 #include "zink_fence.h"
29 #include "zink_framebuffer.h"
30 #include "zink_pipeline.h"
31 #include "zink_program.h"
32 #include "zink_render_pass.h"
33 #include "zink_resource.h"
34 #include "zink_screen.h"
35 #include "zink_state.h"
36 #include "zink_surface.h"
37
38 #include "indices/u_primconvert.h"
39 #include "util/u_blitter.h"
40 #include "util/u_debug.h"
41 #include "util/u_format.h"
42 #include "util/u_framebuffer.h"
43 #include "util/u_helpers.h"
44 #include "util/u_inlines.h"
45
46 #include "nir.h"
47
48 #include "util/u_memory.h"
49 #include "util/u_prim.h"
50 #include "util/u_upload_mgr.h"
51
52 static void
53 zink_context_destroy(struct pipe_context *pctx)
54 {
55 struct zink_context *ctx = zink_context(pctx);
56 struct zink_screen *screen = zink_screen(pctx->screen);
57
58 if (vkQueueWaitIdle(ctx->queue) != VK_SUCCESS)
59 debug_printf("vkQueueWaitIdle failed\n");
60
61 for (int i = 0; i < ARRAY_SIZE(ctx->batches); ++i)
62 vkFreeCommandBuffers(screen->dev, ctx->cmdpool, 1, &ctx->batches[i].cmdbuf);
63 vkDestroyCommandPool(screen->dev, ctx->cmdpool, NULL);
64
65 util_primconvert_destroy(ctx->primconvert);
66 u_upload_destroy(pctx->stream_uploader);
67 slab_destroy_child(&ctx->transfer_pool);
68 util_blitter_destroy(ctx->blitter);
69 FREE(ctx);
70 }
71
72 static VkFilter
73 filter(enum pipe_tex_filter filter)
74 {
75 switch (filter) {
76 case PIPE_TEX_FILTER_NEAREST: return VK_FILTER_NEAREST;
77 case PIPE_TEX_FILTER_LINEAR: return VK_FILTER_LINEAR;
78 }
79 unreachable("unexpected filter");
80 }
81
82 static VkSamplerMipmapMode
83 sampler_mipmap_mode(enum pipe_tex_mipfilter filter)
84 {
85 switch (filter) {
86 case PIPE_TEX_MIPFILTER_NEAREST: return VK_SAMPLER_MIPMAP_MODE_NEAREST;
87 case PIPE_TEX_MIPFILTER_LINEAR: return VK_SAMPLER_MIPMAP_MODE_LINEAR;
88 case PIPE_TEX_MIPFILTER_NONE:
89 unreachable("PIPE_TEX_MIPFILTER_NONE should be dealt with earlier");
90 }
91 unreachable("unexpected filter");
92 }
93
94 static VkSamplerAddressMode
95 sampler_address_mode(enum pipe_tex_wrap filter)
96 {
97 switch (filter) {
98 case PIPE_TEX_WRAP_REPEAT: return VK_SAMPLER_ADDRESS_MODE_REPEAT;
99 case PIPE_TEX_WRAP_CLAMP: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; /* not technically correct, but kinda works */
100 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
101 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
102 case PIPE_TEX_WRAP_MIRROR_REPEAT: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
103 case PIPE_TEX_WRAP_MIRROR_CLAMP: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; /* not technically correct, but kinda works */
104 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
105 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; /* not technically correct, but kinda works */
106 }
107 unreachable("unexpected wrap");
108 }
109
110 static VkCompareOp
111 compare_op(enum pipe_compare_func op)
112 {
113 switch (op) {
114 case PIPE_FUNC_NEVER: return VK_COMPARE_OP_NEVER;
115 case PIPE_FUNC_LESS: return VK_COMPARE_OP_LESS;
116 case PIPE_FUNC_EQUAL: return VK_COMPARE_OP_EQUAL;
117 case PIPE_FUNC_LEQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL;
118 case PIPE_FUNC_GREATER: return VK_COMPARE_OP_GREATER;
119 case PIPE_FUNC_NOTEQUAL: return VK_COMPARE_OP_NOT_EQUAL;
120 case PIPE_FUNC_GEQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL;
121 case PIPE_FUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS;
122 }
123 unreachable("unexpected compare");
124 }
125
126 static void *
127 zink_create_sampler_state(struct pipe_context *pctx,
128 const struct pipe_sampler_state *state)
129 {
130 struct zink_screen *screen = zink_screen(pctx->screen);
131
132 VkSamplerCreateInfo sci = {};
133 sci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
134 sci.magFilter = filter(state->mag_img_filter);
135 sci.minFilter = filter(state->min_img_filter);
136
137 if (state->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) {
138 sci.mipmapMode = sampler_mipmap_mode(state->min_mip_filter);
139 sci.minLod = state->min_lod;
140 sci.maxLod = state->max_lod;
141 } else {
142 sci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
143 sci.minLod = 0;
144 sci.maxLod = 0;
145 }
146
147 sci.addressModeU = sampler_address_mode(state->wrap_s);
148 sci.addressModeV = sampler_address_mode(state->wrap_t);
149 sci.addressModeW = sampler_address_mode(state->wrap_r);
150 sci.mipLodBias = state->lod_bias;
151
152 if (state->compare_mode == PIPE_TEX_COMPARE_NONE)
153 sci.compareOp = VK_COMPARE_OP_NEVER;
154 else
155 sci.compareOp = compare_op(state->compare_func);
156
157 sci.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; // TODO
158 sci.unnormalizedCoordinates = !state->normalized_coords;
159
160 if (state->max_anisotropy > 1) {
161 sci.maxAnisotropy = state->max_anisotropy;
162 sci.anisotropyEnable = VK_TRUE;
163 }
164
165 VkSampler sampler;
166 VkResult err = vkCreateSampler(screen->dev, &sci, NULL, &sampler);
167 if (err != VK_SUCCESS)
168 return NULL;
169
170 return sampler;
171 }
172
173 static void
174 zink_bind_sampler_states(struct pipe_context *pctx,
175 enum pipe_shader_type shader,
176 unsigned start_slot,
177 unsigned num_samplers,
178 void **samplers)
179 {
180 struct zink_context *ctx = zink_context(pctx);
181 for (unsigned i = 0; i < num_samplers; ++i)
182 ctx->samplers[shader][start_slot + i] = (VkSampler)samplers[i];
183 ctx->num_samplers[shader] = start_slot + num_samplers;
184 }
185
186 static void
187 zink_delete_sampler_state(struct pipe_context *pctx,
188 void *sampler_state)
189 {
190 struct zink_batch *batch = zink_curr_batch(zink_context(pctx));
191 util_dynarray_append(&batch->zombie_samplers,
192 VkSampler, sampler_state);
193 }
194
195
196 static VkImageViewType
197 image_view_type(enum pipe_texture_target target)
198 {
199 switch (target) {
200 case PIPE_TEXTURE_1D: return VK_IMAGE_VIEW_TYPE_1D;
201 case PIPE_TEXTURE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
202 case PIPE_TEXTURE_2D: return VK_IMAGE_VIEW_TYPE_2D;
203 case PIPE_TEXTURE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
204 case PIPE_TEXTURE_CUBE: return VK_IMAGE_VIEW_TYPE_CUBE;
205 case PIPE_TEXTURE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
206 case PIPE_TEXTURE_3D: return VK_IMAGE_VIEW_TYPE_3D;
207 case PIPE_TEXTURE_RECT: return VK_IMAGE_VIEW_TYPE_2D; /* not sure */
208 default:
209 unreachable("unexpected target");
210 }
211 }
212
213 static VkComponentSwizzle
214 component_mapping(enum pipe_swizzle swizzle)
215 {
216 switch (swizzle) {
217 case PIPE_SWIZZLE_X: return VK_COMPONENT_SWIZZLE_R;
218 case PIPE_SWIZZLE_Y: return VK_COMPONENT_SWIZZLE_G;
219 case PIPE_SWIZZLE_Z: return VK_COMPONENT_SWIZZLE_B;
220 case PIPE_SWIZZLE_W: return VK_COMPONENT_SWIZZLE_A;
221 case PIPE_SWIZZLE_0: return VK_COMPONENT_SWIZZLE_ZERO;
222 case PIPE_SWIZZLE_1: return VK_COMPONENT_SWIZZLE_ONE;
223 case PIPE_SWIZZLE_NONE: return VK_COMPONENT_SWIZZLE_IDENTITY; // ???
224 default:
225 unreachable("unexpected swizzle");
226 }
227 }
228
229 static VkImageAspectFlags
230 sampler_aspect_from_format(enum pipe_format fmt)
231 {
232 if (util_format_is_depth_or_stencil(fmt)) {
233 const struct util_format_description *desc = util_format_description(fmt);
234 if (util_format_has_depth(desc))
235 return VK_IMAGE_ASPECT_DEPTH_BIT;
236 assert(util_format_has_stencil(desc));
237 return VK_IMAGE_ASPECT_STENCIL_BIT;
238 } else
239 return VK_IMAGE_ASPECT_COLOR_BIT;
240 }
241
242 static struct pipe_sampler_view *
243 zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres,
244 const struct pipe_sampler_view *state)
245 {
246 struct zink_screen *screen = zink_screen(pctx->screen);
247 struct zink_resource *res = zink_resource(pres);
248 struct zink_sampler_view *sampler_view = CALLOC_STRUCT(zink_sampler_view);
249
250 sampler_view->base = *state;
251 sampler_view->base.texture = NULL;
252 pipe_resource_reference(&sampler_view->base.texture, pres);
253 sampler_view->base.reference.count = 1;
254 sampler_view->base.context = pctx;
255
256 VkImageViewCreateInfo ivci = {};
257 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
258 ivci.image = res->image;
259 ivci.viewType = image_view_type(state->target);
260 ivci.format = zink_get_format(screen, state->format);
261 ivci.components.r = component_mapping(state->swizzle_r);
262 ivci.components.g = component_mapping(state->swizzle_g);
263 ivci.components.b = component_mapping(state->swizzle_b);
264 ivci.components.a = component_mapping(state->swizzle_a);
265
266 ivci.subresourceRange.aspectMask = sampler_aspect_from_format(state->format);
267 ivci.subresourceRange.baseMipLevel = state->u.tex.first_level;
268 ivci.subresourceRange.baseArrayLayer = state->u.tex.first_layer;
269 ivci.subresourceRange.levelCount = state->u.tex.last_level - state->u.tex.first_level + 1;
270 ivci.subresourceRange.layerCount = state->u.tex.last_layer - state->u.tex.first_layer + 1;
271
272 VkResult err = vkCreateImageView(screen->dev, &ivci, NULL, &sampler_view->image_view);
273 if (err != VK_SUCCESS) {
274 FREE(sampler_view);
275 return NULL;
276 }
277
278 return &sampler_view->base;
279 }
280
281 static void
282 zink_sampler_view_destroy(struct pipe_context *pctx,
283 struct pipe_sampler_view *pview)
284 {
285 struct zink_sampler_view *view = zink_sampler_view(pview);
286 vkDestroyImageView(zink_screen(pctx->screen)->dev, view->image_view, NULL);
287 FREE(view);
288 }
289
290 static void *
291 zink_create_vs_state(struct pipe_context *pctx,
292 const struct pipe_shader_state *shader)
293 {
294 struct nir_shader *nir;
295 if (shader->type != PIPE_SHADER_IR_NIR)
296 nir = zink_tgsi_to_nir(pctx->screen, shader->tokens);
297 else
298 nir = (struct nir_shader *)shader->ir.nir;
299
300 return zink_compile_nir(zink_screen(pctx->screen), nir);
301 }
302
303 static void
304 bind_stage(struct zink_context *ctx, enum pipe_shader_type stage,
305 struct zink_shader *shader)
306 {
307 assert(stage < PIPE_SHADER_COMPUTE);
308 ctx->gfx_stages[stage] = shader;
309 ctx->dirty |= ZINK_DIRTY_PROGRAM;
310 }
311
312 static void
313 zink_bind_vs_state(struct pipe_context *pctx,
314 void *cso)
315 {
316 bind_stage(zink_context(pctx), PIPE_SHADER_VERTEX, cso);
317 }
318
319 static void
320 zink_delete_vs_state(struct pipe_context *pctx,
321 void *cso)
322 {
323 zink_shader_free(zink_screen(pctx->screen), cso);
324 }
325
326 static void *
327 zink_create_fs_state(struct pipe_context *pctx,
328 const struct pipe_shader_state *shader)
329 {
330 struct nir_shader *nir;
331 if (shader->type != PIPE_SHADER_IR_NIR)
332 nir = zink_tgsi_to_nir(pctx->screen, shader->tokens);
333 else
334 nir = (struct nir_shader *)shader->ir.nir;
335
336 return zink_compile_nir(zink_screen(pctx->screen), nir);
337 }
338
339 static void
340 zink_bind_fs_state(struct pipe_context *pctx,
341 void *cso)
342 {
343 bind_stage(zink_context(pctx), PIPE_SHADER_FRAGMENT, cso);
344 }
345
346 static void
347 zink_delete_fs_state(struct pipe_context *pctx,
348 void *cso)
349 {
350 zink_shader_free(zink_screen(pctx->screen), cso);
351 }
352
353 static void
354 zink_set_polygon_stipple(struct pipe_context *pctx,
355 const struct pipe_poly_stipple *ps)
356 {
357 }
358
359 static void
360 zink_set_vertex_buffers(struct pipe_context *pctx,
361 unsigned start_slot,
362 unsigned num_buffers,
363 const struct pipe_vertex_buffer *buffers)
364 {
365 struct zink_context *ctx = zink_context(pctx);
366
367 if (buffers) {
368 for (int i = 0; i < num_buffers; ++i) {
369 const struct pipe_vertex_buffer *vb = buffers + i;
370 ctx->gfx_pipeline_state.bindings[start_slot + i].stride = vb->stride;
371 }
372 }
373
374 util_set_vertex_buffers_mask(ctx->buffers, &ctx->buffers_enabled_mask,
375 buffers, start_slot, num_buffers);
376 }
377
378 static void
379 zink_set_viewport_states(struct pipe_context *pctx,
380 unsigned start_slot,
381 unsigned num_viewports,
382 const struct pipe_viewport_state *state)
383 {
384 struct zink_context *ctx = zink_context(pctx);
385
386 for (unsigned i = 0; i < num_viewports; ++i) {
387 VkViewport viewport = {
388 state[i].translate[0] - state[i].scale[0],
389 state[i].translate[1] - state[i].scale[1],
390 state[i].scale[0] * 2,
391 state[i].scale[1] * 2,
392 state[i].translate[2] - state[i].scale[2],
393 state[i].translate[2] + state[i].scale[2]
394 };
395 ctx->viewport_states[start_slot + i] = state[i];
396 ctx->viewports[start_slot + i] = viewport;
397 }
398 ctx->num_viewports = start_slot + num_viewports;
399 }
400
401 static void
402 zink_set_scissor_states(struct pipe_context *pctx,
403 unsigned start_slot, unsigned num_scissors,
404 const struct pipe_scissor_state *states)
405 {
406 struct zink_context *ctx = zink_context(pctx);
407
408 for (unsigned i = 0; i < num_scissors; i++) {
409 VkRect2D scissor;
410
411 scissor.offset.x = states[i].minx;
412 scissor.offset.y = states[i].miny;
413 scissor.extent.width = states[i].maxx - states[i].minx;
414 scissor.extent.height = states[i].maxy - states[i].miny;
415 ctx->scissor_states[start_slot + i] = states[i];
416 ctx->scissors[start_slot + i] = scissor;
417 }
418 }
419
420 static void
421 zink_set_constant_buffer(struct pipe_context *pctx,
422 enum pipe_shader_type shader, uint index,
423 const struct pipe_constant_buffer *cb)
424 {
425 struct zink_context *ctx = zink_context(pctx);
426
427 if (cb) {
428 struct pipe_resource *buffer = cb->buffer;
429 unsigned offset = cb->buffer_offset;
430 if (cb->user_buffer) {
431 struct zink_screen *screen = zink_screen(pctx->screen);
432 u_upload_data(ctx->base.const_uploader, 0, cb->buffer_size,
433 screen->props.limits.minUniformBufferOffsetAlignment,
434 cb->user_buffer, &offset, &buffer);
435 }
436
437 pipe_resource_reference(&ctx->ubos[shader][index].buffer, buffer);
438 ctx->ubos[shader][index].buffer_offset = offset;
439 ctx->ubos[shader][index].buffer_size = cb->buffer_size;
440 ctx->ubos[shader][index].user_buffer = NULL;
441
442 if (cb->user_buffer)
443 pipe_resource_reference(&buffer, NULL);
444 } else {
445 pipe_resource_reference(&ctx->ubos[shader][index].buffer, NULL);
446 ctx->ubos[shader][index].buffer_offset = 0;
447 ctx->ubos[shader][index].buffer_size = 0;
448 ctx->ubos[shader][index].user_buffer = NULL;
449 }
450 }
451
452 static void
453 zink_set_sampler_views(struct pipe_context *pctx,
454 enum pipe_shader_type shader_type,
455 unsigned start_slot,
456 unsigned num_views,
457 struct pipe_sampler_view **views)
458 {
459 struct zink_context *ctx = zink_context(pctx);
460 assert(views);
461 for (unsigned i = 0; i < num_views; ++i) {
462 pipe_sampler_view_reference(
463 &ctx->image_views[shader_type][start_slot + i],
464 views[i]);
465 }
466 ctx->num_image_views[shader_type] = start_slot + num_views;
467 }
468
469 static void
470 zink_set_stencil_ref(struct pipe_context *pctx,
471 const struct pipe_stencil_ref *ref)
472 {
473 struct zink_context *ctx = zink_context(pctx);
474 ctx->stencil_ref = *ref;
475 }
476
477 static void
478 zink_set_clip_state(struct pipe_context *pctx,
479 const struct pipe_clip_state *pcs)
480 {
481 }
482
483 static struct zink_render_pass *
484 get_render_pass(struct zink_context *ctx)
485 {
486 struct zink_screen *screen = zink_screen(ctx->base.screen);
487 const struct pipe_framebuffer_state *fb = &ctx->fb_state;
488 struct zink_render_pass_state state;
489
490 for (int i = 0; i < fb->nr_cbufs; i++) {
491 struct zink_resource *cbuf = zink_resource(fb->cbufs[i]->texture);
492 state.rts[i].format = cbuf->format;
493 state.rts[i].samples = cbuf->base.nr_samples > 0 ? cbuf->base.nr_samples : VK_SAMPLE_COUNT_1_BIT;
494 }
495 state.num_cbufs = fb->nr_cbufs;
496
497 if (fb->zsbuf) {
498 struct zink_resource *zsbuf = zink_resource(fb->zsbuf->texture);
499 state.rts[fb->nr_cbufs].format = zsbuf->format;
500 state.rts[fb->nr_cbufs].samples = zsbuf->base.nr_samples > 0 ? zsbuf->base.nr_samples : VK_SAMPLE_COUNT_1_BIT;
501 }
502 state.have_zsbuf = fb->zsbuf != NULL;
503
504 struct hash_entry *entry = _mesa_hash_table_search(ctx->render_pass_cache,
505 &state);
506 if (!entry) {
507 struct zink_render_pass *rp;
508 rp = zink_create_render_pass(screen, &state);
509 entry = _mesa_hash_table_insert(ctx->render_pass_cache, &state, rp);
510 if (!entry)
511 return NULL;
512 }
513
514 return entry->data;
515 }
516
517 static struct zink_framebuffer *
518 get_framebuffer(struct zink_context *ctx)
519 {
520 struct zink_screen *screen = zink_screen(ctx->base.screen);
521
522 struct zink_framebuffer_state state = {};
523 state.rp = get_render_pass(ctx);
524 for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
525 struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
526 state.attachments[i] = zink_surface(psurf);
527 }
528
529 state.num_attachments = ctx->fb_state.nr_cbufs;
530 if (ctx->fb_state.zsbuf) {
531 struct pipe_surface *psurf = ctx->fb_state.zsbuf;
532 state.attachments[state.num_attachments++] = zink_surface(psurf);
533 }
534
535 state.width = ctx->fb_state.width;
536 state.height = ctx->fb_state.height;
537 state.layers = MAX2(ctx->fb_state.layers, 1);
538
539 struct hash_entry *entry = _mesa_hash_table_search(ctx->framebuffer_cache,
540 &state);
541 if (!entry) {
542 struct zink_framebuffer *fb = zink_create_framebuffer(screen, &state);
543 entry = _mesa_hash_table_insert(ctx->framebuffer_cache, &state, fb);
544 if (!entry)
545 return NULL;
546 }
547
548 return entry->data;
549 }
550
551 void
552 zink_begin_render_pass(struct zink_context *ctx, struct zink_batch *batch)
553 {
554 struct zink_screen *screen = zink_screen(ctx->base.screen);
555 assert(batch == zink_curr_batch(ctx));
556 assert(ctx->gfx_pipeline_state.render_pass);
557
558 struct pipe_framebuffer_state *fb_state = &ctx->fb_state;
559
560 VkRenderPassBeginInfo rpbi = {};
561 rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
562 rpbi.renderPass = ctx->gfx_pipeline_state.render_pass->render_pass;
563 rpbi.renderArea.offset.x = 0;
564 rpbi.renderArea.offset.y = 0;
565 rpbi.renderArea.extent.width = fb_state->width;
566 rpbi.renderArea.extent.height = fb_state->height;
567 rpbi.clearValueCount = 0;
568 rpbi.pClearValues = NULL;
569 rpbi.framebuffer = ctx->framebuffer->fb;
570
571 assert(ctx->gfx_pipeline_state.render_pass && ctx->framebuffer);
572 assert(!batch->rp || batch->rp == ctx->gfx_pipeline_state.render_pass);
573 assert(!batch->fb || batch->fb == ctx->framebuffer);
574
575 for (int i = 0; i < fb_state->nr_cbufs; i++) {
576 struct zink_resource *res = zink_resource(fb_state->cbufs[i]->texture);
577 if (res->layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
578 zink_resource_barrier(batch->cmdbuf, res, res->aspect,
579 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
580 }
581
582 if (fb_state->zsbuf) {
583 struct zink_resource *res = zink_resource(fb_state->zsbuf->texture);
584 if (res->layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
585 zink_resource_barrier(batch->cmdbuf, res, res->aspect,
586 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
587 }
588
589 zink_render_pass_reference(screen, &batch->rp, ctx->gfx_pipeline_state.render_pass);
590 zink_framebuffer_reference(screen, &batch->fb, ctx->framebuffer);
591
592 vkCmdBeginRenderPass(batch->cmdbuf, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
593 }
594
595 static void
596 flush_batch(struct zink_context *ctx)
597 {
598 struct zink_batch *batch = zink_curr_batch(ctx);
599 if (batch->rp)
600 vkCmdEndRenderPass(batch->cmdbuf);
601
602 zink_end_batch(ctx, batch);
603
604 ctx->curr_batch++;
605 if (ctx->curr_batch == ARRAY_SIZE(ctx->batches))
606 ctx->curr_batch = 0;
607
608 zink_start_batch(ctx, zink_curr_batch(ctx));
609 }
610
611 struct zink_batch *
612 zink_batch_rp(struct zink_context *ctx)
613 {
614 struct zink_batch *batch = zink_curr_batch(ctx);
615 if (!batch->rp) {
616 zink_begin_render_pass(ctx, batch);
617 assert(batch->rp);
618 }
619 return batch;
620 }
621
622 struct zink_batch *
623 zink_batch_no_rp(struct zink_context *ctx)
624 {
625 struct zink_batch *batch = zink_curr_batch(ctx);
626 if (batch->rp) {
627 /* flush batch and get a new one */
628 flush_batch(ctx);
629 batch = zink_curr_batch(ctx);
630 assert(!batch->rp);
631 }
632 return batch;
633 }
634
635 static void
636 zink_set_framebuffer_state(struct pipe_context *pctx,
637 const struct pipe_framebuffer_state *state)
638 {
639 struct zink_context *ctx = zink_context(pctx);
640 struct zink_screen *screen = zink_screen(pctx->screen);
641
642 VkSampleCountFlagBits rast_samples = VK_SAMPLE_COUNT_1_BIT;
643 for (int i = 0; i < state->nr_cbufs; i++)
644 rast_samples = MAX2(rast_samples, state->cbufs[i]->texture->nr_samples);
645 if (state->zsbuf && state->zsbuf->texture->nr_samples)
646 rast_samples = MAX2(rast_samples, state->zsbuf->texture->nr_samples);
647
648 util_copy_framebuffer_state(&ctx->fb_state, state);
649
650 struct zink_framebuffer *fb = get_framebuffer(ctx);
651 zink_framebuffer_reference(screen, &ctx->framebuffer, fb);
652 zink_render_pass_reference(screen, &ctx->gfx_pipeline_state.render_pass, fb->rp);
653
654 ctx->gfx_pipeline_state.rast_samples = rast_samples;
655 ctx->gfx_pipeline_state.num_attachments = state->nr_cbufs;
656
657 struct zink_batch *batch = zink_batch_no_rp(ctx);
658
659 for (int i = 0; i < state->nr_cbufs; i++) {
660 struct zink_resource *res = zink_resource(state->cbufs[i]->texture);
661 if (res->layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
662 zink_resource_barrier(batch->cmdbuf, res, res->aspect,
663 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
664 }
665
666 if (state->zsbuf) {
667 struct zink_resource *res = zink_resource(state->zsbuf->texture);
668 if (res->layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
669 zink_resource_barrier(batch->cmdbuf, res, res->aspect,
670 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
671 }
672 }
673
674 static void
675 zink_set_blend_color(struct pipe_context *pctx,
676 const struct pipe_blend_color *color)
677 {
678 struct zink_context *ctx = zink_context(pctx);
679 memcpy(ctx->blend_constants, color->color, sizeof(float) * 4);
680 }
681
682 static void
683 zink_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)
684 {
685 struct zink_context *ctx = zink_context(pctx);
686 ctx->gfx_pipeline_state.sample_mask = sample_mask;
687 }
688
689 static VkAccessFlags
690 access_src_flags(VkImageLayout layout)
691 {
692 switch (layout) {
693 case VK_IMAGE_LAYOUT_UNDEFINED:
694 case VK_IMAGE_LAYOUT_GENERAL:
695 return 0;
696
697 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
698 return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
699 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
700 return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
701
702 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
703 return VK_ACCESS_SHADER_READ_BIT;
704
705 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
706 return VK_ACCESS_TRANSFER_READ_BIT;
707
708 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
709 return VK_ACCESS_TRANSFER_WRITE_BIT;
710
711 case VK_IMAGE_LAYOUT_PREINITIALIZED:
712 return VK_ACCESS_HOST_WRITE_BIT;
713
714 default:
715 unreachable("unexpected layout");
716 }
717 }
718
719 static VkAccessFlags
720 access_dst_flags(VkImageLayout layout)
721 {
722 switch (layout) {
723 case VK_IMAGE_LAYOUT_UNDEFINED:
724 case VK_IMAGE_LAYOUT_GENERAL:
725 return 0;
726
727 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
728 return VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
729 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
730 return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
731
732 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
733 return VK_ACCESS_TRANSFER_READ_BIT;
734
735 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
736 return VK_ACCESS_TRANSFER_WRITE_BIT;
737
738 default:
739 unreachable("unexpected layout");
740 }
741 }
742
743 static VkPipelineStageFlags
744 pipeline_dst_stage(VkImageLayout layout)
745 {
746 switch (layout) {
747 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
748 return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
749 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
750 return VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
751
752 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
753 return VK_PIPELINE_STAGE_TRANSFER_BIT;
754 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
755 return VK_PIPELINE_STAGE_TRANSFER_BIT;
756
757 default:
758 return VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
759 }
760 }
761
762 static VkPipelineStageFlags
763 pipeline_src_stage(VkImageLayout layout)
764 {
765 switch (layout) {
766 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
767 return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
768 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
769 return VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
770
771 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
772 return VK_PIPELINE_STAGE_TRANSFER_BIT;
773 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
774 return VK_PIPELINE_STAGE_TRANSFER_BIT;
775
776 default:
777 return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
778 }
779 }
780
781
782 void
783 zink_resource_barrier(VkCommandBuffer cmdbuf, struct zink_resource *res,
784 VkImageAspectFlags aspect, VkImageLayout new_layout)
785 {
786 VkImageSubresourceRange isr = {
787 aspect,
788 0, VK_REMAINING_MIP_LEVELS,
789 0, VK_REMAINING_ARRAY_LAYERS
790 };
791
792 VkImageMemoryBarrier imb = {
793 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
794 NULL,
795 access_src_flags(res->layout),
796 access_dst_flags(new_layout),
797 res->layout,
798 new_layout,
799 VK_QUEUE_FAMILY_IGNORED,
800 VK_QUEUE_FAMILY_IGNORED,
801 res->image,
802 isr
803 };
804 vkCmdPipelineBarrier(
805 cmdbuf,
806 pipeline_src_stage(res->layout),
807 pipeline_dst_stage(new_layout),
808 0,
809 0, NULL,
810 0, NULL,
811 1, &imb
812 );
813
814 res->layout = new_layout;
815 }
816
817 static void
818 zink_clear(struct pipe_context *pctx,
819 unsigned buffers,
820 const union pipe_color_union *pcolor,
821 double depth, unsigned stencil)
822 {
823 struct zink_context *ctx = zink_context(pctx);
824 struct pipe_framebuffer_state *fb = &ctx->fb_state;
825
826 /* FIXME: this is very inefficient; if no renderpass has been started yet,
827 * we should record the clear if it's full-screen, and apply it as we
828 * start the render-pass. Otherwise we can do a partial out-of-renderpass
829 * clear.
830 */
831 struct zink_batch *batch = zink_batch_rp(ctx);
832
833 VkClearAttachment attachments[1 + PIPE_MAX_COLOR_BUFS];
834 int num_attachments = 0;
835
836 if (buffers & PIPE_CLEAR_COLOR) {
837 VkClearColorValue color;
838 color.float32[0] = pcolor->f[0];
839 color.float32[1] = pcolor->f[1];
840 color.float32[2] = pcolor->f[2];
841 color.float32[3] = pcolor->f[3];
842
843 for (unsigned i = 0; i < fb->nr_cbufs; i++) {
844 if (!(buffers & (PIPE_CLEAR_COLOR0 << i)) || !fb->cbufs[i])
845 continue;
846
847 attachments[num_attachments].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
848 attachments[num_attachments].colorAttachment = i;
849 attachments[num_attachments].clearValue.color = color;
850 ++num_attachments;
851 }
852 }
853
854 if (buffers & PIPE_CLEAR_DEPTHSTENCIL && fb->zsbuf) {
855 VkImageAspectFlags aspect = 0;
856 if (buffers & PIPE_CLEAR_DEPTH)
857 aspect |= VK_IMAGE_ASPECT_DEPTH_BIT;
858 if (buffers & PIPE_CLEAR_STENCIL)
859 aspect |= VK_IMAGE_ASPECT_STENCIL_BIT;
860
861 attachments[num_attachments].aspectMask = aspect;
862 attachments[num_attachments].clearValue.depthStencil.depth = depth;
863 attachments[num_attachments].clearValue.depthStencil.stencil = stencil;
864 ++num_attachments;
865 }
866
867 VkClearRect cr;
868 cr.rect.offset.x = 0;
869 cr.rect.offset.y = 0;
870 cr.rect.extent.width = fb->width;
871 cr.rect.extent.height = fb->height;
872 cr.baseArrayLayer = 0;
873 cr.layerCount = util_framebuffer_get_num_layers(fb);
874 vkCmdClearAttachments(batch->cmdbuf, num_attachments, attachments, 1, &cr);
875 }
876
877 VkShaderStageFlagBits
878 zink_shader_stage(enum pipe_shader_type type)
879 {
880 VkShaderStageFlagBits stages[] = {
881 [PIPE_SHADER_VERTEX] = VK_SHADER_STAGE_VERTEX_BIT,
882 [PIPE_SHADER_FRAGMENT] = VK_SHADER_STAGE_FRAGMENT_BIT,
883 [PIPE_SHADER_GEOMETRY] = VK_SHADER_STAGE_GEOMETRY_BIT,
884 [PIPE_SHADER_TESS_CTRL] = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
885 [PIPE_SHADER_TESS_EVAL] = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
886 [PIPE_SHADER_COMPUTE] = VK_SHADER_STAGE_COMPUTE_BIT,
887 };
888 return stages[type];
889 }
890
891 static VkDescriptorSet
892 allocate_descriptor_set(struct zink_screen *screen,
893 struct zink_batch *batch,
894 struct zink_gfx_program *prog)
895 {
896 assert(batch->descs_left >= prog->num_descriptors);
897 VkDescriptorSetAllocateInfo dsai;
898 memset((void *)&dsai, 0, sizeof(dsai));
899 dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
900 dsai.pNext = NULL;
901 dsai.descriptorPool = batch->descpool;
902 dsai.descriptorSetCount = 1;
903 dsai.pSetLayouts = &prog->dsl;
904
905 VkDescriptorSet desc_set;
906 if (vkAllocateDescriptorSets(screen->dev, &dsai, &desc_set) != VK_SUCCESS) {
907 debug_printf("ZINK: failed to allocate descriptor set :/");
908 return VK_NULL_HANDLE;
909 }
910
911 batch->descs_left -= prog->num_descriptors;
912 return desc_set;
913 }
914
915 static void
916 zink_bind_vertex_buffers(struct zink_batch *batch, struct zink_context *ctx)
917 {
918 VkBuffer buffers[PIPE_MAX_ATTRIBS];
919 VkDeviceSize buffer_offsets[PIPE_MAX_ATTRIBS];
920 const struct zink_vertex_elements_state *elems = ctx->element_state;
921 for (unsigned i = 0; i < elems->hw_state.num_bindings; i++) {
922 struct pipe_vertex_buffer *vb = ctx->buffers + ctx->element_state->binding_map[i];
923 assert(vb && vb->buffer.resource);
924 struct zink_resource *res = zink_resource(vb->buffer.resource);
925 buffers[i] = res->buffer;
926 buffer_offsets[i] = vb->buffer_offset;
927 zink_batch_reference_resoure(batch, res);
928 }
929
930 if (elems->hw_state.num_bindings > 0)
931 vkCmdBindVertexBuffers(batch->cmdbuf, 0,
932 elems->hw_state.num_bindings,
933 buffers, buffer_offsets);
934 }
935
936 static uint32_t
937 hash_gfx_program(const void *key)
938 {
939 return _mesa_hash_data(key, sizeof(struct zink_shader *) * (PIPE_SHADER_TYPES - 1));
940 }
941
942 static bool
943 equals_gfx_program(const void *a, const void *b)
944 {
945 return memcmp(a, b, sizeof(struct zink_shader *) * (PIPE_SHADER_TYPES - 1)) == 0;
946 }
947
948 static uint32_t
949 hash_render_pass_state(const void *key)
950 {
951 return _mesa_hash_data(key, sizeof(struct zink_render_pass_state));
952 }
953
954 static bool
955 equals_render_pass_state(const void *a, const void *b)
956 {
957 return memcmp(a, b, sizeof(struct zink_render_pass_state)) == 0;
958 }
959
960 static uint32_t
961 hash_framebuffer_state(const void *key)
962 {
963 struct zink_framebuffer_state *s = (struct zink_framebuffer_state*)key;
964 return _mesa_hash_data(key, sizeof(struct zink_framebuffer_state) + sizeof(s->attachments) * s->num_attachments);
965 }
966
967 static bool
968 equals_framebuffer_state(const void *a, const void *b)
969 {
970 struct zink_framebuffer_state *s = (struct zink_framebuffer_state*)a;
971 return memcmp(a, b, sizeof(struct zink_framebuffer_state) + sizeof(s->attachments) * s->num_attachments) == 0;
972 }
973
974 static struct zink_gfx_program *
975 get_gfx_program(struct zink_context *ctx)
976 {
977 if (ctx->dirty & ZINK_DIRTY_PROGRAM) {
978 struct hash_entry *entry = _mesa_hash_table_search(ctx->program_cache,
979 ctx->gfx_stages);
980 if (!entry) {
981 struct zink_gfx_program *prog;
982 prog = zink_create_gfx_program(zink_screen(ctx->base.screen),
983 ctx->gfx_stages);
984 entry = _mesa_hash_table_insert(ctx->program_cache, prog->stages, prog);
985 if (!entry)
986 return NULL;
987 }
988 ctx->curr_program = entry->data;
989 ctx->dirty &= ~ZINK_DIRTY_PROGRAM;
990 }
991
992 assert(ctx->curr_program);
993 return ctx->curr_program;
994 }
995
996 static void
997 zink_draw_vbo(struct pipe_context *pctx,
998 const struct pipe_draw_info *dinfo)
999 {
1000 struct zink_context *ctx = zink_context(pctx);
1001 struct zink_screen *screen = zink_screen(pctx->screen);
1002 struct zink_rasterizer_state *rast_state = ctx->rast_state;
1003
1004 if (dinfo->mode >= PIPE_PRIM_QUADS ||
1005 dinfo->mode == PIPE_PRIM_LINE_LOOP ||
1006 dinfo->index_size == 1) {
1007 if (!u_trim_pipe_prim(dinfo->mode, (unsigned *)&dinfo->count))
1008 return;
1009
1010 util_primconvert_save_rasterizer_state(ctx->primconvert, &rast_state->base);
1011 util_primconvert_draw_vbo(ctx->primconvert, dinfo);
1012 return;
1013 }
1014
1015 struct zink_gfx_program *gfx_program = get_gfx_program(ctx);
1016 if (!gfx_program)
1017 return;
1018
1019 VkPipeline pipeline = zink_get_gfx_pipeline(screen, gfx_program,
1020 &ctx->gfx_pipeline_state,
1021 dinfo->mode);
1022
1023 bool depth_bias = false;
1024 switch (u_reduced_prim(dinfo->mode)) {
1025 case PIPE_PRIM_POINTS:
1026 depth_bias = rast_state->offset_point;
1027 break;
1028
1029 case PIPE_PRIM_LINES:
1030 depth_bias = rast_state->offset_line;
1031 break;
1032
1033 case PIPE_PRIM_TRIANGLES:
1034 depth_bias = rast_state->offset_tri;
1035 break;
1036
1037 default:
1038 unreachable("unexpected reduced prim");
1039 }
1040
1041 unsigned index_offset = 0;
1042 struct pipe_resource *index_buffer = NULL;
1043 if (dinfo->index_size > 0) {
1044 if (dinfo->has_user_indices) {
1045 if (!util_upload_index_buffer(pctx, dinfo, &index_buffer, &index_offset)) {
1046 debug_printf("util_upload_index_buffer() failed\n");
1047 return;
1048 }
1049 } else
1050 index_buffer = dinfo->index.resource;
1051 }
1052
1053 VkWriteDescriptorSet wds[PIPE_SHADER_TYPES * PIPE_MAX_CONSTANT_BUFFERS + PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS];
1054 VkDescriptorBufferInfo buffer_infos[PIPE_SHADER_TYPES * PIPE_MAX_CONSTANT_BUFFERS];
1055 VkDescriptorImageInfo image_infos[PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS];
1056 int num_wds = 0, num_buffer_info = 0, num_image_info = 0;
1057
1058 struct zink_resource *transitions[PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS];
1059 int num_transitions = 0;
1060
1061 for (int i = 0; i < ARRAY_SIZE(ctx->gfx_stages); i++) {
1062 struct zink_shader *shader = ctx->gfx_stages[i];
1063 if (!shader)
1064 continue;
1065
1066 for (int j = 0; j < shader->num_bindings; j++) {
1067 int index = shader->bindings[j].index;
1068 if (shader->bindings[j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
1069 assert(ctx->ubos[i][index].buffer_size > 0);
1070 assert(ctx->ubos[i][index].buffer_size <= screen->props.limits.maxUniformBufferRange);
1071 assert(ctx->ubos[i][index].buffer);
1072 struct zink_resource *res = zink_resource(ctx->ubos[i][index].buffer);
1073 buffer_infos[num_buffer_info].buffer = res->buffer;
1074 buffer_infos[num_buffer_info].offset = ctx->ubos[i][index].buffer_offset;
1075 buffer_infos[num_buffer_info].range = ctx->ubos[i][index].buffer_size;
1076 wds[num_wds].pBufferInfo = buffer_infos + num_buffer_info;
1077 ++num_buffer_info;
1078 } else {
1079 struct pipe_sampler_view *psampler_view = ctx->image_views[i][index];
1080 assert(psampler_view);
1081 struct zink_sampler_view *sampler_view = zink_sampler_view(psampler_view);
1082
1083 struct zink_resource *res = zink_resource(psampler_view->texture);
1084 VkImageLayout layout = res->layout;
1085 if (layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
1086 layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL &&
1087 layout != VK_IMAGE_LAYOUT_GENERAL) {
1088 transitions[num_transitions++] = res;
1089 layout = VK_IMAGE_LAYOUT_GENERAL;
1090 }
1091 image_infos[num_image_info].imageLayout = layout;
1092 image_infos[num_image_info].imageView = sampler_view->image_view;
1093 image_infos[num_image_info].sampler = ctx->samplers[i][index];
1094 wds[num_wds].pImageInfo = image_infos + num_image_info;
1095 ++num_image_info;
1096 }
1097
1098 wds[num_wds].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1099 wds[num_wds].pNext = NULL;
1100 wds[num_wds].dstBinding = shader->bindings[j].binding;
1101 wds[num_wds].dstArrayElement = 0;
1102 wds[num_wds].descriptorCount = 1;
1103 wds[num_wds].descriptorType = shader->bindings[j].type;
1104 ++num_wds;
1105 }
1106 }
1107
1108 struct zink_batch *batch;
1109 if (num_transitions > 0) {
1110 batch = zink_batch_no_rp(ctx);
1111
1112 for (int i = 0; i < num_transitions; ++i)
1113 zink_resource_barrier(batch->cmdbuf, transitions[i],
1114 transitions[i]->aspect,
1115 VK_IMAGE_LAYOUT_GENERAL);
1116 }
1117
1118 batch = zink_batch_rp(ctx);
1119
1120 if (batch->descs_left < gfx_program->num_descriptors) {
1121 flush_batch(ctx);
1122 batch = zink_batch_rp(ctx);
1123 assert(batch->descs_left >= gfx_program->num_descriptors);
1124 }
1125
1126 VkDescriptorSet desc_set = allocate_descriptor_set(screen, batch,
1127 gfx_program);
1128 assert(desc_set != VK_NULL_HANDLE);
1129
1130 for (int i = 0; i < ARRAY_SIZE(ctx->gfx_stages); i++) {
1131 struct zink_shader *shader = ctx->gfx_stages[i];
1132 if (!shader)
1133 continue;
1134
1135 for (int j = 0; j < shader->num_bindings; j++) {
1136 int index = shader->bindings[j].index;
1137 if (shader->bindings[j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
1138 struct zink_resource *res = zink_resource(ctx->ubos[i][index].buffer);
1139 zink_batch_reference_resoure(batch, res);
1140 } else {
1141 struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->image_views[i][index]);
1142 zink_batch_reference_sampler_view(batch, sampler_view);
1143 }
1144 }
1145 }
1146
1147 vkCmdSetViewport(batch->cmdbuf, 0, ctx->num_viewports, ctx->viewports);
1148 if (ctx->rast_state->base.scissor)
1149 vkCmdSetScissor(batch->cmdbuf, 0, ctx->num_viewports, ctx->scissors);
1150 else if (ctx->fb_state.width && ctx->fb_state.height) {
1151 VkRect2D fb_scissor = {};
1152 fb_scissor.extent.width = ctx->fb_state.width;
1153 fb_scissor.extent.height = ctx->fb_state.height;
1154 vkCmdSetScissor(batch->cmdbuf, 0, 1, &fb_scissor);
1155 }
1156
1157 vkCmdSetStencilReference(batch->cmdbuf, VK_STENCIL_FACE_FRONT_BIT, ctx->stencil_ref.ref_value[0]);
1158 vkCmdSetStencilReference(batch->cmdbuf, VK_STENCIL_FACE_BACK_BIT, ctx->stencil_ref.ref_value[1]);
1159
1160 if (depth_bias)
1161 vkCmdSetDepthBias(batch->cmdbuf, rast_state->offset_units, rast_state->offset_clamp, rast_state->offset_scale);
1162 else
1163 vkCmdSetDepthBias(batch->cmdbuf, 0.0f, 0.0f, 0.0f);
1164
1165 if (ctx->gfx_pipeline_state.blend_state->need_blend_constants)
1166 vkCmdSetBlendConstants(batch->cmdbuf, ctx->blend_constants);
1167
1168 for (int i = 0; i < num_wds; ++i)
1169 wds[i].dstSet = desc_set;
1170
1171 vkUpdateDescriptorSets(screen->dev, num_wds, wds, 0, NULL);
1172
1173 vkCmdBindPipeline(batch->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1174 vkCmdBindDescriptorSets(batch->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS,
1175 gfx_program->layout, 0, 1, &desc_set, 0, NULL);
1176 zink_bind_vertex_buffers(batch, ctx);
1177
1178 if (dinfo->index_size > 0) {
1179 assert(dinfo->index_size != 1);
1180 VkIndexType index_type = dinfo->index_size == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32;
1181 struct zink_resource *res = zink_resource(index_buffer);
1182 vkCmdBindIndexBuffer(batch->cmdbuf, res->buffer, index_offset, index_type);
1183 zink_batch_reference_resoure(batch, res);
1184 vkCmdDrawIndexed(batch->cmdbuf,
1185 dinfo->count, dinfo->instance_count,
1186 dinfo->start, dinfo->index_bias, dinfo->start_instance);
1187 } else
1188 vkCmdDraw(batch->cmdbuf, dinfo->count, dinfo->instance_count, dinfo->start, dinfo->start_instance);
1189
1190 if (dinfo->index_size > 0 && dinfo->has_user_indices)
1191 pipe_resource_reference(&index_buffer, NULL);
1192 }
1193
1194 static void
1195 zink_flush(struct pipe_context *pctx,
1196 struct pipe_fence_handle **pfence,
1197 enum pipe_flush_flags flags)
1198 {
1199 struct zink_context *ctx = zink_context(pctx);
1200
1201 struct zink_batch *batch = zink_curr_batch(ctx);
1202 flush_batch(ctx);
1203
1204 if (pfence)
1205 zink_fence_reference(zink_screen(pctx->screen),
1206 (struct zink_fence **)pfence,
1207 batch->fence);
1208
1209 /* HACK:
1210 * For some strange reason, we need to finish before presenting, or else
1211 * we start rendering on top of the back-buffer for the next frame. This
1212 * seems like a bug in the DRI-driver to me, because we really should
1213 * be properly protected by fences here, and the back-buffer should
1214 * either be swapped with the front-buffer, or blitted from. But for
1215 * some strange reason, neither of these things happen.
1216 */
1217 if (flags & PIPE_FLUSH_END_OF_FRAME)
1218 pctx->screen->fence_finish(pctx->screen, pctx,
1219 (struct pipe_fence_handle *)batch->fence,
1220 PIPE_TIMEOUT_INFINITE);
1221 }
1222
1223 static bool
1224 blit_resolve(struct zink_context *ctx, const struct pipe_blit_info *info)
1225 {
1226 if (info->mask != PIPE_MASK_RGBA ||
1227 info->scissor_enable ||
1228 info->alpha_blend)
1229 return false;
1230
1231 struct zink_resource *src = zink_resource(info->src.resource);
1232 struct zink_resource *dst = zink_resource(info->dst.resource);
1233
1234 struct zink_batch *batch = zink_batch_no_rp(ctx);
1235
1236 zink_batch_reference_resoure(batch, src);
1237 zink_batch_reference_resoure(batch, dst);
1238
1239 VkImageResolve region = {};
1240
1241 region.srcSubresource.aspectMask = src->aspect;
1242 region.srcSubresource.mipLevel = info->src.level;
1243 region.srcSubresource.baseArrayLayer = 0; // no clue
1244 region.srcSubresource.layerCount = 1; // no clue
1245 region.srcOffset.x = info->src.box.x;
1246 region.srcOffset.y = info->src.box.y;
1247 region.srcOffset.z = info->src.box.z;
1248
1249 region.dstSubresource.aspectMask = dst->aspect;
1250 region.dstSubresource.mipLevel = info->dst.level;
1251 region.dstSubresource.baseArrayLayer = 0; // no clue
1252 region.dstSubresource.layerCount = 1; // no clue
1253 region.dstOffset.x = info->dst.box.x;
1254 region.dstOffset.y = info->dst.box.y;
1255 region.dstOffset.z = info->dst.box.z;
1256
1257 region.extent.width = info->dst.box.width;
1258 region.extent.height = info->dst.box.height;
1259 region.extent.depth = info->dst.box.depth;
1260 vkCmdResolveImage(batch->cmdbuf, src->image, src->layout,
1261 dst->image, dst->layout,
1262 1, &region);
1263
1264 /* HACK: I have no idea why this is needed, but without it ioquake3
1265 * randomly keeps fading to black.
1266 */
1267 flush_batch(ctx);
1268
1269 return true;
1270 }
1271
1272 static bool
1273 blit_native(struct zink_context *ctx, const struct pipe_blit_info *info)
1274 {
1275 if (info->mask != PIPE_MASK_RGBA ||
1276 info->scissor_enable ||
1277 info->alpha_blend)
1278 return false;
1279
1280 struct zink_resource *src = zink_resource(info->src.resource);
1281 struct zink_resource *dst = zink_resource(info->dst.resource);
1282
1283 struct zink_batch *batch = zink_batch_no_rp(ctx);
1284 zink_batch_reference_resoure(batch, src);
1285 zink_batch_reference_resoure(batch, dst);
1286
1287 if (dst->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
1288 zink_resource_barrier(batch->cmdbuf, dst, dst->aspect,
1289 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1290
1291 VkImageBlit region = {};
1292 region.srcSubresource.aspectMask = src->aspect;
1293 region.srcSubresource.mipLevel = info->src.level;
1294 region.srcOffsets[0].x = info->src.box.x;
1295 region.srcOffsets[0].y = info->src.box.y;
1296 region.srcOffsets[1].x = info->src.box.x + info->src.box.width;
1297 region.srcOffsets[1].y = info->src.box.y + info->src.box.height;
1298
1299 if (src->base.array_size > 1) {
1300 region.srcOffsets[0].z = 0;
1301 region.srcOffsets[1].z = 1;
1302 region.srcSubresource.baseArrayLayer = info->src.box.z;
1303 region.srcSubresource.layerCount = info->src.box.depth;
1304 } else {
1305 region.srcOffsets[0].z = info->src.box.z;
1306 region.srcOffsets[1].z = info->src.box.z + info->src.box.depth;
1307 region.srcSubresource.baseArrayLayer = 0;
1308 region.srcSubresource.layerCount = 1;
1309 }
1310
1311 region.dstSubresource.aspectMask = dst->aspect;
1312 region.dstSubresource.mipLevel = info->dst.level;
1313 region.dstOffsets[0].x = info->dst.box.x;
1314 region.dstOffsets[0].y = info->dst.box.y;
1315 region.dstOffsets[1].x = info->dst.box.x + info->dst.box.width;
1316 region.dstOffsets[1].y = info->dst.box.y + info->dst.box.height;
1317
1318 if (dst->base.array_size > 1) {
1319 region.dstOffsets[0].z = 0;
1320 region.dstOffsets[1].z = 1;
1321 region.dstSubresource.baseArrayLayer = info->dst.box.z;
1322 region.dstSubresource.layerCount = info->dst.box.depth;
1323 } else {
1324 region.dstOffsets[0].z = info->dst.box.z;
1325 region.dstOffsets[1].z = info->dst.box.z + info->dst.box.depth;
1326 region.dstSubresource.baseArrayLayer = 0;
1327 region.dstSubresource.layerCount = 1;
1328 }
1329
1330 vkCmdBlitImage(batch->cmdbuf, src->image, src->layout,
1331 dst->image, dst->layout,
1332 1, &region,
1333 filter(info->filter));
1334
1335 /* HACK: I have no idea why this is needed, but without it ioquake3
1336 * randomly keeps fading to black.
1337 */
1338 flush_batch(ctx);
1339
1340 return true;
1341 }
1342
1343 static void
1344 zink_blit(struct pipe_context *pctx,
1345 const struct pipe_blit_info *info)
1346 {
1347 struct zink_context *ctx = zink_context(pctx);
1348 if (info->src.resource->nr_samples > 1 &&
1349 info->dst.resource->nr_samples <= 1) {
1350 if (blit_resolve(ctx, info))
1351 return;
1352 } else {
1353 if (blit_native(ctx, info))
1354 return;
1355 }
1356
1357 if (!util_blitter_is_blit_supported(ctx->blitter, info)) {
1358 debug_printf("blit unsupported %s -> %s\n",
1359 util_format_short_name(info->src.resource->format),
1360 util_format_short_name(info->dst.resource->format));
1361 return;
1362 }
1363
1364 util_blitter_save_blend(ctx->blitter, ctx->gfx_pipeline_state.blend_state);
1365 util_blitter_save_depth_stencil_alpha(ctx->blitter, ctx->gfx_pipeline_state.depth_stencil_alpha_state);
1366 util_blitter_save_vertex_elements(ctx->blitter, ctx->element_state);
1367 util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref);
1368 util_blitter_save_rasterizer(ctx->blitter, ctx->rast_state);
1369 util_blitter_save_fragment_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_FRAGMENT]);
1370 util_blitter_save_vertex_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_VERTEX]);
1371 util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
1372 util_blitter_save_viewport(ctx->blitter, ctx->viewport_states);
1373 util_blitter_save_scissor(ctx->blitter, ctx->scissor_states);
1374 util_blitter_save_fragment_sampler_states(ctx->blitter,
1375 ctx->num_samplers[PIPE_SHADER_FRAGMENT],
1376 (void **)ctx->samplers[PIPE_SHADER_FRAGMENT]);
1377 util_blitter_save_fragment_sampler_views(ctx->blitter,
1378 ctx->num_image_views[PIPE_SHADER_FRAGMENT],
1379 ctx->image_views[PIPE_SHADER_FRAGMENT]);
1380 util_blitter_save_fragment_constant_buffer_slot(ctx->blitter, ctx->ubos[PIPE_SHADER_FRAGMENT]);
1381 util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->buffers);
1382 util_blitter_save_sample_mask(ctx->blitter, ctx->gfx_pipeline_state.sample_mask);
1383
1384 util_blitter_blit(ctx->blitter, info);
1385 }
1386
1387 static void
1388 zink_flush_resource(struct pipe_context *pipe,
1389 struct pipe_resource *resource)
1390 {
1391 }
1392
1393 static void
1394 zink_resource_copy_region(struct pipe_context *pctx,
1395 struct pipe_resource *pdst,
1396 unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz,
1397 struct pipe_resource *psrc,
1398 unsigned src_level, const struct pipe_box *src_box)
1399 {
1400 struct zink_resource *dst = zink_resource(pdst);
1401 struct zink_resource *src = zink_resource(psrc);
1402 struct zink_context *ctx = zink_context(pctx);
1403 if (dst->base.target != PIPE_BUFFER && src->base.target != PIPE_BUFFER) {
1404 VkImageCopy region = {};
1405
1406 region.srcSubresource.aspectMask = src->aspect;
1407 region.srcSubresource.mipLevel = src_level;
1408 region.srcSubresource.layerCount = 1;
1409 if (src->base.array_size > 1) {
1410 region.srcSubresource.baseArrayLayer = src_box->z;
1411 region.srcSubresource.layerCount = src_box->depth;
1412 region.extent.depth = 1;
1413 } else {
1414 region.srcOffset.z = src_box->z;
1415 region.srcSubresource.layerCount = 1;
1416 region.extent.depth = src_box->depth;
1417 }
1418
1419 region.srcOffset.x = src_box->x;
1420 region.srcOffset.y = src_box->y;
1421
1422 region.dstSubresource.aspectMask = dst->aspect;
1423 region.dstSubresource.mipLevel = dst_level;
1424 if (dst->base.array_size > 1) {
1425 region.dstSubresource.baseArrayLayer = dstz;
1426 region.dstSubresource.layerCount = src_box->depth;
1427 } else {
1428 region.dstOffset.z = dstz;
1429 region.dstSubresource.layerCount = 1;
1430 }
1431
1432 region.dstOffset.x = dstx;
1433 region.dstOffset.y = dsty;
1434 region.extent.width = src_box->width;
1435 region.extent.height = src_box->height;
1436
1437 struct zink_batch *batch = zink_batch_no_rp(ctx);
1438 zink_batch_reference_resoure(batch, src);
1439 zink_batch_reference_resoure(batch, dst);
1440
1441 if (src->layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
1442 zink_resource_barrier(batch->cmdbuf, src, src->aspect,
1443 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1444 }
1445
1446 if (dst->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
1447 zink_resource_barrier(batch->cmdbuf, dst, dst->aspect,
1448 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1449 }
1450
1451 vkCmdCopyImage(batch->cmdbuf, src->image, src->layout,
1452 dst->image, dst->layout,
1453 1, &region);
1454 } else
1455 debug_printf("zink: TODO resource copy\n");
1456 }
1457
1458 struct pipe_context *
1459 zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
1460 {
1461 struct zink_screen *screen = zink_screen(pscreen);
1462 struct zink_context *ctx = CALLOC_STRUCT(zink_context);
1463
1464 ctx->base.screen = pscreen;
1465 ctx->base.priv = priv;
1466
1467 ctx->base.destroy = zink_context_destroy;
1468
1469 zink_context_state_init(&ctx->base);
1470
1471 ctx->base.create_sampler_state = zink_create_sampler_state;
1472 ctx->base.bind_sampler_states = zink_bind_sampler_states;
1473 ctx->base.delete_sampler_state = zink_delete_sampler_state;
1474
1475 ctx->base.create_sampler_view = zink_create_sampler_view;
1476 ctx->base.set_sampler_views = zink_set_sampler_views;
1477 ctx->base.sampler_view_destroy = zink_sampler_view_destroy;
1478
1479 ctx->base.create_vs_state = zink_create_vs_state;
1480 ctx->base.bind_vs_state = zink_bind_vs_state;
1481 ctx->base.delete_vs_state = zink_delete_vs_state;
1482
1483 ctx->base.create_fs_state = zink_create_fs_state;
1484 ctx->base.bind_fs_state = zink_bind_fs_state;
1485 ctx->base.delete_fs_state = zink_delete_fs_state;
1486
1487 ctx->base.set_polygon_stipple = zink_set_polygon_stipple;
1488 ctx->base.set_vertex_buffers = zink_set_vertex_buffers;
1489 ctx->base.set_viewport_states = zink_set_viewport_states;
1490 ctx->base.set_scissor_states = zink_set_scissor_states;
1491 ctx->base.set_constant_buffer = zink_set_constant_buffer;
1492 ctx->base.set_framebuffer_state = zink_set_framebuffer_state;
1493 ctx->base.set_stencil_ref = zink_set_stencil_ref;
1494 ctx->base.set_clip_state = zink_set_clip_state;
1495 ctx->base.set_blend_color = zink_set_blend_color;
1496
1497 ctx->base.set_sample_mask = zink_set_sample_mask;
1498
1499 ctx->base.clear = zink_clear;
1500 ctx->base.draw_vbo = zink_draw_vbo;
1501 ctx->base.flush = zink_flush;
1502
1503 ctx->base.resource_copy_region = zink_resource_copy_region;
1504 ctx->base.blit = zink_blit;
1505
1506 ctx->base.flush_resource = zink_flush_resource;
1507 zink_context_surface_init(&ctx->base);
1508 zink_context_resource_init(&ctx->base);
1509 zink_context_query_init(&ctx->base);
1510
1511 slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);
1512
1513 ctx->base.stream_uploader = u_upload_create_default(&ctx->base);
1514 ctx->base.const_uploader = ctx->base.stream_uploader;
1515
1516 int prim_hwsupport = 1 << PIPE_PRIM_POINTS |
1517 1 << PIPE_PRIM_LINES |
1518 1 << PIPE_PRIM_LINE_STRIP |
1519 1 << PIPE_PRIM_TRIANGLES |
1520 1 << PIPE_PRIM_TRIANGLE_STRIP |
1521 1 << PIPE_PRIM_TRIANGLE_FAN;
1522
1523 ctx->primconvert = util_primconvert_create(&ctx->base, prim_hwsupport);
1524 if (!ctx->primconvert)
1525 goto fail;
1526
1527 ctx->blitter = util_blitter_create(&ctx->base);
1528 if (!ctx->blitter)
1529 goto fail;
1530
1531 VkCommandPoolCreateInfo cpci = {};
1532 cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1533 cpci.queueFamilyIndex = screen->gfx_queue;
1534 cpci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1535 if (vkCreateCommandPool(screen->dev, &cpci, NULL, &ctx->cmdpool) != VK_SUCCESS)
1536 goto fail;
1537
1538 VkCommandBufferAllocateInfo cbai = {};
1539 cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1540 cbai.commandPool = ctx->cmdpool;
1541 cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1542 cbai.commandBufferCount = 1;
1543
1544 VkDescriptorPoolSize sizes[] = {
1545 {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, ZINK_BATCH_DESC_SIZE}
1546 };
1547 VkDescriptorPoolCreateInfo dpci = {};
1548 dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1549 dpci.pPoolSizes = sizes;
1550 dpci.poolSizeCount = ARRAY_SIZE(sizes);
1551 dpci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1552 dpci.maxSets = ZINK_BATCH_DESC_SIZE;
1553
1554 for (int i = 0; i < ARRAY_SIZE(ctx->batches); ++i) {
1555 if (vkAllocateCommandBuffers(screen->dev, &cbai, &ctx->batches[i].cmdbuf) != VK_SUCCESS)
1556 goto fail;
1557
1558 ctx->batches[i].resources = _mesa_set_create(NULL, _mesa_hash_pointer,
1559 _mesa_key_pointer_equal);
1560 ctx->batches[i].sampler_views = _mesa_set_create(NULL,
1561 _mesa_hash_pointer,
1562 _mesa_key_pointer_equal);
1563
1564 if (!ctx->batches[i].resources || !ctx->batches[i].sampler_views)
1565 goto fail;
1566
1567 util_dynarray_init(&ctx->batches[i].zombie_samplers, NULL);
1568
1569 if (vkCreateDescriptorPool(screen->dev, &dpci, 0,
1570 &ctx->batches[i].descpool) != VK_SUCCESS)
1571 goto fail;
1572 }
1573
1574 vkGetDeviceQueue(screen->dev, screen->gfx_queue, 0, &ctx->queue);
1575
1576 ctx->program_cache = _mesa_hash_table_create(NULL,
1577 hash_gfx_program,
1578 equals_gfx_program);
1579 ctx->render_pass_cache = _mesa_hash_table_create(NULL,
1580 hash_render_pass_state,
1581 equals_render_pass_state);
1582 ctx->framebuffer_cache = _mesa_hash_table_create(NULL,
1583 hash_framebuffer_state,
1584 equals_framebuffer_state);
1585
1586 if (!ctx->program_cache || !ctx->render_pass_cache ||
1587 !ctx->framebuffer_cache)
1588 goto fail;
1589
1590 ctx->dirty = ZINK_DIRTY_PROGRAM;
1591
1592 /* start the first batch */
1593 zink_start_batch(ctx, zink_curr_batch(ctx));
1594
1595 return &ctx->base;
1596
1597 fail:
1598 if (ctx) {
1599 vkDestroyCommandPool(screen->dev, ctx->cmdpool, NULL);
1600 FREE(ctx);
1601 }
1602 return NULL;
1603 }