zink: wait for idle on context-destroy
[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_cmdbuf.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->cmdbufs); ++i)
62 vkFreeCommandBuffers(screen->dev, ctx->cmdpool, 1, &ctx->cmdbufs[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 void *
111 zink_create_sampler_state(struct pipe_context *pctx,
112 const struct pipe_sampler_state *state)
113 {
114 struct zink_screen *screen = zink_screen(pctx->screen);
115
116 VkSamplerCreateInfo sci = {};
117 sci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
118 sci.magFilter = filter(state->mag_img_filter);
119 sci.minFilter = filter(state->min_img_filter);
120
121 if (state->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) {
122 sci.mipmapMode = sampler_mipmap_mode(state->min_mip_filter);
123 sci.minLod = state->min_lod;
124 sci.maxLod = state->max_lod;
125 } else {
126 sci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
127 sci.minLod = 0;
128 sci.maxLod = 0;
129 }
130
131 sci.addressModeU = sampler_address_mode(state->wrap_s);
132 sci.addressModeV = sampler_address_mode(state->wrap_t);
133 sci.addressModeW = sampler_address_mode(state->wrap_r);
134 sci.mipLodBias = state->lod_bias;
135 sci.compareOp = VK_COMPARE_OP_NEVER; // TODO
136 sci.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; // TODO
137
138 if (state->max_anisotropy > 1) {
139 sci.maxAnisotropy = state->max_anisotropy;
140 sci.anisotropyEnable = VK_TRUE;
141 }
142
143 VkSampler sampler;
144 VkResult err = vkCreateSampler(screen->dev, &sci, NULL, &sampler);
145 if (err != VK_SUCCESS)
146 return NULL;
147
148 return sampler;
149 }
150
151 static void
152 zink_bind_sampler_states(struct pipe_context *pctx,
153 enum pipe_shader_type shader,
154 unsigned start_slot,
155 unsigned num_samplers,
156 void **samplers)
157 {
158 struct zink_context *ctx = zink_context(pctx);
159 for (unsigned i = 0; i < num_samplers; ++i)
160 ctx->samplers[shader][start_slot + i] = (VkSampler)samplers[i];
161 }
162
163 static void
164 zink_delete_sampler_state(struct pipe_context *pctx,
165 void *sampler_state)
166 {
167 struct zink_screen *screen = zink_screen(pctx->screen);
168 vkDestroySampler(screen->dev, sampler_state, NULL);
169 }
170
171
172 static VkImageViewType
173 image_view_type(enum pipe_texture_target target)
174 {
175 switch (target) {
176 case PIPE_TEXTURE_1D: return VK_IMAGE_VIEW_TYPE_1D;
177 case PIPE_TEXTURE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
178 case PIPE_TEXTURE_2D: return VK_IMAGE_VIEW_TYPE_2D;
179 case PIPE_TEXTURE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
180 case PIPE_TEXTURE_CUBE: return VK_IMAGE_VIEW_TYPE_CUBE;
181 case PIPE_TEXTURE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
182 case PIPE_TEXTURE_3D: return VK_IMAGE_VIEW_TYPE_3D;
183 case PIPE_TEXTURE_RECT: return VK_IMAGE_VIEW_TYPE_2D; /* not sure */
184 default:
185 unreachable("unexpected target");
186 }
187 }
188
189 static VkComponentSwizzle
190 component_mapping(enum pipe_swizzle swizzle)
191 {
192 switch (swizzle) {
193 case PIPE_SWIZZLE_X: return VK_COMPONENT_SWIZZLE_R;
194 case PIPE_SWIZZLE_Y: return VK_COMPONENT_SWIZZLE_G;
195 case PIPE_SWIZZLE_Z: return VK_COMPONENT_SWIZZLE_B;
196 case PIPE_SWIZZLE_W: return VK_COMPONENT_SWIZZLE_A;
197 case PIPE_SWIZZLE_0: return VK_COMPONENT_SWIZZLE_ZERO;
198 case PIPE_SWIZZLE_1: return VK_COMPONENT_SWIZZLE_ONE;
199 case PIPE_SWIZZLE_NONE: return VK_COMPONENT_SWIZZLE_IDENTITY; // ???
200 default:
201 unreachable("unexpected swizzle");
202 }
203 }
204
205 static struct pipe_sampler_view *
206 zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres,
207 const struct pipe_sampler_view *state)
208 {
209 struct zink_screen *screen = zink_screen(pctx->screen);
210 struct zink_resource *res = zink_resource(pres);
211 struct zink_sampler_view *sampler_view = CALLOC_STRUCT(zink_sampler_view);
212
213 sampler_view->base = *state;
214 sampler_view->base.texture = NULL;
215 pipe_resource_reference(&sampler_view->base.texture, pres);
216 sampler_view->base.reference.count = 1;
217 sampler_view->base.context = pctx;
218
219 VkImageViewCreateInfo ivci = {};
220 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
221 ivci.image = res->image;
222 ivci.viewType = image_view_type(state->target);
223 ivci.format = zink_get_format(state->format);
224 ivci.components.r = component_mapping(state->swizzle_r);
225 ivci.components.g = component_mapping(state->swizzle_g);
226 ivci.components.b = component_mapping(state->swizzle_b);
227 ivci.components.a = component_mapping(state->swizzle_a);
228 ivci.subresourceRange.aspectMask = zink_aspect_from_format(state->format);
229 ivci.subresourceRange.baseMipLevel = state->u.tex.first_level;
230 ivci.subresourceRange.baseArrayLayer = state->u.tex.first_layer;
231 ivci.subresourceRange.levelCount = state->u.tex.last_level - state->u.tex.first_level + 1;
232 ivci.subresourceRange.layerCount = state->u.tex.last_layer - state->u.tex.first_layer + 1;
233
234 VkResult err = vkCreateImageView(screen->dev, &ivci, NULL, &sampler_view->image_view);
235 if (err != VK_SUCCESS) {
236 FREE(sampler_view);
237 return NULL;
238 }
239
240 return &sampler_view->base;
241 }
242
243 static void
244 zink_destroy_sampler_view(struct pipe_context *pctx,
245 struct pipe_sampler_view *pview)
246 {
247 struct zink_sampler_view *view = zink_sampler_view(pview);
248 vkDestroyImageView(zink_screen(pctx->screen)->dev, view->image_view, NULL);
249 FREE(view);
250 }
251
252 static void *
253 zink_create_vs_state(struct pipe_context *pctx,
254 const struct pipe_shader_state *shader)
255 {
256 struct nir_shader *nir;
257 if (shader->type != PIPE_SHADER_IR_NIR)
258 nir = zink_tgsi_to_nir(pctx->screen, shader->tokens);
259 else
260 nir = (struct nir_shader *)shader->ir.nir;
261
262 return zink_compile_nir(zink_screen(pctx->screen), nir);
263 }
264
265 static void
266 bind_stage(struct zink_context *ctx, enum pipe_shader_type stage,
267 struct zink_shader *shader)
268 {
269 assert(stage < PIPE_SHADER_COMPUTE);
270 ctx->gfx_stages[stage] = shader;
271 ctx->dirty |= ZINK_DIRTY_PROGRAM;
272 }
273
274 static void
275 zink_bind_vs_state(struct pipe_context *pctx,
276 void *cso)
277 {
278 bind_stage(zink_context(pctx), PIPE_SHADER_VERTEX, cso);
279 }
280
281 static void
282 zink_delete_vs_state(struct pipe_context *pctx,
283 void *cso)
284 {
285 zink_shader_free(zink_screen(pctx->screen), cso);
286 }
287
288 static void *
289 zink_create_fs_state(struct pipe_context *pctx,
290 const struct pipe_shader_state *shader)
291 {
292 struct nir_shader *nir;
293 if (shader->type != PIPE_SHADER_IR_NIR)
294 nir = zink_tgsi_to_nir(pctx->screen, shader->tokens);
295 else
296 nir = (struct nir_shader *)shader->ir.nir;
297
298 return zink_compile_nir(zink_screen(pctx->screen), nir);
299 }
300
301 static void
302 zink_bind_fs_state(struct pipe_context *pctx,
303 void *cso)
304 {
305 bind_stage(zink_context(pctx), PIPE_SHADER_FRAGMENT, cso);
306 }
307
308 static void
309 zink_delete_fs_state(struct pipe_context *pctx,
310 void *cso)
311 {
312 zink_shader_free(zink_screen(pctx->screen), cso);
313 }
314
315 static void
316 zink_set_polygon_stipple(struct pipe_context *pctx,
317 const struct pipe_poly_stipple *ps)
318 {
319 }
320
321 static void
322 zink_set_vertex_buffers(struct pipe_context *pctx,
323 unsigned start_slot,
324 unsigned num_buffers,
325 const struct pipe_vertex_buffer *buffers)
326 {
327 struct zink_context *ctx = zink_context(pctx);
328
329 if (buffers) {
330 for (int i = 0; i < num_buffers; ++i) {
331 const struct pipe_vertex_buffer *vb = buffers + i;
332 ctx->gfx_pipeline_state.bindings[start_slot + i].stride = vb->stride;
333 }
334 }
335
336 util_set_vertex_buffers_mask(ctx->buffers, &ctx->buffers_enabled_mask,
337 buffers, start_slot, num_buffers);
338 }
339
340 static void
341 zink_set_viewport_states(struct pipe_context *pctx,
342 unsigned start_slot,
343 unsigned num_viewports,
344 const struct pipe_viewport_state *state)
345 {
346 struct zink_context *ctx = zink_context(pctx);
347
348 for (unsigned i = 0; i < num_viewports; ++i) {
349 VkViewport viewport = {
350 state[i].translate[0] - state[i].scale[0],
351 state[i].translate[1] - state[i].scale[1],
352 state[i].scale[0] * 2,
353 state[i].scale[1] * 2,
354 state[i].translate[2] - state[i].scale[2],
355 state[i].translate[2] + state[i].scale[2]
356 };
357 ctx->viewports[start_slot + i] = viewport;
358 }
359 ctx->num_viewports = start_slot + num_viewports;
360 }
361
362 static void
363 zink_set_scissor_states(struct pipe_context *pctx,
364 unsigned start_slot, unsigned num_scissors,
365 const struct pipe_scissor_state *states)
366 {
367 struct zink_context *ctx = zink_context(pctx);
368
369 for (unsigned i = 0; i < num_scissors; i++) {
370 VkRect2D scissor;
371
372 scissor.offset.x = states[i].minx;
373 scissor.offset.y = states[i].miny;
374 scissor.extent.width = states[i].maxx - states[i].minx;
375 scissor.extent.height = states[i].maxy - states[i].miny;
376 ctx->scissors[start_slot + i] = scissor;
377 }
378 ctx->num_scissors = start_slot + num_scissors;
379 }
380
381 static void
382 zink_set_constant_buffer(struct pipe_context *pctx,
383 enum pipe_shader_type shader, uint index,
384 const struct pipe_constant_buffer *cb)
385 {
386 struct zink_context *ctx = zink_context(pctx);
387
388 if (cb) {
389 struct pipe_resource *buffer = cb->buffer;
390 unsigned offset = cb->buffer_offset;
391 if (cb->user_buffer)
392 u_upload_data(ctx->base.const_uploader, 0, cb->buffer_size, 64,
393 cb->user_buffer, &offset, &buffer);
394
395 pipe_resource_reference(&ctx->ubos[shader][index].buffer, buffer);
396 ctx->ubos[shader][index].buffer_offset = offset;
397 ctx->ubos[shader][index].buffer_size = cb->buffer_size;
398 ctx->ubos[shader][index].user_buffer = NULL;
399
400 if (cb->user_buffer)
401 pipe_resource_reference(&buffer, NULL);
402 } else {
403 pipe_resource_reference(&ctx->ubos[shader][index].buffer, NULL);
404 ctx->ubos[shader][index].buffer_offset = 0;
405 ctx->ubos[shader][index].buffer_size = 0;
406 ctx->ubos[shader][index].user_buffer = NULL;
407 }
408 }
409
410 static void
411 zink_set_sampler_views(struct pipe_context *pctx,
412 enum pipe_shader_type shader_type,
413 unsigned start_slot,
414 unsigned num_views,
415 struct pipe_sampler_view **views)
416 {
417 struct zink_context *ctx = zink_context(pctx);
418 assert(views);
419 for (unsigned i = 0; i < num_views; ++i) {
420 pipe_sampler_view_reference(
421 &ctx->image_views[shader_type][start_slot + i],
422 views[i]);
423 }
424 }
425
426 static void
427 zink_set_stencil_ref(struct pipe_context *pctx,
428 const struct pipe_stencil_ref *ref)
429 {
430 struct zink_context *ctx = zink_context(pctx);
431 ctx->stencil_ref[0] = ref->ref_value[0];
432 ctx->stencil_ref[1] = ref->ref_value[1];
433 }
434
435 static void
436 zink_set_clip_state(struct pipe_context *pctx,
437 const struct pipe_clip_state *pcs)
438 {
439 }
440
441 static struct zink_render_pass *
442 get_render_pass(struct zink_context *ctx,
443 const struct pipe_framebuffer_state *fb)
444 {
445 struct zink_render_pass_state state;
446
447 for (int i = 0; i < fb->nr_cbufs; i++) {
448 struct zink_resource *cbuf = zink_resource(fb->cbufs[i]->texture);
449 state.rts[i].format = cbuf->format;
450 }
451 state.num_cbufs = fb->nr_cbufs;
452
453 if (fb->zsbuf) {
454 struct zink_resource *zsbuf = zink_resource(fb->zsbuf->texture);
455 state.rts[fb->nr_cbufs].format = zsbuf->format;
456 }
457 state.have_zsbuf = fb->zsbuf != NULL;
458
459 // TODO: cache instead!
460 return zink_create_render_pass(zink_screen(ctx->base.screen), &state);
461 }
462
463 static struct zink_framebuffer *
464 get_framebuffer(struct zink_context *ctx,
465 const struct pipe_framebuffer_state *fb,
466 struct zink_render_pass *rp)
467 {
468 // TODO: cache!
469 return zink_create_framebuffer(zink_screen(ctx->base.screen), fb, rp);
470 }
471
472 static void
473 zink_set_framebuffer_state(struct pipe_context *pctx,
474 const struct pipe_framebuffer_state *state)
475 {
476 struct zink_context *ctx = zink_context(pctx);
477 struct zink_screen *screen = zink_screen(pctx->screen);
478
479 struct zink_render_pass *rp = get_render_pass(ctx, state);
480 zink_render_pass_reference(screen, &ctx->gfx_pipeline_state.render_pass, rp);
481
482 struct zink_framebuffer *fb = get_framebuffer(ctx, state, rp);
483 zink_framebuffer_reference(screen, &ctx->framebuffer, fb);
484 zink_framebuffer_reference(screen, &fb, NULL);
485 zink_render_pass_reference(screen, &rp, NULL);
486
487 ctx->gfx_pipeline_state.num_attachments = state->nr_cbufs;
488
489 util_copy_framebuffer_state(&ctx->fb_state, state);
490
491 struct zink_cmdbuf *cmdbuf = zink_start_cmdbuf(ctx);
492 if (!cmdbuf)
493 return;
494
495 for (int i = 0; i < state->nr_cbufs; i++) {
496 struct zink_resource *res = zink_resource(state->cbufs[i]->texture);
497 if (res->layout != VK_IMAGE_LAYOUT_GENERAL &&
498 res->layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
499 zink_resource_barrier(cmdbuf->cmdbuf, res, res->aspect,
500 VK_IMAGE_LAYOUT_GENERAL);
501 }
502
503 if (state->zsbuf) {
504 struct zink_resource *res = zink_resource(state->zsbuf->texture);
505 if (res->layout != VK_IMAGE_LAYOUT_GENERAL &&
506 res->layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
507 zink_resource_barrier(cmdbuf->cmdbuf, res, res->aspect,
508 VK_IMAGE_LAYOUT_GENERAL);
509 }
510
511 zink_end_cmdbuf(ctx, cmdbuf);
512 }
513
514 static void
515 zink_set_active_query_state(struct pipe_context *pctx, bool enable)
516 {
517 }
518
519 static void
520 zink_set_blend_color(struct pipe_context *pctx,
521 const struct pipe_blend_color *color)
522 {
523 struct zink_context *ctx = zink_context(pctx);
524 memcpy(ctx->blend_constants, color->color, sizeof(float) * 4);
525 }
526
527 static VkAccessFlags
528 access_flags(VkImageLayout layout)
529 {
530 switch (layout) {
531 case VK_IMAGE_LAYOUT_UNDEFINED:
532 case VK_IMAGE_LAYOUT_GENERAL:
533 return 0;
534
535 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
536 return VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
537 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
538 return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
539
540 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
541 return VK_ACCESS_SHADER_READ_BIT;
542
543 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
544 return VK_ACCESS_TRANSFER_READ_BIT;
545
546 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
547 return VK_ACCESS_TRANSFER_WRITE_BIT;
548
549 case VK_IMAGE_LAYOUT_PREINITIALIZED:
550 return VK_ACCESS_HOST_WRITE_BIT;
551
552 default:
553 unreachable("unexpected layout");
554 }
555 }
556
557 void
558 zink_resource_barrier(VkCommandBuffer cmdbuf, struct zink_resource *res,
559 VkImageAspectFlags aspect, VkImageLayout new_layout)
560 {
561 VkImageSubresourceRange isr = {
562 aspect,
563 0, VK_REMAINING_MIP_LEVELS,
564 0, VK_REMAINING_ARRAY_LAYERS
565 };
566
567 VkImageMemoryBarrier imb = {
568 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
569 NULL,
570 access_flags(res->layout),
571 access_flags(new_layout),
572 res->layout,
573 new_layout,
574 VK_QUEUE_FAMILY_IGNORED,
575 VK_QUEUE_FAMILY_IGNORED,
576 res->image,
577 isr
578 };
579 vkCmdPipelineBarrier(
580 cmdbuf,
581 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
582 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
583 0,
584 0, NULL,
585 0, NULL,
586 1, &imb
587 );
588
589 res->layout = new_layout;
590 }
591
592 static void
593 zink_clear(struct pipe_context *pctx,
594 unsigned buffers,
595 const union pipe_color_union *pcolor,
596 double depth, unsigned stencil)
597 {
598 struct zink_context *ctx = zink_context(pctx);
599 struct pipe_framebuffer_state *fb = &ctx->fb_state;
600
601 struct zink_cmdbuf *cmdbuf = zink_start_cmdbuf(ctx);
602 if (!cmdbuf)
603 return;
604
605 // first transition all images to a compatible layout
606 if (buffers & PIPE_CLEAR_COLOR) {
607 for (unsigned i = 0; i < fb->nr_cbufs; i++) {
608 if (!(buffers & (PIPE_CLEAR_COLOR0 << i)) || !fb->cbufs[i])
609 continue;
610
611 struct zink_resource *cbuf = zink_resource(fb->cbufs[i]->texture);
612
613 if (cbuf->layout != VK_IMAGE_LAYOUT_GENERAL &&
614 cbuf->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
615 zink_resource_barrier(cmdbuf->cmdbuf, cbuf, cbuf->aspect,
616 VK_IMAGE_LAYOUT_GENERAL);
617 }
618 }
619
620 VkImageAspectFlags depthStencilAspect = 0;
621 if (buffers & PIPE_CLEAR_DEPTHSTENCIL && fb->zsbuf) {
622 struct zink_resource *zsbuf = zink_resource(fb->zsbuf->texture);
623 if (buffers & PIPE_CLEAR_DEPTH)
624 depthStencilAspect |= VK_IMAGE_ASPECT_DEPTH_BIT;
625 if (buffers & PIPE_CLEAR_STENCIL)
626 depthStencilAspect |= VK_IMAGE_ASPECT_STENCIL_BIT;
627
628 if (zsbuf->layout != VK_IMAGE_LAYOUT_GENERAL &&
629 zsbuf->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
630 zink_resource_barrier(cmdbuf->cmdbuf, zsbuf, depthStencilAspect,
631 VK_IMAGE_LAYOUT_GENERAL);
632 }
633
634 VkClearColorValue color;
635 color.float32[0] = pcolor->f[0];
636 color.float32[1] = pcolor->f[1];
637 color.float32[2] = pcolor->f[2];
638 color.float32[3] = pcolor->f[3];
639
640 if (buffers & PIPE_CLEAR_COLOR) {
641 for (unsigned i = 0; i < fb->nr_cbufs; i++) {
642 if (!(buffers & (PIPE_CLEAR_COLOR0 << i)) || !fb->cbufs[i])
643 continue;
644
645 struct zink_resource *cbuf = zink_resource(fb->cbufs[i]->texture);
646
647 VkImageSubresourceRange range;
648 range.aspectMask = cbuf->aspect;
649 range.baseMipLevel = 0;
650 range.levelCount = VK_REMAINING_MIP_LEVELS;
651 range.baseArrayLayer = 0;
652 range.layerCount = VK_REMAINING_ARRAY_LAYERS;
653 vkCmdClearColorImage(cmdbuf->cmdbuf,
654 cbuf->image, VK_IMAGE_LAYOUT_GENERAL,
655 &color,
656 1, &range);
657 }
658 }
659
660 if (depthStencilAspect) {
661 struct zink_resource *zsbuf = zink_resource(fb->zsbuf->texture);
662
663 VkClearDepthStencilValue zsvalue = { depth, stencil };
664
665 VkImageSubresourceRange range;
666 range.aspectMask = depthStencilAspect;
667 range.baseMipLevel = 0;
668 range.levelCount = VK_REMAINING_MIP_LEVELS;
669 range.baseArrayLayer = 0;
670 range.layerCount = VK_REMAINING_ARRAY_LAYERS;
671
672 vkCmdClearDepthStencilImage(cmdbuf->cmdbuf,
673 zsbuf->image, VK_IMAGE_LAYOUT_GENERAL,
674 &zsvalue,
675 1, &range);
676 }
677
678 zink_end_cmdbuf(ctx, cmdbuf);
679 }
680
681 VkShaderStageFlagBits
682 zink_shader_stage(enum pipe_shader_type type)
683 {
684 VkShaderStageFlagBits stages[] = {
685 [PIPE_SHADER_VERTEX] = VK_SHADER_STAGE_VERTEX_BIT,
686 [PIPE_SHADER_FRAGMENT] = VK_SHADER_STAGE_FRAGMENT_BIT,
687 [PIPE_SHADER_GEOMETRY] = VK_SHADER_STAGE_GEOMETRY_BIT,
688 [PIPE_SHADER_TESS_CTRL] = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
689 [PIPE_SHADER_TESS_EVAL] = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
690 [PIPE_SHADER_COMPUTE] = VK_SHADER_STAGE_COMPUTE_BIT,
691 };
692 return stages[type];
693 }
694
695 static VkDescriptorSet
696 allocate_descriptor_set(struct zink_context *ctx, VkDescriptorSetLayout dsl)
697 {
698 struct zink_screen *screen = zink_screen(ctx->base.screen);
699 VkDescriptorSetAllocateInfo dsai;
700 memset((void *)&dsai, 0, sizeof(dsai));
701 dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
702 dsai.pNext = NULL;
703 dsai.descriptorPool = ctx->descpool;
704 dsai.descriptorSetCount = 1;
705 dsai.pSetLayouts = &dsl;
706
707 VkDescriptorSet desc_set;
708 if (vkAllocateDescriptorSets(screen->dev, &dsai, &desc_set) != VK_SUCCESS) {
709 if (vkResetDescriptorPool(screen->dev, ctx->descpool, 0) != VK_SUCCESS) {
710 fprintf(stderr, "vkResetDescriptorPool failed\n");
711 return VK_NULL_HANDLE;
712 }
713 if (vkAllocateDescriptorSets(screen->dev, &dsai, &desc_set) != VK_SUCCESS) {
714 fprintf(stderr, "vkAllocateDescriptorSets failed\n");
715 return VK_NULL_HANDLE;
716 }
717 }
718
719 return desc_set;
720 }
721
722 static VkPrimitiveTopology
723 zink_primitive_topology(enum pipe_prim_type mode)
724 {
725 switch (mode) {
726 case PIPE_PRIM_POINTS:
727 return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
728
729 case PIPE_PRIM_LINES:
730 return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
731
732 case PIPE_PRIM_LINE_STRIP:
733 return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
734
735 case PIPE_PRIM_TRIANGLES:
736 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
737
738 case PIPE_PRIM_TRIANGLE_STRIP:
739 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
740
741 case PIPE_PRIM_TRIANGLE_FAN:
742 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
743
744 default:
745 unreachable("unexpected enum pipe_prim_type");
746 }
747 }
748
749 static void
750 zink_bind_vertex_buffers(struct zink_cmdbuf *cmdbuf, struct zink_context *ctx)
751 {
752 VkBuffer buffers[PIPE_MAX_ATTRIBS];
753 VkDeviceSize buffer_offsets[PIPE_MAX_ATTRIBS];
754 struct zink_vertex_elements_state *elems = ctx->gfx_pipeline_state.element_state;
755 for (unsigned i = 0; i < elems->num_bindings; i++) {
756 struct pipe_vertex_buffer *vb = ctx->buffers + elems->binding_map[i];
757 assert(vb && vb->buffer.resource);
758 struct zink_resource *res = zink_resource(vb->buffer.resource);
759 buffers[i] = res->buffer;
760 buffer_offsets[i] = vb->buffer_offset;
761 zink_cmdbuf_reference_resoure(cmdbuf, res);
762 }
763
764 if (elems->num_bindings > 0)
765 vkCmdBindVertexBuffers(cmdbuf->cmdbuf, 0, elems->num_bindings, buffers, buffer_offsets);
766 }
767
768 static void
769 begin_render_pass(struct zink_screen *screen, struct zink_cmdbuf *cmdbuf,
770 struct zink_render_pass *rp, struct zink_framebuffer *fb,
771 unsigned width, unsigned height)
772 {
773 VkRenderPassBeginInfo rpbi = {};
774 rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
775 rpbi.renderPass = rp->render_pass;
776 rpbi.renderArea.offset.x = 0;
777 rpbi.renderArea.offset.y = 0;
778 rpbi.renderArea.extent.width = width;
779 rpbi.renderArea.extent.height = height;
780 rpbi.clearValueCount = 0;
781 rpbi.pClearValues = NULL;
782 rpbi.framebuffer = fb->fb;
783
784 assert(rp && fb);
785 assert(!cmdbuf->rp && !cmdbuf->fb);
786 zink_render_pass_reference(screen, &cmdbuf->rp, rp);
787 zink_framebuffer_reference(screen, &cmdbuf->fb, fb);
788
789 vkCmdBeginRenderPass(cmdbuf->cmdbuf, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
790 }
791
792 static uint32_t
793 hash_gfx_program(const void *key)
794 {
795 return _mesa_hash_data(key, sizeof(struct zink_shader *) * (PIPE_SHADER_TYPES - 1));
796 }
797
798 static bool
799 equals_gfx_program(const void *a, const void *b)
800 {
801 return memcmp(a, b, sizeof(struct zink_shader *) * (PIPE_SHADER_TYPES - 1)) == 0;
802 }
803
804 static struct zink_gfx_program *
805 get_gfx_program(struct zink_context *ctx)
806 {
807 if (ctx->dirty & ZINK_DIRTY_PROGRAM) {
808 struct hash_entry *entry = _mesa_hash_table_search(ctx->program_cache,
809 ctx->gfx_stages);
810 if (!entry) {
811 struct zink_gfx_program *prog;
812 prog = zink_create_gfx_program(zink_screen(ctx->base.screen)->dev,
813 ctx->gfx_stages);
814 entry = _mesa_hash_table_insert(ctx->program_cache, prog->stages, prog);
815 if (!entry)
816 return NULL;
817 }
818 ctx->curr_program = entry->data;
819 ctx->dirty &= ~ZINK_DIRTY_PROGRAM;
820 }
821
822 assert(ctx->curr_program);
823 return ctx->curr_program;
824 }
825
826 static void
827 zink_draw_vbo(struct pipe_context *pctx,
828 const struct pipe_draw_info *dinfo)
829 {
830 struct zink_context *ctx = zink_context(pctx);
831 struct zink_screen *screen = zink_screen(pctx->screen);
832 struct zink_rasterizer_state *rast_state = ctx->gfx_pipeline_state.rast_state;
833
834 if (dinfo->mode >= PIPE_PRIM_QUADS ||
835 dinfo->mode == PIPE_PRIM_LINE_LOOP) {
836 if (!u_trim_pipe_prim(dinfo->mode, (unsigned *)&dinfo->count))
837 return;
838
839 util_primconvert_save_rasterizer_state(ctx->primconvert, &rast_state->base);
840 util_primconvert_draw_vbo(ctx->primconvert, dinfo);
841 return;
842 }
843
844 struct zink_gfx_program *gfx_program = get_gfx_program(ctx);
845 if (!gfx_program)
846 return;
847
848 ctx->gfx_pipeline_state.primitive_topology = zink_primitive_topology(dinfo->mode);
849
850 VkPipeline pipeline = zink_get_gfx_pipeline(screen->dev, gfx_program,
851 &ctx->gfx_pipeline_state);
852
853 bool depth_bias = false;
854 switch (u_reduced_prim(dinfo->mode)) {
855 case PIPE_PRIM_POINTS:
856 depth_bias = rast_state->offset_point;
857 break;
858
859 case PIPE_PRIM_LINES:
860 depth_bias = rast_state->offset_line;
861 break;
862
863 case PIPE_PRIM_TRIANGLES:
864 depth_bias = rast_state->offset_tri;
865 break;
866
867 default:
868 unreachable("unexpected reduced prim");
869 }
870
871 unsigned index_offset = 0;
872 struct pipe_resource *index_buffer = NULL;
873 if (dinfo->index_size > 0) {
874 if (dinfo->has_user_indices) {
875 if (!util_upload_index_buffer(pctx, dinfo, &index_buffer, &index_offset)) {
876 debug_printf("util_upload_index_buffer() failed\n");
877 return;
878 }
879 } else
880 index_buffer = dinfo->index.resource;
881 }
882
883 struct zink_cmdbuf *cmdbuf = zink_start_cmdbuf(ctx);
884 if (!cmdbuf)
885 return;
886
887 begin_render_pass(screen, cmdbuf, ctx->gfx_pipeline_state.render_pass,
888 ctx->framebuffer,
889 ctx->fb_state.width, ctx->fb_state.height);
890
891 vkCmdSetViewport(cmdbuf->cmdbuf, 0, ctx->num_viewports, ctx->viewports);
892
893 if (ctx->num_scissors)
894 vkCmdSetScissor(cmdbuf->cmdbuf, 0, ctx->num_scissors, ctx->scissors);
895 else if (ctx->fb_state.width && ctx->fb_state.height) {
896 VkRect2D fb_scissor = {};
897 fb_scissor.extent.width = ctx->fb_state.width;
898 fb_scissor.extent.height = ctx->fb_state.height;
899 vkCmdSetScissor(cmdbuf->cmdbuf, 0, 1, &fb_scissor);
900 }
901
902 vkCmdSetStencilReference(cmdbuf->cmdbuf, VK_STENCIL_FACE_FRONT_BIT, ctx->stencil_ref[0]);
903 vkCmdSetStencilReference(cmdbuf->cmdbuf, VK_STENCIL_FACE_BACK_BIT, ctx->stencil_ref[1]);
904
905 if (depth_bias)
906 vkCmdSetDepthBias(cmdbuf->cmdbuf, rast_state->offset_units, rast_state->offset_clamp, rast_state->offset_scale);
907 else
908 vkCmdSetDepthBias(cmdbuf->cmdbuf, 0.0f, 0.0f, 0.0f);
909
910 if (ctx->gfx_pipeline_state.blend_state->need_blend_constants)
911 vkCmdSetBlendConstants(cmdbuf->cmdbuf, ctx->blend_constants);
912
913 VkDescriptorSet desc_set = allocate_descriptor_set(ctx, gfx_program->dsl);
914
915 VkWriteDescriptorSet wds[PIPE_SHADER_TYPES * PIPE_MAX_CONSTANT_BUFFERS + PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS];
916 VkDescriptorBufferInfo buffer_infos[PIPE_SHADER_TYPES * PIPE_MAX_CONSTANT_BUFFERS];
917 VkDescriptorImageInfo image_infos[PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS];
918 int num_wds = 0, num_buffer_info = 0, num_image_info = 0;
919
920 for (int i = 0; i < ARRAY_SIZE(ctx->gfx_stages); i++) {
921 struct zink_shader *shader = ctx->gfx_stages[i];
922 if (!shader)
923 continue;
924
925 for (int j = 0; j < shader->num_bindings; j++) {
926 int index = shader->bindings[j].index;
927 if (shader->bindings[j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
928 assert(ctx->ubos[i][index].buffer_size > 0);
929 assert(ctx->ubos[i][index].buffer);
930 struct zink_resource *res = zink_resource(ctx->ubos[i][index].buffer);
931 buffer_infos[num_buffer_info].buffer = res->buffer;
932 buffer_infos[num_buffer_info].offset = ctx->ubos[i][index].buffer_offset;
933 buffer_infos[num_buffer_info].range = VK_WHOLE_SIZE;
934 wds[num_wds].pBufferInfo = buffer_infos + num_buffer_info;
935 ++num_buffer_info;
936 zink_cmdbuf_reference_resoure(cmdbuf, res);
937 } else {
938 struct pipe_sampler_view *psampler_view = ctx->image_views[i][index];
939 assert(psampler_view);
940 struct zink_sampler_view *sampler_view = (struct zink_sampler_view *)psampler_view;
941 struct zink_resource *res = zink_resource(psampler_view->texture);
942 image_infos[num_image_info].imageLayout = res->layout;
943 image_infos[num_image_info].imageView = sampler_view->image_view;
944 image_infos[num_image_info].sampler = ctx->samplers[i][index];
945 wds[num_wds].pImageInfo = image_infos + num_image_info;
946 ++num_image_info;
947 zink_cmdbuf_reference_resoure(cmdbuf, res);
948 }
949
950 wds[num_wds].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
951 wds[num_wds].pNext = NULL;
952 wds[num_wds].dstSet = desc_set;
953 wds[num_wds].dstBinding = shader->bindings[j].binding;
954 wds[num_wds].dstArrayElement = 0;
955 wds[num_wds].descriptorCount = 1;
956 wds[num_wds].descriptorType = shader->bindings[j].type;
957 ++num_wds;
958 }
959 }
960
961 vkUpdateDescriptorSets(screen->dev, num_wds, wds, 0, NULL);
962
963 vkCmdBindPipeline(cmdbuf->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
964 vkCmdBindDescriptorSets(cmdbuf->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS,
965 gfx_program->layout, 0, 1, &desc_set, 0, NULL);
966 zink_bind_vertex_buffers(cmdbuf, ctx);
967
968 if (dinfo->index_size > 0) {
969 assert(dinfo->index_size != 1);
970 VkIndexType index_type = dinfo->index_size == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32;
971 struct zink_resource *res = zink_resource(index_buffer);
972 vkCmdBindIndexBuffer(cmdbuf->cmdbuf, res->buffer, index_offset, index_type);
973 zink_cmdbuf_reference_resoure(cmdbuf, res);
974 vkCmdDrawIndexed(cmdbuf->cmdbuf,
975 dinfo->count, dinfo->instance_count,
976 dinfo->start, dinfo->index_bias, dinfo->start_instance);
977 } else
978 vkCmdDraw(cmdbuf->cmdbuf, dinfo->count, dinfo->instance_count, dinfo->start, dinfo->start_instance);
979
980 vkCmdEndRenderPass(cmdbuf->cmdbuf);
981
982 zink_end_cmdbuf(ctx, cmdbuf);
983
984 if (dinfo->index_size > 0 && dinfo->has_user_indices)
985 pipe_resource_reference(&index_buffer, NULL);
986 }
987
988 static void
989 zink_flush(struct pipe_context *pctx,
990 struct pipe_fence_handle **pfence,
991 enum pipe_flush_flags flags)
992 {
993 struct zink_context *ctx = zink_context(pctx);
994
995 if (pfence)
996 zink_fence_reference(zink_screen(pctx->screen), (struct zink_fence **)pfence,
997 ctx->cmdbufs[0].fence);
998 }
999
1000 static void
1001 zink_blit(struct pipe_context *pctx,
1002 const struct pipe_blit_info *info)
1003 {
1004 struct zink_context *ctx = zink_context(pctx);
1005 bool is_resolve = false;
1006 if (info->mask != PIPE_MASK_RGBA ||
1007 info->scissor_enable ||
1008 info->alpha_blend) {
1009 if (!util_blitter_is_blit_supported(ctx->blitter, info)) {
1010 debug_printf("blit unsupported %s -> %s\n",
1011 util_format_short_name(info->src.resource->format),
1012 util_format_short_name(info->dst.resource->format));
1013 return;
1014 }
1015
1016 util_blitter_save_fragment_constant_buffer_slot(ctx->blitter, ctx->ubos[PIPE_SHADER_FRAGMENT]);
1017 util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->buffers);
1018 util_blitter_save_vertex_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_VERTEX]);
1019 util_blitter_save_fragment_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_FRAGMENT]);
1020 util_blitter_save_rasterizer(ctx->blitter, ctx->gfx_pipeline_state.rast_state);
1021
1022 util_blitter_blit(ctx->blitter, info);
1023 }
1024
1025 struct zink_resource *src = zink_resource(info->src.resource);
1026 struct zink_resource *dst = zink_resource(info->dst.resource);
1027
1028 if (src->base.nr_samples > 1 && dst->base.nr_samples <= 1)
1029 is_resolve = true;
1030
1031 struct zink_cmdbuf *cmdbuf = zink_start_cmdbuf(ctx);
1032 if (!cmdbuf)
1033 return;
1034
1035 if (is_resolve) {
1036 VkImageResolve region = {};
1037
1038 region.srcSubresource.aspectMask = src->aspect;
1039 region.srcSubresource.mipLevel = info->src.level;
1040 region.srcSubresource.baseArrayLayer = 0; // no clue
1041 region.srcSubresource.layerCount = 1; // no clue
1042 region.srcOffset.x = info->src.box.x;
1043 region.srcOffset.y = info->src.box.y;
1044 region.srcOffset.z = info->src.box.z;
1045
1046 region.dstSubresource.aspectMask = dst->aspect;
1047 region.dstSubresource.mipLevel = info->dst.level;
1048 region.dstSubresource.baseArrayLayer = 0; // no clue
1049 region.dstSubresource.layerCount = 1; // no clue
1050 region.dstOffset.x = info->dst.box.x;
1051 region.dstOffset.y = info->dst.box.y;
1052 region.dstOffset.z = info->dst.box.z;
1053
1054 region.extent.width = info->dst.box.width;
1055 region.extent.height = info->dst.box.height;
1056 region.extent.depth = info->dst.box.depth;
1057 vkCmdResolveImage(cmdbuf->cmdbuf, src->image, src->layout,
1058 dst->image, dst->layout,
1059 1, &region);
1060
1061 } else {
1062 if (dst->layout != VK_IMAGE_LAYOUT_GENERAL &&
1063 dst->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
1064 zink_resource_barrier(cmdbuf->cmdbuf, dst, dst->aspect,
1065 VK_IMAGE_LAYOUT_GENERAL);
1066
1067 VkImageBlit region = {};
1068 region.srcSubresource.aspectMask = src->aspect;
1069 region.srcSubresource.mipLevel = info->src.level;
1070 region.srcOffsets[0].x = info->src.box.x;
1071 region.srcOffsets[0].y = info->src.box.y;
1072 region.srcOffsets[1].x = info->src.box.x + info->src.box.width;
1073 region.srcOffsets[1].y = info->src.box.y + info->src.box.height;
1074
1075 if (src->base.array_size > 1) {
1076 region.srcOffsets[0].z = 0;
1077 region.srcOffsets[1].z = 1;
1078 region.srcSubresource.baseArrayLayer = info->src.box.z;
1079 region.srcSubresource.layerCount = info->src.box.depth;
1080 } else {
1081 region.srcOffsets[0].z = info->src.box.z;
1082 region.srcOffsets[1].z = info->src.box.z + info->src.box.depth;
1083 region.srcSubresource.baseArrayLayer = 0;
1084 region.srcSubresource.layerCount = 1;
1085 }
1086
1087 region.dstSubresource.aspectMask = dst->aspect;
1088 region.dstSubresource.mipLevel = info->dst.level;
1089 region.dstOffsets[0].x = info->dst.box.x;
1090 region.dstOffsets[0].y = info->dst.box.y;
1091 region.dstOffsets[1].x = info->dst.box.x + info->dst.box.width;
1092 region.dstOffsets[1].y = info->dst.box.y + info->dst.box.height;
1093
1094 if (dst->base.array_size > 1) {
1095 region.dstOffsets[0].z = 0;
1096 region.dstOffsets[1].z = 1;
1097 region.dstSubresource.baseArrayLayer = info->dst.box.z;
1098 region.dstSubresource.layerCount = info->dst.box.depth;
1099 } else {
1100 region.dstOffsets[0].z = info->dst.box.z;
1101 region.dstOffsets[1].z = info->dst.box.z + info->dst.box.depth;
1102 region.dstSubresource.baseArrayLayer = 0;
1103 region.dstSubresource.layerCount = 1;
1104 }
1105
1106 vkCmdBlitImage(cmdbuf->cmdbuf, src->image, src->layout,
1107 dst->image, dst->layout,
1108 1, &region,
1109 filter(info->filter));
1110 }
1111 zink_end_cmdbuf(ctx, cmdbuf);
1112 }
1113
1114 static void
1115 zink_flush_resource(struct pipe_context *pipe,
1116 struct pipe_resource *resource)
1117 {
1118 }
1119
1120 static void
1121 zink_resource_copy_region(struct pipe_context *pctx,
1122 struct pipe_resource *pdst,
1123 unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz,
1124 struct pipe_resource *psrc,
1125 unsigned src_level, const struct pipe_box *src_box)
1126 {
1127 struct zink_resource *dst = zink_resource(pdst);
1128 struct zink_resource *src = zink_resource(psrc);
1129 struct zink_context *ctx = zink_context(pctx);
1130 if (dst->base.target != PIPE_BUFFER && src->base.target != PIPE_BUFFER) {
1131 VkImageCopy region = {};
1132
1133 region.srcSubresource.aspectMask = src->aspect;
1134 region.srcSubresource.mipLevel = src_level;
1135 region.srcSubresource.layerCount = 1;
1136 if (src->base.array_size > 1) {
1137 region.srcSubresource.baseArrayLayer = src_box->z;
1138 region.srcSubresource.layerCount = src_box->depth;
1139 region.extent.depth = 1;
1140 } else {
1141 region.srcOffset.z = src_box->z;
1142 region.srcSubresource.layerCount = 1;
1143 region.extent.depth = src_box->depth;
1144 }
1145
1146 region.srcOffset.x = src_box->x;
1147 region.srcOffset.y = src_box->y;
1148
1149 region.dstSubresource.aspectMask = dst->aspect;
1150 region.dstSubresource.mipLevel = dst_level;
1151 if (dst->base.array_size > 1) {
1152 region.dstSubresource.baseArrayLayer = dstz;
1153 region.dstSubresource.layerCount = src_box->depth;
1154 } else {
1155 region.dstOffset.z = dstz;
1156 region.dstSubresource.layerCount = 1;
1157 }
1158
1159 region.dstOffset.x = dstx;
1160 region.dstOffset.y = dsty;
1161 region.extent.width = src_box->width;
1162 region.extent.height = src_box->height;
1163
1164 struct zink_cmdbuf *cmdbuf = zink_start_cmdbuf(ctx);
1165 if (!cmdbuf)
1166 return;
1167
1168 vkCmdCopyImage(cmdbuf->cmdbuf, src->image, src->layout,
1169 dst->image, dst->layout,
1170 1, &region);
1171 zink_end_cmdbuf(ctx, cmdbuf);
1172 } else
1173 debug_printf("zink: TODO resource copy\n");
1174 }
1175
1176 struct pipe_context *
1177 zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
1178 {
1179 struct zink_screen *screen = zink_screen(pscreen);
1180 struct zink_context *ctx = CALLOC_STRUCT(zink_context);
1181
1182 ctx->base.screen = pscreen;
1183 ctx->base.priv = priv;
1184
1185 ctx->base.destroy = zink_context_destroy;
1186
1187 zink_context_state_init(&ctx->base);
1188
1189 ctx->base.create_sampler_state = zink_create_sampler_state;
1190 ctx->base.bind_sampler_states = zink_bind_sampler_states;
1191 ctx->base.delete_sampler_state = zink_delete_sampler_state;
1192
1193 ctx->base.create_sampler_view = zink_create_sampler_view;
1194 ctx->base.set_sampler_views = zink_set_sampler_views;
1195 ctx->base.sampler_view_destroy = zink_destroy_sampler_view;
1196
1197 ctx->base.create_vs_state = zink_create_vs_state;
1198 ctx->base.bind_vs_state = zink_bind_vs_state;
1199 ctx->base.delete_vs_state = zink_delete_vs_state;
1200
1201 ctx->base.create_fs_state = zink_create_fs_state;
1202 ctx->base.bind_fs_state = zink_bind_fs_state;
1203 ctx->base.delete_fs_state = zink_delete_fs_state;
1204
1205 ctx->base.set_polygon_stipple = zink_set_polygon_stipple;
1206 ctx->base.set_vertex_buffers = zink_set_vertex_buffers;
1207 ctx->base.set_viewport_states = zink_set_viewport_states;
1208 ctx->base.set_scissor_states = zink_set_scissor_states;
1209 ctx->base.set_constant_buffer = zink_set_constant_buffer;
1210 ctx->base.set_framebuffer_state = zink_set_framebuffer_state;
1211 ctx->base.set_stencil_ref = zink_set_stencil_ref;
1212 ctx->base.set_clip_state = zink_set_clip_state;
1213 ctx->base.set_active_query_state = zink_set_active_query_state;
1214 ctx->base.set_blend_color = zink_set_blend_color;
1215
1216 ctx->base.clear = zink_clear;
1217 ctx->base.draw_vbo = zink_draw_vbo;
1218 ctx->base.flush = zink_flush;
1219
1220 ctx->base.resource_copy_region = zink_resource_copy_region;
1221 ctx->base.blit = zink_blit;
1222
1223 ctx->base.flush_resource = zink_flush_resource;
1224 zink_context_surface_init(&ctx->base);
1225 zink_context_resource_init(&ctx->base);
1226 zink_context_query_init(&ctx->base);
1227
1228 slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);
1229
1230 ctx->base.stream_uploader = u_upload_create_default(&ctx->base);
1231 ctx->base.const_uploader = ctx->base.stream_uploader;
1232
1233 int prim_hwsupport = 1 << PIPE_PRIM_POINTS |
1234 1 << PIPE_PRIM_LINES |
1235 1 << PIPE_PRIM_LINE_STRIP |
1236 1 << PIPE_PRIM_TRIANGLES |
1237 1 << PIPE_PRIM_TRIANGLE_STRIP |
1238 1 << PIPE_PRIM_TRIANGLE_FAN;
1239
1240 ctx->primconvert = util_primconvert_create(&ctx->base, prim_hwsupport);
1241 if (!ctx->primconvert)
1242 goto fail;
1243
1244 ctx->blitter = util_blitter_create(&ctx->base);
1245 if (!ctx->blitter)
1246 goto fail;
1247
1248 VkCommandPoolCreateInfo cpci = {};
1249 cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1250 cpci.queueFamilyIndex = screen->gfx_queue;
1251 cpci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1252 if (vkCreateCommandPool(screen->dev, &cpci, NULL, &ctx->cmdpool) != VK_SUCCESS)
1253 goto fail;
1254
1255 VkCommandBufferAllocateInfo cbai = {};
1256 cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1257 cbai.commandPool = ctx->cmdpool;
1258 cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1259 cbai.commandBufferCount = 1;
1260 for (int i = 0; i < ARRAY_SIZE(ctx->cmdbufs); ++i) {
1261 if (vkAllocateCommandBuffers(screen->dev, &cbai, &ctx->cmdbufs[i].cmdbuf) != VK_SUCCESS)
1262 goto fail;
1263
1264 ctx->cmdbufs[i].resources = _mesa_set_create(NULL, _mesa_hash_pointer,
1265 _mesa_key_pointer_equal);
1266 if (!ctx->cmdbufs[i].resources)
1267 goto fail;
1268 }
1269
1270 VkDescriptorPoolSize sizes[] = {
1271 {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000}
1272 };
1273 VkDescriptorPoolCreateInfo dpci = {};
1274 dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1275 dpci.pPoolSizes = sizes;
1276 dpci.poolSizeCount = ARRAY_SIZE(sizes);
1277 dpci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1278 dpci.maxSets = 1000;
1279
1280 if(vkCreateDescriptorPool(screen->dev, &dpci, 0, &ctx->descpool) != VK_SUCCESS)
1281 goto fail;
1282
1283 vkGetDeviceQueue(screen->dev, screen->gfx_queue, 0, &ctx->queue);
1284
1285 ctx->program_cache = _mesa_hash_table_create(NULL, hash_gfx_program, equals_gfx_program);
1286 if (!ctx->program_cache)
1287 goto fail;
1288
1289 ctx->dirty = ZINK_DIRTY_PROGRAM;
1290
1291 return &ctx->base;
1292
1293 fail:
1294 if (ctx) {
1295 vkDestroyCommandPool(screen->dev, ctx->cmdpool, NULL);
1296 FREE(ctx);
1297 }
1298 return NULL;
1299 }