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