zink: refcount zink_gfx_program objects
[mesa.git] / src / gallium / drivers / zink / zink_batch.c
1 #include "zink_batch.h"
2
3 #include "zink_context.h"
4 #include "zink_fence.h"
5 #include "zink_framebuffer.h"
6 #include "zink_query.h"
7 #include "zink_program.h"
8 #include "zink_render_pass.h"
9 #include "zink_resource.h"
10 #include "zink_screen.h"
11
12 #include "util/u_debug.h"
13 #include "util/set.h"
14
15 static void
16 reset_batch(struct zink_context *ctx, struct zink_batch *batch)
17 {
18 struct zink_screen *screen = zink_screen(ctx->base.screen);
19 batch->descs_left = ZINK_BATCH_DESC_SIZE;
20
21 // cmdbuf hasn't been submitted before
22 if (!batch->fence)
23 return;
24
25 zink_fence_finish(screen, batch->fence, PIPE_TIMEOUT_INFINITE);
26 zink_fence_reference(screen, &batch->fence, NULL);
27
28 zink_render_pass_reference(screen, &batch->rp, NULL);
29 zink_framebuffer_reference(screen, &batch->fb, NULL);
30 set_foreach(batch->programs, entry) {
31 struct zink_gfx_program *prog = (struct zink_gfx_program*)entry->key;
32 zink_gfx_program_reference(screen, &prog, NULL);
33 }
34 _mesa_set_clear(batch->programs, NULL);
35
36 /* unref all used resources */
37 set_foreach(batch->resources, entry) {
38 struct pipe_resource *pres = (struct pipe_resource *)entry->key;
39 pipe_resource_reference(&pres, NULL);
40 }
41 _mesa_set_clear(batch->resources, NULL);
42
43 /* unref all used sampler-views */
44 set_foreach(batch->sampler_views, entry) {
45 struct pipe_sampler_view *pres = (struct pipe_sampler_view *)entry->key;
46 pipe_sampler_view_reference(&pres, NULL);
47 }
48 _mesa_set_clear(batch->sampler_views, NULL);
49
50 util_dynarray_foreach(&batch->zombie_samplers, VkSampler, samp) {
51 vkDestroySampler(screen->dev, *samp, NULL);
52 }
53 util_dynarray_clear(&batch->zombie_samplers);
54
55 if (vkResetDescriptorPool(screen->dev, batch->descpool, 0) != VK_SUCCESS)
56 fprintf(stderr, "vkResetDescriptorPool failed\n");
57 }
58
59 void
60 zink_start_batch(struct zink_context *ctx, struct zink_batch *batch)
61 {
62 reset_batch(ctx, batch);
63
64 VkCommandBufferBeginInfo cbbi = {};
65 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
66 cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
67 if (vkBeginCommandBuffer(batch->cmdbuf, &cbbi) != VK_SUCCESS)
68 debug_printf("vkBeginCommandBuffer failed\n");
69
70 if (!ctx->queries_disabled)
71 zink_resume_queries(ctx, batch);
72 }
73
74 void
75 zink_end_batch(struct zink_context *ctx, struct zink_batch *batch)
76 {
77 if (!ctx->queries_disabled)
78 zink_suspend_queries(ctx, batch);
79
80 if (vkEndCommandBuffer(batch->cmdbuf) != VK_SUCCESS) {
81 debug_printf("vkEndCommandBuffer failed\n");
82 return;
83 }
84
85 assert(batch->fence == NULL);
86 batch->fence = zink_create_fence(ctx->base.screen, batch);
87 if (!batch->fence)
88 return;
89
90 VkSubmitInfo si = {};
91 si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
92 si.waitSemaphoreCount = 0;
93 si.pWaitSemaphores = NULL;
94 si.signalSemaphoreCount = 0;
95 si.pSignalSemaphores = NULL;
96 si.pWaitDstStageMask = NULL;
97 si.commandBufferCount = 1;
98 si.pCommandBuffers = &batch->cmdbuf;
99
100 if (vkQueueSubmit(ctx->queue, 1, &si, batch->fence->fence) != VK_SUCCESS) {
101 debug_printf("vkQueueSubmit failed\n");
102 abort();
103 }
104 }
105
106 void
107 zink_batch_reference_resoure(struct zink_batch *batch,
108 struct zink_resource *res)
109 {
110 struct set_entry *entry = _mesa_set_search(batch->resources, res);
111 if (!entry) {
112 entry = _mesa_set_add(batch->resources, res);
113 pipe_reference(NULL, &res->base.reference);
114 }
115 }
116
117 void
118 zink_batch_reference_sampler_view(struct zink_batch *batch,
119 struct zink_sampler_view *sv)
120 {
121 struct set_entry *entry = _mesa_set_search(batch->sampler_views, sv);
122 if (!entry) {
123 entry = _mesa_set_add(batch->sampler_views, sv);
124 pipe_reference(NULL, &sv->base.reference);
125 }
126 }
127
128 void
129 zink_batch_reference_program(struct zink_batch *batch,
130 struct zink_gfx_program *prog)
131 {
132 struct set_entry *entry = _mesa_set_search(batch->programs, prog);
133 if (!entry) {
134 entry = _mesa_set_add(batch->programs, prog);
135 pipe_reference(NULL, &prog->reference);
136 }
137 }