1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2015 Advanced Micro Devices, Inc.
4bf215546Sopenharmony_ci * Copyright 2008 VMware, Inc.
5bf215546Sopenharmony_ci * All Rights Reserved.
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
10bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub
11bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom
12bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
15bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
16bf215546Sopenharmony_ci * Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "dd_pipe.h"
29bf215546Sopenharmony_ci#include "dd_public.h"
30bf215546Sopenharmony_ci#include "util/u_memory.h"
31bf215546Sopenharmony_ci#include <ctype.h>
32bf215546Sopenharmony_ci#include <stdio.h>
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_cistatic const char *
36bf215546Sopenharmony_cidd_screen_get_name(struct pipe_screen *_screen)
37bf215546Sopenharmony_ci{
38bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci   return screen->get_name(screen);
41bf215546Sopenharmony_ci}
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_cistatic const char *
44bf215546Sopenharmony_cidd_screen_get_vendor(struct pipe_screen *_screen)
45bf215546Sopenharmony_ci{
46bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ci   return screen->get_vendor(screen);
49bf215546Sopenharmony_ci}
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_cistatic const char *
52bf215546Sopenharmony_cidd_screen_get_device_vendor(struct pipe_screen *_screen)
53bf215546Sopenharmony_ci{
54bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci   return screen->get_device_vendor(screen);
57bf215546Sopenharmony_ci}
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_cistatic const void *
60bf215546Sopenharmony_cidd_screen_get_compiler_options(struct pipe_screen *_screen,
61bf215546Sopenharmony_ci                               enum pipe_shader_ir ir,
62bf215546Sopenharmony_ci                               enum pipe_shader_type shader)
63bf215546Sopenharmony_ci{
64bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   return screen->get_compiler_options(screen, ir, shader);
67bf215546Sopenharmony_ci}
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_cistatic struct disk_cache *
70bf215546Sopenharmony_cidd_screen_get_disk_shader_cache(struct pipe_screen *_screen)
71bf215546Sopenharmony_ci{
72bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ci   return screen->get_disk_shader_cache(screen);
75bf215546Sopenharmony_ci}
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_cistatic int
78bf215546Sopenharmony_cidd_screen_get_param(struct pipe_screen *_screen,
79bf215546Sopenharmony_ci                    enum pipe_cap param)
80bf215546Sopenharmony_ci{
81bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci   return screen->get_param(screen, param);
84bf215546Sopenharmony_ci}
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_cistatic float
87bf215546Sopenharmony_cidd_screen_get_paramf(struct pipe_screen *_screen,
88bf215546Sopenharmony_ci                     enum pipe_capf param)
89bf215546Sopenharmony_ci{
90bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci   return screen->get_paramf(screen, param);
93bf215546Sopenharmony_ci}
94bf215546Sopenharmony_ci
95bf215546Sopenharmony_cistatic int
96bf215546Sopenharmony_cidd_screen_get_compute_param(struct pipe_screen *_screen,
97bf215546Sopenharmony_ci                            enum pipe_shader_ir ir_type,
98bf215546Sopenharmony_ci                            enum pipe_compute_cap param,
99bf215546Sopenharmony_ci                            void *ret)
100bf215546Sopenharmony_ci{
101bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
102bf215546Sopenharmony_ci
103bf215546Sopenharmony_ci   return screen->get_compute_param(screen, ir_type, param, ret);
104bf215546Sopenharmony_ci}
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_cistatic int
107bf215546Sopenharmony_cidd_screen_get_shader_param(struct pipe_screen *_screen,
108bf215546Sopenharmony_ci                           enum pipe_shader_type shader,
109bf215546Sopenharmony_ci                           enum pipe_shader_cap param)
110bf215546Sopenharmony_ci{
111bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci   return screen->get_shader_param(screen, shader, param);
114bf215546Sopenharmony_ci}
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_cistatic uint64_t
117bf215546Sopenharmony_cidd_screen_get_timestamp(struct pipe_screen *_screen)
118bf215546Sopenharmony_ci{
119bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ci   return screen->get_timestamp(screen);
122bf215546Sopenharmony_ci}
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_cistatic void dd_screen_query_memory_info(struct pipe_screen *_screen,
125bf215546Sopenharmony_ci                                        struct pipe_memory_info *info)
126bf215546Sopenharmony_ci{
127bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ci   screen->query_memory_info(screen, info);
130bf215546Sopenharmony_ci}
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_cistatic struct pipe_context *
133bf215546Sopenharmony_cidd_screen_context_create(struct pipe_screen *_screen, void *priv,
134bf215546Sopenharmony_ci                         unsigned flags)
135bf215546Sopenharmony_ci{
136bf215546Sopenharmony_ci   struct dd_screen *dscreen = dd_screen(_screen);
137bf215546Sopenharmony_ci   struct pipe_screen *screen = dscreen->screen;
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci   flags |= PIPE_CONTEXT_DEBUG;
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci   return dd_context_create(dscreen,
142bf215546Sopenharmony_ci                            screen->context_create(screen, priv, flags));
143bf215546Sopenharmony_ci}
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_cistatic bool
146bf215546Sopenharmony_cidd_screen_is_format_supported(struct pipe_screen *_screen,
147bf215546Sopenharmony_ci                              enum pipe_format format,
148bf215546Sopenharmony_ci                              enum pipe_texture_target target,
149bf215546Sopenharmony_ci                              unsigned sample_count,
150bf215546Sopenharmony_ci                              unsigned storage_sample_count,
151bf215546Sopenharmony_ci                              unsigned tex_usage)
152bf215546Sopenharmony_ci{
153bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci   return screen->is_format_supported(screen, format, target, sample_count,
156bf215546Sopenharmony_ci                                      storage_sample_count, tex_usage);
157bf215546Sopenharmony_ci}
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_cistatic bool
160bf215546Sopenharmony_cidd_screen_can_create_resource(struct pipe_screen *_screen,
161bf215546Sopenharmony_ci                              const struct pipe_resource *templat)
162bf215546Sopenharmony_ci{
163bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci   return screen->can_create_resource(screen, templat);
166bf215546Sopenharmony_ci}
167bf215546Sopenharmony_ci
168bf215546Sopenharmony_cistatic void
169bf215546Sopenharmony_cidd_screen_flush_frontbuffer(struct pipe_screen *_screen,
170bf215546Sopenharmony_ci                            struct pipe_context *_pipe,
171bf215546Sopenharmony_ci                            struct pipe_resource *resource,
172bf215546Sopenharmony_ci                            unsigned level, unsigned layer,
173bf215546Sopenharmony_ci                            void *context_private,
174bf215546Sopenharmony_ci                            struct pipe_box *sub_box)
175bf215546Sopenharmony_ci{
176bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
177bf215546Sopenharmony_ci   struct pipe_context *pipe = _pipe ? dd_context(_pipe)->pipe : NULL;
178bf215546Sopenharmony_ci
179bf215546Sopenharmony_ci   screen->flush_frontbuffer(screen, pipe, resource, level, layer, context_private,
180bf215546Sopenharmony_ci                             sub_box);
181bf215546Sopenharmony_ci}
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_cistatic int
184bf215546Sopenharmony_cidd_screen_get_driver_query_info(struct pipe_screen *_screen,
185bf215546Sopenharmony_ci                                unsigned index,
186bf215546Sopenharmony_ci                                struct pipe_driver_query_info *info)
187bf215546Sopenharmony_ci{
188bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_ci   return screen->get_driver_query_info(screen, index, info);
191bf215546Sopenharmony_ci}
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_cistatic int
194bf215546Sopenharmony_cidd_screen_get_driver_query_group_info(struct pipe_screen *_screen,
195bf215546Sopenharmony_ci                                      unsigned index,
196bf215546Sopenharmony_ci                                      struct pipe_driver_query_group_info *info)
197bf215546Sopenharmony_ci{
198bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci   return screen->get_driver_query_group_info(screen, index, info);
201bf215546Sopenharmony_ci}
202bf215546Sopenharmony_ci
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_cistatic void
205bf215546Sopenharmony_cidd_screen_get_driver_uuid(struct pipe_screen *_screen, char *uuid)
206bf215546Sopenharmony_ci{
207bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
208bf215546Sopenharmony_ci
209bf215546Sopenharmony_ci   screen->get_driver_uuid(screen, uuid);
210bf215546Sopenharmony_ci}
211bf215546Sopenharmony_ci
212bf215546Sopenharmony_cistatic void
213bf215546Sopenharmony_cidd_screen_get_device_uuid(struct pipe_screen *_screen, char *uuid)
214bf215546Sopenharmony_ci{
215bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_ci   screen->get_device_uuid(screen, uuid);
218bf215546Sopenharmony_ci}
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_ci/********************************************************************
221bf215546Sopenharmony_ci * resource
222bf215546Sopenharmony_ci */
223bf215546Sopenharmony_ci
224bf215546Sopenharmony_cistatic struct pipe_resource *
225bf215546Sopenharmony_cidd_screen_resource_create(struct pipe_screen *_screen,
226bf215546Sopenharmony_ci                          const struct pipe_resource *templat)
227bf215546Sopenharmony_ci{
228bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
229bf215546Sopenharmony_ci   struct pipe_resource *res = screen->resource_create(screen, templat);
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci   if (!res)
232bf215546Sopenharmony_ci      return NULL;
233bf215546Sopenharmony_ci   res->screen = _screen;
234bf215546Sopenharmony_ci   return res;
235bf215546Sopenharmony_ci}
236bf215546Sopenharmony_ci
237bf215546Sopenharmony_cistatic struct pipe_resource *
238bf215546Sopenharmony_cidd_screen_resource_from_handle(struct pipe_screen *_screen,
239bf215546Sopenharmony_ci                               const struct pipe_resource *templ,
240bf215546Sopenharmony_ci                               struct winsys_handle *handle,
241bf215546Sopenharmony_ci                               unsigned usage)
242bf215546Sopenharmony_ci{
243bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
244bf215546Sopenharmony_ci   struct pipe_resource *res =
245bf215546Sopenharmony_ci      screen->resource_from_handle(screen, templ, handle, usage);
246bf215546Sopenharmony_ci
247bf215546Sopenharmony_ci   if (!res)
248bf215546Sopenharmony_ci      return NULL;
249bf215546Sopenharmony_ci   res->screen = _screen;
250bf215546Sopenharmony_ci   return res;
251bf215546Sopenharmony_ci}
252bf215546Sopenharmony_ci
253bf215546Sopenharmony_cistatic struct pipe_resource *
254bf215546Sopenharmony_cidd_screen_resource_from_user_memory(struct pipe_screen *_screen,
255bf215546Sopenharmony_ci                                    const struct pipe_resource *templ,
256bf215546Sopenharmony_ci                                    void *user_memory)
257bf215546Sopenharmony_ci{
258bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
259bf215546Sopenharmony_ci   struct pipe_resource *res =
260bf215546Sopenharmony_ci      screen->resource_from_user_memory(screen, templ, user_memory);
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_ci   if (!res)
263bf215546Sopenharmony_ci      return NULL;
264bf215546Sopenharmony_ci   res->screen = _screen;
265bf215546Sopenharmony_ci   return res;
266bf215546Sopenharmony_ci}
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_cistatic struct pipe_resource *
269bf215546Sopenharmony_cidd_screen_resource_from_memobj(struct pipe_screen *_screen,
270bf215546Sopenharmony_ci                               const struct pipe_resource *templ,
271bf215546Sopenharmony_ci                               struct pipe_memory_object *memobj,
272bf215546Sopenharmony_ci                               uint64_t offset)
273bf215546Sopenharmony_ci{
274bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
275bf215546Sopenharmony_ci   struct pipe_resource *res =
276bf215546Sopenharmony_ci      screen->resource_from_memobj(screen, templ, memobj, offset);
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_ci   if (!res)
279bf215546Sopenharmony_ci      return NULL;
280bf215546Sopenharmony_ci   res->screen = _screen;
281bf215546Sopenharmony_ci   return res;
282bf215546Sopenharmony_ci}
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_cistatic void
285bf215546Sopenharmony_cidd_screen_resource_changed(struct pipe_screen *_screen,
286bf215546Sopenharmony_ci                           struct pipe_resource *res)
287bf215546Sopenharmony_ci{
288bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci   if (screen->resource_changed)
291bf215546Sopenharmony_ci      screen->resource_changed(screen, res);
292bf215546Sopenharmony_ci}
293bf215546Sopenharmony_ci
294bf215546Sopenharmony_cistatic void
295bf215546Sopenharmony_cidd_screen_resource_destroy(struct pipe_screen *_screen,
296bf215546Sopenharmony_ci                           struct pipe_resource *res)
297bf215546Sopenharmony_ci{
298bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ci   screen->resource_destroy(screen, res);
301bf215546Sopenharmony_ci}
302bf215546Sopenharmony_ci
303bf215546Sopenharmony_cistatic bool
304bf215546Sopenharmony_cidd_screen_resource_get_handle(struct pipe_screen *_screen,
305bf215546Sopenharmony_ci                              struct pipe_context *_pipe,
306bf215546Sopenharmony_ci                              struct pipe_resource *resource,
307bf215546Sopenharmony_ci                              struct winsys_handle *handle,
308bf215546Sopenharmony_ci                              unsigned usage)
309bf215546Sopenharmony_ci{
310bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
311bf215546Sopenharmony_ci   struct pipe_context *pipe = _pipe ? dd_context(_pipe)->pipe : NULL;
312bf215546Sopenharmony_ci
313bf215546Sopenharmony_ci   return screen->resource_get_handle(screen, pipe, resource, handle, usage);
314bf215546Sopenharmony_ci}
315bf215546Sopenharmony_ci
316bf215546Sopenharmony_cistatic bool
317bf215546Sopenharmony_cidd_screen_resource_get_param(struct pipe_screen *_screen,
318bf215546Sopenharmony_ci                             struct pipe_context *_pipe,
319bf215546Sopenharmony_ci                             struct pipe_resource *resource,
320bf215546Sopenharmony_ci                             unsigned plane,
321bf215546Sopenharmony_ci                             unsigned layer,
322bf215546Sopenharmony_ci                             unsigned level,
323bf215546Sopenharmony_ci                             enum pipe_resource_param param,
324bf215546Sopenharmony_ci                             unsigned handle_usage,
325bf215546Sopenharmony_ci                             uint64_t *value)
326bf215546Sopenharmony_ci{
327bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
328bf215546Sopenharmony_ci   struct pipe_context *pipe = _pipe ? dd_context(_pipe)->pipe : NULL;
329bf215546Sopenharmony_ci
330bf215546Sopenharmony_ci   return screen->resource_get_param(screen, pipe, resource, plane, layer,
331bf215546Sopenharmony_ci                                     level, param, handle_usage, value);
332bf215546Sopenharmony_ci}
333bf215546Sopenharmony_ci
334bf215546Sopenharmony_cistatic void
335bf215546Sopenharmony_cidd_screen_resource_get_info(struct pipe_screen *_screen,
336bf215546Sopenharmony_ci                            struct pipe_resource *resource,
337bf215546Sopenharmony_ci                            unsigned *stride,
338bf215546Sopenharmony_ci                            unsigned *offset)
339bf215546Sopenharmony_ci{
340bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
341bf215546Sopenharmony_ci
342bf215546Sopenharmony_ci   screen->resource_get_info(screen, resource, stride, offset);
343bf215546Sopenharmony_ci}
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_cistatic bool
346bf215546Sopenharmony_cidd_screen_check_resource_capability(struct pipe_screen *_screen,
347bf215546Sopenharmony_ci                                    struct pipe_resource *resource,
348bf215546Sopenharmony_ci                                    unsigned bind)
349bf215546Sopenharmony_ci{
350bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_ci   return screen->check_resource_capability(screen, resource, bind);
353bf215546Sopenharmony_ci}
354bf215546Sopenharmony_ci
355bf215546Sopenharmony_cistatic int
356bf215546Sopenharmony_cidd_screen_get_sparse_texture_virtual_page_size(struct pipe_screen *_screen,
357bf215546Sopenharmony_ci                                               enum pipe_texture_target target,
358bf215546Sopenharmony_ci                                               bool multi_sample,
359bf215546Sopenharmony_ci                                               enum pipe_format format,
360bf215546Sopenharmony_ci                                               unsigned offset, unsigned size,
361bf215546Sopenharmony_ci                                               int *x, int *y, int *z)
362bf215546Sopenharmony_ci{
363bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
364bf215546Sopenharmony_ci
365bf215546Sopenharmony_ci   return screen->get_sparse_texture_virtual_page_size(
366bf215546Sopenharmony_ci      _screen, target, multi_sample, format, offset, size, x, y, z);
367bf215546Sopenharmony_ci}
368bf215546Sopenharmony_ci
369bf215546Sopenharmony_ci/********************************************************************
370bf215546Sopenharmony_ci * fence
371bf215546Sopenharmony_ci */
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_cistatic void
374bf215546Sopenharmony_cidd_screen_fence_reference(struct pipe_screen *_screen,
375bf215546Sopenharmony_ci                          struct pipe_fence_handle **pdst,
376bf215546Sopenharmony_ci                          struct pipe_fence_handle *src)
377bf215546Sopenharmony_ci{
378bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
379bf215546Sopenharmony_ci
380bf215546Sopenharmony_ci   screen->fence_reference(screen, pdst, src);
381bf215546Sopenharmony_ci}
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_cistatic bool
384bf215546Sopenharmony_cidd_screen_fence_finish(struct pipe_screen *_screen,
385bf215546Sopenharmony_ci                       struct pipe_context *_ctx,
386bf215546Sopenharmony_ci                       struct pipe_fence_handle *fence,
387bf215546Sopenharmony_ci                       uint64_t timeout)
388bf215546Sopenharmony_ci{
389bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
390bf215546Sopenharmony_ci   struct pipe_context *ctx = _ctx ? dd_context(_ctx)->pipe : NULL;
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_ci   return screen->fence_finish(screen, ctx, fence, timeout);
393bf215546Sopenharmony_ci}
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_cistatic int
396bf215546Sopenharmony_cidd_screen_fence_get_fd(struct pipe_screen *_screen,
397bf215546Sopenharmony_ci                       struct pipe_fence_handle *fence)
398bf215546Sopenharmony_ci{
399bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
400bf215546Sopenharmony_ci
401bf215546Sopenharmony_ci   return screen->fence_get_fd(screen, fence);
402bf215546Sopenharmony_ci}
403bf215546Sopenharmony_ci
404bf215546Sopenharmony_ci/********************************************************************
405bf215546Sopenharmony_ci * vertex state
406bf215546Sopenharmony_ci */
407bf215546Sopenharmony_ci
408bf215546Sopenharmony_cistatic struct pipe_vertex_state *
409bf215546Sopenharmony_cidd_screen_create_vertex_state(struct pipe_screen *_screen,
410bf215546Sopenharmony_ci                              struct pipe_vertex_buffer *buffer,
411bf215546Sopenharmony_ci                              const struct pipe_vertex_element *elements,
412bf215546Sopenharmony_ci                              unsigned num_elements,
413bf215546Sopenharmony_ci                              struct pipe_resource *indexbuf,
414bf215546Sopenharmony_ci                              uint32_t full_velem_mask)
415bf215546Sopenharmony_ci{
416bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
417bf215546Sopenharmony_ci   struct pipe_vertex_state *state =
418bf215546Sopenharmony_ci      screen->create_vertex_state(screen, buffer, elements, num_elements,
419bf215546Sopenharmony_ci                                  indexbuf, full_velem_mask);
420bf215546Sopenharmony_ci
421bf215546Sopenharmony_ci   if (!state)
422bf215546Sopenharmony_ci      return NULL;
423bf215546Sopenharmony_ci   state->screen = _screen;
424bf215546Sopenharmony_ci   return state;
425bf215546Sopenharmony_ci}
426bf215546Sopenharmony_ci
427bf215546Sopenharmony_cistatic void
428bf215546Sopenharmony_cidd_screen_vertex_state_destroy(struct pipe_screen *_screen,
429bf215546Sopenharmony_ci                               struct pipe_vertex_state *state)
430bf215546Sopenharmony_ci{
431bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
432bf215546Sopenharmony_ci
433bf215546Sopenharmony_ci   screen->vertex_state_destroy(screen, state);
434bf215546Sopenharmony_ci}
435bf215546Sopenharmony_ci
436bf215546Sopenharmony_ci/********************************************************************
437bf215546Sopenharmony_ci * memobj
438bf215546Sopenharmony_ci */
439bf215546Sopenharmony_ci
440bf215546Sopenharmony_cistatic struct pipe_memory_object *
441bf215546Sopenharmony_cidd_screen_memobj_create_from_handle(struct pipe_screen *_screen,
442bf215546Sopenharmony_ci                                    struct winsys_handle *handle,
443bf215546Sopenharmony_ci                                    bool dedicated)
444bf215546Sopenharmony_ci{
445bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci   return screen->memobj_create_from_handle(screen, handle, dedicated);
448bf215546Sopenharmony_ci}
449bf215546Sopenharmony_ci
450bf215546Sopenharmony_cistatic void
451bf215546Sopenharmony_cidd_screen_memobj_destroy(struct pipe_screen *_screen,
452bf215546Sopenharmony_ci                         struct pipe_memory_object *memobj)
453bf215546Sopenharmony_ci{
454bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
455bf215546Sopenharmony_ci
456bf215546Sopenharmony_ci   screen->memobj_destroy(screen, memobj);
457bf215546Sopenharmony_ci}
458bf215546Sopenharmony_ci/********************************************************************
459bf215546Sopenharmony_ci * screen
460bf215546Sopenharmony_ci */
461bf215546Sopenharmony_ci
462bf215546Sopenharmony_cistatic char *
463bf215546Sopenharmony_cidd_screen_finalize_nir(struct pipe_screen *_screen, void *nir)
464bf215546Sopenharmony_ci{
465bf215546Sopenharmony_ci   struct pipe_screen *screen = dd_screen(_screen)->screen;
466bf215546Sopenharmony_ci
467bf215546Sopenharmony_ci   return screen->finalize_nir(screen, nir);
468bf215546Sopenharmony_ci}
469bf215546Sopenharmony_ci
470bf215546Sopenharmony_cistatic void
471bf215546Sopenharmony_cidd_screen_destroy(struct pipe_screen *_screen)
472bf215546Sopenharmony_ci{
473bf215546Sopenharmony_ci   struct dd_screen *dscreen = dd_screen(_screen);
474bf215546Sopenharmony_ci   struct pipe_screen *screen = dscreen->screen;
475bf215546Sopenharmony_ci
476bf215546Sopenharmony_ci   screen->destroy(screen);
477bf215546Sopenharmony_ci   FREE(dscreen);
478bf215546Sopenharmony_ci}
479bf215546Sopenharmony_ci
480bf215546Sopenharmony_cistatic void
481bf215546Sopenharmony_ciskip_space(const char **p)
482bf215546Sopenharmony_ci{
483bf215546Sopenharmony_ci   while (isspace(**p))
484bf215546Sopenharmony_ci      (*p)++;
485bf215546Sopenharmony_ci}
486bf215546Sopenharmony_ci
487bf215546Sopenharmony_cistatic bool
488bf215546Sopenharmony_cimatch_word(const char **cur, const char *word)
489bf215546Sopenharmony_ci{
490bf215546Sopenharmony_ci   size_t len = strlen(word);
491bf215546Sopenharmony_ci   if (strncmp(*cur, word, len) != 0)
492bf215546Sopenharmony_ci      return false;
493bf215546Sopenharmony_ci
494bf215546Sopenharmony_ci   const char *p = *cur + len;
495bf215546Sopenharmony_ci   if (*p) {
496bf215546Sopenharmony_ci      if (!isspace(*p))
497bf215546Sopenharmony_ci         return false;
498bf215546Sopenharmony_ci
499bf215546Sopenharmony_ci      *cur = p + 1;
500bf215546Sopenharmony_ci   } else {
501bf215546Sopenharmony_ci      *cur = p;
502bf215546Sopenharmony_ci   }
503bf215546Sopenharmony_ci
504bf215546Sopenharmony_ci   return true;
505bf215546Sopenharmony_ci}
506bf215546Sopenharmony_ci
507bf215546Sopenharmony_cistatic bool
508bf215546Sopenharmony_cimatch_uint(const char **cur, unsigned *value)
509bf215546Sopenharmony_ci{
510bf215546Sopenharmony_ci   char *end;
511bf215546Sopenharmony_ci   unsigned v = strtoul(*cur, &end, 0);
512bf215546Sopenharmony_ci   if (end == *cur || (*end && !isspace(*end)))
513bf215546Sopenharmony_ci      return false;
514bf215546Sopenharmony_ci   *cur = end;
515bf215546Sopenharmony_ci   *value = v;
516bf215546Sopenharmony_ci   return true;
517bf215546Sopenharmony_ci}
518bf215546Sopenharmony_ci
519bf215546Sopenharmony_cistruct pipe_screen *
520bf215546Sopenharmony_ciddebug_screen_create(struct pipe_screen *screen)
521bf215546Sopenharmony_ci{
522bf215546Sopenharmony_ci   struct dd_screen *dscreen;
523bf215546Sopenharmony_ci   const char *option;
524bf215546Sopenharmony_ci   bool flush = false;
525bf215546Sopenharmony_ci   bool verbose = false;
526bf215546Sopenharmony_ci   bool transfers = false;
527bf215546Sopenharmony_ci   unsigned timeout = 1000;
528bf215546Sopenharmony_ci   unsigned apitrace_dump_call = 0;
529bf215546Sopenharmony_ci   enum dd_dump_mode mode = DD_DUMP_ONLY_HANGS;
530bf215546Sopenharmony_ci
531bf215546Sopenharmony_ci   option = debug_get_option("GALLIUM_DDEBUG", NULL);
532bf215546Sopenharmony_ci   if (!option)
533bf215546Sopenharmony_ci      return screen;
534bf215546Sopenharmony_ci
535bf215546Sopenharmony_ci   if (!strcmp(option, "help")) {
536bf215546Sopenharmony_ci      puts("Gallium driver debugger");
537bf215546Sopenharmony_ci      puts("");
538bf215546Sopenharmony_ci      puts("Usage:");
539bf215546Sopenharmony_ci      puts("");
540bf215546Sopenharmony_ci      puts("  GALLIUM_DDEBUG=\"[<timeout in ms>] [(always|apitrace <call#)] [flush] [transfers] [verbose]\"");
541bf215546Sopenharmony_ci      puts("  GALLIUM_DDEBUG_SKIP=[count]");
542bf215546Sopenharmony_ci      puts("");
543bf215546Sopenharmony_ci      puts("Dump context and driver information of draw calls into");
544bf215546Sopenharmony_ci      puts("$HOME/"DD_DIR"/. By default, watch for GPU hangs and only dump information");
545bf215546Sopenharmony_ci      puts("about draw calls related to the hang.");
546bf215546Sopenharmony_ci      puts("");
547bf215546Sopenharmony_ci      puts("<timeout in ms>");
548bf215546Sopenharmony_ci      puts("  Change the default timeout for GPU hang detection (default=1000ms).");
549bf215546Sopenharmony_ci      puts("  Setting this to 0 will disable GPU hang detection entirely.");
550bf215546Sopenharmony_ci      puts("");
551bf215546Sopenharmony_ci      puts("always");
552bf215546Sopenharmony_ci      puts("  Dump information about all draw calls.");
553bf215546Sopenharmony_ci      puts("");
554bf215546Sopenharmony_ci      puts("transfers");
555bf215546Sopenharmony_ci      puts("  Also dump and do hang detection on transfers.");
556bf215546Sopenharmony_ci      puts("");
557bf215546Sopenharmony_ci      puts("apitrace <call#>");
558bf215546Sopenharmony_ci      puts("  Dump information about the draw call corresponding to the given");
559bf215546Sopenharmony_ci      puts("  apitrace call number and exit.");
560bf215546Sopenharmony_ci      puts("");
561bf215546Sopenharmony_ci      puts("flush");
562bf215546Sopenharmony_ci      puts("  Flush after every draw call.");
563bf215546Sopenharmony_ci      puts("");
564bf215546Sopenharmony_ci      puts("verbose");
565bf215546Sopenharmony_ci      puts("  Write additional information to stderr.");
566bf215546Sopenharmony_ci      puts("");
567bf215546Sopenharmony_ci      puts("GALLIUM_DDEBUG_SKIP=count");
568bf215546Sopenharmony_ci      puts("  Skip dumping on the first count draw calls (only relevant with 'always').");
569bf215546Sopenharmony_ci      puts("");
570bf215546Sopenharmony_ci      exit(0);
571bf215546Sopenharmony_ci   }
572bf215546Sopenharmony_ci
573bf215546Sopenharmony_ci   for (;;) {
574bf215546Sopenharmony_ci      skip_space(&option);
575bf215546Sopenharmony_ci      if (!*option)
576bf215546Sopenharmony_ci         break;
577bf215546Sopenharmony_ci
578bf215546Sopenharmony_ci      if (match_word(&option, "always")) {
579bf215546Sopenharmony_ci         if (mode == DD_DUMP_APITRACE_CALL) {
580bf215546Sopenharmony_ci            printf("ddebug: both 'always' and 'apitrace' specified\n");
581bf215546Sopenharmony_ci            exit(1);
582bf215546Sopenharmony_ci         }
583bf215546Sopenharmony_ci
584bf215546Sopenharmony_ci         mode = DD_DUMP_ALL_CALLS;
585bf215546Sopenharmony_ci      } else if (match_word(&option, "flush")) {
586bf215546Sopenharmony_ci         flush = true;
587bf215546Sopenharmony_ci      } else if (match_word(&option, "transfers")) {
588bf215546Sopenharmony_ci         transfers = true;
589bf215546Sopenharmony_ci      } else if (match_word(&option, "verbose")) {
590bf215546Sopenharmony_ci         verbose = true;
591bf215546Sopenharmony_ci      } else if (match_word(&option, "apitrace")) {
592bf215546Sopenharmony_ci         if (mode != DD_DUMP_ONLY_HANGS) {
593bf215546Sopenharmony_ci            printf("ddebug: 'apitrace' can only appear once and not mixed with 'always'\n");
594bf215546Sopenharmony_ci            exit(1);
595bf215546Sopenharmony_ci         }
596bf215546Sopenharmony_ci
597bf215546Sopenharmony_ci         if (!match_uint(&option, &apitrace_dump_call)) {
598bf215546Sopenharmony_ci            printf("ddebug: expected call number after 'apitrace'\n");
599bf215546Sopenharmony_ci            exit(1);
600bf215546Sopenharmony_ci         }
601bf215546Sopenharmony_ci
602bf215546Sopenharmony_ci         mode = DD_DUMP_APITRACE_CALL;
603bf215546Sopenharmony_ci      } else if (match_uint(&option, &timeout)) {
604bf215546Sopenharmony_ci         /* no-op */
605bf215546Sopenharmony_ci      } else {
606bf215546Sopenharmony_ci         printf("ddebug: bad options: %s\n", option);
607bf215546Sopenharmony_ci         exit(1);
608bf215546Sopenharmony_ci      }
609bf215546Sopenharmony_ci   }
610bf215546Sopenharmony_ci
611bf215546Sopenharmony_ci   dscreen = CALLOC_STRUCT(dd_screen);
612bf215546Sopenharmony_ci   if (!dscreen)
613bf215546Sopenharmony_ci      return NULL;
614bf215546Sopenharmony_ci
615bf215546Sopenharmony_ci#define SCR_INIT(_member) \
616bf215546Sopenharmony_ci   dscreen->base._member = screen->_member ? dd_screen_##_member : NULL
617bf215546Sopenharmony_ci
618bf215546Sopenharmony_ci   dscreen->base.destroy = dd_screen_destroy;
619bf215546Sopenharmony_ci   dscreen->base.get_name = dd_screen_get_name;
620bf215546Sopenharmony_ci   dscreen->base.get_vendor = dd_screen_get_vendor;
621bf215546Sopenharmony_ci   dscreen->base.get_device_vendor = dd_screen_get_device_vendor;
622bf215546Sopenharmony_ci   SCR_INIT(get_disk_shader_cache);
623bf215546Sopenharmony_ci   dscreen->base.get_param = dd_screen_get_param;
624bf215546Sopenharmony_ci   dscreen->base.get_paramf = dd_screen_get_paramf;
625bf215546Sopenharmony_ci   dscreen->base.get_compute_param = dd_screen_get_compute_param;
626bf215546Sopenharmony_ci   dscreen->base.get_shader_param = dd_screen_get_shader_param;
627bf215546Sopenharmony_ci   dscreen->base.query_memory_info = dd_screen_query_memory_info;
628bf215546Sopenharmony_ci   /* get_video_param */
629bf215546Sopenharmony_ci   /* get_compute_param */
630bf215546Sopenharmony_ci   SCR_INIT(get_timestamp);
631bf215546Sopenharmony_ci   dscreen->base.context_create = dd_screen_context_create;
632bf215546Sopenharmony_ci   dscreen->base.is_format_supported = dd_screen_is_format_supported;
633bf215546Sopenharmony_ci   /* is_video_format_supported */
634bf215546Sopenharmony_ci   SCR_INIT(can_create_resource);
635bf215546Sopenharmony_ci   dscreen->base.resource_create = dd_screen_resource_create;
636bf215546Sopenharmony_ci   dscreen->base.resource_from_handle = dd_screen_resource_from_handle;
637bf215546Sopenharmony_ci   SCR_INIT(resource_from_memobj);
638bf215546Sopenharmony_ci   SCR_INIT(resource_from_user_memory);
639bf215546Sopenharmony_ci   SCR_INIT(check_resource_capability);
640bf215546Sopenharmony_ci   dscreen->base.resource_get_handle = dd_screen_resource_get_handle;
641bf215546Sopenharmony_ci   SCR_INIT(resource_get_param);
642bf215546Sopenharmony_ci   SCR_INIT(resource_get_info);
643bf215546Sopenharmony_ci   SCR_INIT(resource_changed);
644bf215546Sopenharmony_ci   dscreen->base.resource_destroy = dd_screen_resource_destroy;
645bf215546Sopenharmony_ci   SCR_INIT(flush_frontbuffer);
646bf215546Sopenharmony_ci   SCR_INIT(fence_reference);
647bf215546Sopenharmony_ci   SCR_INIT(fence_finish);
648bf215546Sopenharmony_ci   SCR_INIT(fence_get_fd);
649bf215546Sopenharmony_ci   SCR_INIT(memobj_create_from_handle);
650bf215546Sopenharmony_ci   SCR_INIT(memobj_destroy);
651bf215546Sopenharmony_ci   SCR_INIT(get_driver_query_info);
652bf215546Sopenharmony_ci   SCR_INIT(get_driver_query_group_info);
653bf215546Sopenharmony_ci   SCR_INIT(get_compiler_options);
654bf215546Sopenharmony_ci   SCR_INIT(get_driver_uuid);
655bf215546Sopenharmony_ci   SCR_INIT(get_device_uuid);
656bf215546Sopenharmony_ci   SCR_INIT(finalize_nir);
657bf215546Sopenharmony_ci   SCR_INIT(get_sparse_texture_virtual_page_size);
658bf215546Sopenharmony_ci   SCR_INIT(create_vertex_state);
659bf215546Sopenharmony_ci   SCR_INIT(vertex_state_destroy);
660bf215546Sopenharmony_ci
661bf215546Sopenharmony_ci#undef SCR_INIT
662bf215546Sopenharmony_ci
663bf215546Sopenharmony_ci   dscreen->screen = screen;
664bf215546Sopenharmony_ci   dscreen->timeout_ms = timeout;
665bf215546Sopenharmony_ci   dscreen->dump_mode = mode;
666bf215546Sopenharmony_ci   dscreen->flush_always = flush;
667bf215546Sopenharmony_ci   dscreen->transfers = transfers;
668bf215546Sopenharmony_ci   dscreen->verbose = verbose;
669bf215546Sopenharmony_ci   dscreen->apitrace_dump_call = apitrace_dump_call;
670bf215546Sopenharmony_ci
671bf215546Sopenharmony_ci   switch (dscreen->dump_mode) {
672bf215546Sopenharmony_ci   case DD_DUMP_ALL_CALLS:
673bf215546Sopenharmony_ci      fprintf(stderr, "Gallium debugger active. Logging all calls.\n");
674bf215546Sopenharmony_ci      break;
675bf215546Sopenharmony_ci   case DD_DUMP_APITRACE_CALL:
676bf215546Sopenharmony_ci      fprintf(stderr, "Gallium debugger active. Going to dump an apitrace call.\n");
677bf215546Sopenharmony_ci      break;
678bf215546Sopenharmony_ci   default:
679bf215546Sopenharmony_ci      fprintf(stderr, "Gallium debugger active.\n");
680bf215546Sopenharmony_ci      break;
681bf215546Sopenharmony_ci   }
682bf215546Sopenharmony_ci
683bf215546Sopenharmony_ci   if (dscreen->timeout_ms > 0)
684bf215546Sopenharmony_ci      fprintf(stderr, "Hang detection timeout is %ums.\n", dscreen->timeout_ms);
685bf215546Sopenharmony_ci   else
686bf215546Sopenharmony_ci      fprintf(stderr, "Hang detection is disabled.\n");
687bf215546Sopenharmony_ci
688bf215546Sopenharmony_ci   dscreen->skip_count = debug_get_num_option("GALLIUM_DDEBUG_SKIP", 0);
689bf215546Sopenharmony_ci   if (dscreen->skip_count > 0) {
690bf215546Sopenharmony_ci      fprintf(stderr, "Gallium debugger skipping the first %u draw calls.\n",
691bf215546Sopenharmony_ci              dscreen->skip_count);
692bf215546Sopenharmony_ci   }
693bf215546Sopenharmony_ci
694bf215546Sopenharmony_ci   return &dscreen->base;
695bf215546Sopenharmony_ci}
696