• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2010 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 
29 #include "pipe/p_screen.h"
30 #include "pipe/p_state.h"
31 #include "util/u_memory.h"
32 #include "util/u_debug.h"
33 
34 #include "rbug_public.h"
35 #include "rbug_screen.h"
36 #include "rbug_context.h"
37 #include "rbug_objects.h"
38 
39 DEBUG_GET_ONCE_BOOL_OPTION(rbug, "GALLIUM_RBUG", false)
40 
41 static void
rbug_screen_destroy(struct pipe_screen * _screen)42 rbug_screen_destroy(struct pipe_screen *_screen)
43 {
44    struct rbug_screen *rb_screen = rbug_screen(_screen);
45    struct pipe_screen *screen = rb_screen->screen;
46 
47    screen->destroy(screen);
48 
49    FREE(rb_screen);
50 }
51 
52 static const char *
rbug_screen_get_name(struct pipe_screen * _screen)53 rbug_screen_get_name(struct pipe_screen *_screen)
54 {
55    struct rbug_screen *rb_screen = rbug_screen(_screen);
56    struct pipe_screen *screen = rb_screen->screen;
57 
58    return screen->get_name(screen);
59 }
60 
61 static const char *
rbug_screen_get_vendor(struct pipe_screen * _screen)62 rbug_screen_get_vendor(struct pipe_screen *_screen)
63 {
64    struct rbug_screen *rb_screen = rbug_screen(_screen);
65    struct pipe_screen *screen = rb_screen->screen;
66 
67    return screen->get_vendor(screen);
68 }
69 
70 static const char *
rbug_screen_get_device_vendor(struct pipe_screen * _screen)71 rbug_screen_get_device_vendor(struct pipe_screen *_screen)
72 {
73    struct rbug_screen *rb_screen = rbug_screen(_screen);
74    struct pipe_screen *screen = rb_screen->screen;
75 
76    return screen->get_device_vendor(screen);
77 }
78 
79 static const void *
rbug_screen_get_compiler_options(struct pipe_screen * _screen,enum pipe_shader_ir ir,enum pipe_shader_type shader)80 rbug_screen_get_compiler_options(struct pipe_screen *_screen,
81                                  enum pipe_shader_ir ir,
82                                  enum pipe_shader_type shader)
83 {
84    struct pipe_screen *screen = rbug_screen(_screen)->screen;
85 
86    return screen->get_compiler_options(screen, ir, shader);
87 }
88 
89 static struct disk_cache *
rbug_screen_get_disk_shader_cache(struct pipe_screen * _screen)90 rbug_screen_get_disk_shader_cache(struct pipe_screen *_screen)
91 {
92    struct pipe_screen *screen = rbug_screen(_screen)->screen;
93 
94    return screen->get_disk_shader_cache(screen);
95 }
96 
97 static int
rbug_screen_get_param(struct pipe_screen * _screen,enum pipe_cap param)98 rbug_screen_get_param(struct pipe_screen *_screen,
99                       enum pipe_cap param)
100 {
101    struct rbug_screen *rb_screen = rbug_screen(_screen);
102    struct pipe_screen *screen = rb_screen->screen;
103 
104    return screen->get_param(screen,
105                             param);
106 }
107 
108 static int
rbug_screen_get_shader_param(struct pipe_screen * _screen,enum pipe_shader_type shader,enum pipe_shader_cap param)109 rbug_screen_get_shader_param(struct pipe_screen *_screen,
110                              enum pipe_shader_type shader,
111                              enum pipe_shader_cap param)
112 {
113    struct rbug_screen *rb_screen = rbug_screen(_screen);
114    struct pipe_screen *screen = rb_screen->screen;
115 
116    return screen->get_shader_param(screen, shader,
117                             param);
118 }
119 
120 static float
rbug_screen_get_paramf(struct pipe_screen * _screen,enum pipe_capf param)121 rbug_screen_get_paramf(struct pipe_screen *_screen,
122                        enum pipe_capf param)
123 {
124    struct rbug_screen *rb_screen = rbug_screen(_screen);
125    struct pipe_screen *screen = rb_screen->screen;
126 
127    return screen->get_paramf(screen,
128                              param);
129 }
130 
131 static bool
rbug_screen_is_format_supported(struct pipe_screen * _screen,enum pipe_format format,enum pipe_texture_target target,unsigned sample_count,unsigned storage_sample_count,unsigned tex_usage)132 rbug_screen_is_format_supported(struct pipe_screen *_screen,
133                                 enum pipe_format format,
134                                 enum pipe_texture_target target,
135                                 unsigned sample_count,
136                                 unsigned storage_sample_count,
137                                 unsigned tex_usage)
138 {
139    struct rbug_screen *rb_screen = rbug_screen(_screen);
140    struct pipe_screen *screen = rb_screen->screen;
141 
142    return screen->is_format_supported(screen,
143                                       format,
144                                       target,
145                                       sample_count,
146                                       storage_sample_count,
147                                       tex_usage);
148 }
149 
150 static void
rbug_screen_query_dmabuf_modifiers(struct pipe_screen * _screen,enum pipe_format format,int max,uint64_t * modifiers,unsigned int * external_only,int * count)151 rbug_screen_query_dmabuf_modifiers(struct pipe_screen *_screen,
152                                    enum pipe_format format, int max,
153                                    uint64_t *modifiers,
154                                    unsigned int *external_only, int *count)
155 {
156    struct rbug_screen *rb_screen = rbug_screen(_screen);
157    struct pipe_screen *screen = rb_screen->screen;
158 
159    screen->query_dmabuf_modifiers(screen,
160                                   format,
161                                   max,
162                                   modifiers,
163                                   external_only,
164                                   count);
165 }
166 
167 static bool
rbug_screen_is_dmabuf_modifier_supported(struct pipe_screen * _screen,uint64_t modifier,enum pipe_format format,bool * external_only)168 rbug_screen_is_dmabuf_modifier_supported(struct pipe_screen *_screen,
169                                          uint64_t modifier,
170                                          enum pipe_format format,
171                                          bool *external_only)
172 {
173    struct rbug_screen *rb_screen = rbug_screen(_screen);
174    struct pipe_screen *screen = rb_screen->screen;
175 
176    return screen->is_dmabuf_modifier_supported(screen,
177                                                modifier,
178                                                format,
179                                                external_only);
180 }
181 
182 static unsigned int
rbug_screen_get_dmabuf_modifier_planes(struct pipe_screen * _screen,uint64_t modifier,enum pipe_format format)183 rbug_screen_get_dmabuf_modifier_planes(struct pipe_screen *_screen,
184                                        uint64_t modifier,
185                                        enum pipe_format format)
186 {
187    struct rbug_screen *rb_screen = rbug_screen(_screen);
188    struct pipe_screen *screen = rb_screen->screen;
189 
190    return screen->get_dmabuf_modifier_planes(screen, modifier, format);
191 }
192 
193 static int
rbug_screen_get_sparse_texture_virtual_page_size(struct pipe_screen * _screen,enum pipe_texture_target target,bool multi_sample,enum pipe_format format,unsigned offset,unsigned size,int * x,int * y,int * z)194 rbug_screen_get_sparse_texture_virtual_page_size(struct pipe_screen *_screen,
195                                                  enum pipe_texture_target target,
196                                                  bool multi_sample,
197                                                  enum pipe_format format,
198                                                  unsigned offset, unsigned size,
199                                                  int *x, int *y, int *z)
200 {
201    struct rbug_screen *rb_screen = rbug_screen(_screen);
202    struct pipe_screen *screen = rb_screen->screen;
203 
204    return screen->get_sparse_texture_virtual_page_size(screen, target, multi_sample,
205                                                        format, offset, size, x, y, z);
206 }
207 
208 static struct pipe_context *
rbug_screen_context_create(struct pipe_screen * _screen,void * priv,unsigned flags)209 rbug_screen_context_create(struct pipe_screen *_screen,
210                            void *priv, unsigned flags)
211 {
212    struct rbug_screen *rb_screen = rbug_screen(_screen);
213    struct pipe_screen *screen = rb_screen->screen;
214    struct pipe_context *result;
215 
216    result = screen->context_create(screen, priv, flags);
217    if (result)
218       return rbug_context_create(_screen, result);
219    return NULL;
220 }
221 
222 static bool
rbug_screen_can_create_resource(struct pipe_screen * _screen,const struct pipe_resource * templat)223 rbug_screen_can_create_resource(struct pipe_screen *_screen,
224                                 const struct pipe_resource *templat)
225 {
226    struct rbug_screen *rb_screen = rbug_screen(_screen);
227    struct pipe_screen *screen = rb_screen->screen;
228 
229    return screen->can_create_resource(screen,
230                                       templat);
231 }
232 
233 static struct pipe_resource *
rbug_screen_resource_create(struct pipe_screen * _screen,const struct pipe_resource * templat)234 rbug_screen_resource_create(struct pipe_screen *_screen,
235                             const struct pipe_resource *templat)
236 {
237    struct rbug_screen *rb_screen = rbug_screen(_screen);
238    struct pipe_screen *screen = rb_screen->screen;
239    struct pipe_resource *result;
240 
241    result = screen->resource_create(screen,
242                                     templat);
243 
244    if (result)
245       return rbug_resource_create(rb_screen, result);
246    return NULL;
247 }
248 
249 static struct pipe_resource *
rbug_screen_resource_create_with_modifiers(struct pipe_screen * _screen,const struct pipe_resource * templat,const uint64_t * modifiers,int count)250 rbug_screen_resource_create_with_modifiers(struct pipe_screen *_screen,
251                                            const struct pipe_resource *templat,
252                                            const uint64_t *modifiers, int count)
253 {
254    struct rbug_screen *rb_screen = rbug_screen(_screen);
255    struct pipe_screen *screen = rb_screen->screen;
256    struct pipe_resource *result;
257 
258    result = screen->resource_create_with_modifiers(screen,
259                                                    templat,
260                                                    modifiers,
261                                                    count);
262 
263    if (result)
264       return rbug_resource_create(rb_screen, result);
265    return NULL;
266 }
267 
268 static struct pipe_resource *
rbug_screen_resource_from_handle(struct pipe_screen * _screen,const struct pipe_resource * templ,struct winsys_handle * handle,unsigned usage)269 rbug_screen_resource_from_handle(struct pipe_screen *_screen,
270                                  const struct pipe_resource *templ,
271                                  struct winsys_handle *handle,
272                                  unsigned usage)
273 {
274    struct rbug_screen *rb_screen = rbug_screen(_screen);
275    struct pipe_screen *screen = rb_screen->screen;
276    struct pipe_resource *result;
277 
278    result = screen->resource_from_handle(screen, templ, handle, usage);
279 
280    result = rbug_resource_create(rbug_screen(_screen), result);
281 
282    return result;
283 }
284 
285 static bool
rbug_screen_check_resource_capability(struct pipe_screen * _screen,struct pipe_resource * _resource,unsigned bind)286 rbug_screen_check_resource_capability(struct pipe_screen *_screen,
287                                       struct pipe_resource *_resource,
288                                       unsigned bind)
289 {
290    struct rbug_screen *rb_screen = rbug_screen(_screen);
291    struct rbug_resource *rb_resource = rbug_resource(_resource);
292    struct pipe_screen *screen = rb_screen->screen;
293    struct pipe_resource *resource = rb_resource->resource;
294 
295    return screen->check_resource_capability(screen, resource, bind);
296 }
297 
298 static bool
rbug_screen_resource_get_handle(struct pipe_screen * _screen,struct pipe_context * _pipe,struct pipe_resource * _resource,struct winsys_handle * handle,unsigned usage)299 rbug_screen_resource_get_handle(struct pipe_screen *_screen,
300                                 struct pipe_context *_pipe,
301                                 struct pipe_resource *_resource,
302                                 struct winsys_handle *handle,
303                                 unsigned usage)
304 {
305    struct rbug_screen *rb_screen = rbug_screen(_screen);
306    struct rbug_context *rb_pipe = rbug_context(_pipe);
307    struct rbug_resource *rb_resource = rbug_resource(_resource);
308    struct pipe_screen *screen = rb_screen->screen;
309    struct pipe_resource *resource = rb_resource->resource;
310 
311    return screen->resource_get_handle(screen, rb_pipe ? rb_pipe->pipe : NULL,
312                                       resource, handle, usage);
313 }
314 
315 static bool
rbug_screen_resource_get_param(struct pipe_screen * _screen,struct pipe_context * _pipe,struct pipe_resource * _resource,unsigned plane,unsigned layer,unsigned level,enum pipe_resource_param param,unsigned handle_usage,uint64_t * value)316 rbug_screen_resource_get_param(struct pipe_screen *_screen,
317                                struct pipe_context *_pipe,
318                                struct pipe_resource *_resource,
319                                unsigned plane,
320                                unsigned layer,
321                                unsigned level,
322                                enum pipe_resource_param param,
323                                unsigned handle_usage,
324                                uint64_t *value)
325 {
326    struct rbug_screen *rb_screen = rbug_screen(_screen);
327    struct rbug_context *rb_pipe = rbug_context(_pipe);
328    struct rbug_resource *rb_resource = rbug_resource(_resource);
329    struct pipe_screen *screen = rb_screen->screen;
330    struct pipe_resource *resource = rb_resource->resource;
331 
332    return screen->resource_get_param(screen, rb_pipe ? rb_pipe->pipe : NULL,
333                                      resource, plane, layer, level, param,
334                                      handle_usage, value);
335 }
336 
337 
338 static void
rbug_screen_resource_get_info(struct pipe_screen * _screen,struct pipe_resource * _resource,unsigned * stride,unsigned * offset)339 rbug_screen_resource_get_info(struct pipe_screen *_screen,
340                               struct pipe_resource *_resource,
341                               unsigned *stride,
342                               unsigned *offset)
343 {
344    struct rbug_screen *rb_screen = rbug_screen(_screen);
345    struct rbug_resource *rb_resource = rbug_resource(_resource);
346    struct pipe_screen *screen = rb_screen->screen;
347    struct pipe_resource *resource = rb_resource->resource;
348 
349    screen->resource_get_info(screen, resource, stride, offset);
350 }
351 
352 static void
rbug_screen_resource_changed(struct pipe_screen * _screen,struct pipe_resource * _resource)353 rbug_screen_resource_changed(struct pipe_screen *_screen,
354                              struct pipe_resource *_resource)
355 {
356    struct rbug_screen *rb_screen = rbug_screen(_screen);
357    struct rbug_resource *rb_resource = rbug_resource(_resource);
358    struct pipe_screen *screen = rb_screen->screen;
359    struct pipe_resource *resource = rb_resource->resource;
360 
361    screen->resource_changed(screen, resource);
362 }
363 
364 static void
rbug_screen_resource_destroy(struct pipe_screen * screen,struct pipe_resource * _resource)365 rbug_screen_resource_destroy(struct pipe_screen *screen,
366                              struct pipe_resource *_resource)
367 {
368    rbug_resource_destroy(rbug_resource(_resource));
369 }
370 
371 static void
rbug_screen_flush_frontbuffer(struct pipe_screen * _screen,struct pipe_context * _ctx,struct pipe_resource * _resource,unsigned level,unsigned layer,void * context_private,struct pipe_box * sub_box)372 rbug_screen_flush_frontbuffer(struct pipe_screen *_screen,
373                               struct pipe_context *_ctx,
374                               struct pipe_resource *_resource,
375                               unsigned level, unsigned layer,
376                               void *context_private, struct pipe_box *sub_box)
377 {
378    struct rbug_screen *rb_screen = rbug_screen(_screen);
379    struct rbug_resource *rb_resource = rbug_resource(_resource);
380    struct pipe_screen *screen = rb_screen->screen;
381    struct pipe_resource *resource = rb_resource->resource;
382    struct pipe_context *ctx = _ctx ? rbug_context(_ctx)->pipe : NULL;
383 
384    screen->flush_frontbuffer(screen,
385                              ctx,
386                              resource,
387                              level, layer,
388                              context_private, sub_box);
389 }
390 
391 static void
rbug_screen_fence_reference(struct pipe_screen * _screen,struct pipe_fence_handle ** ptr,struct pipe_fence_handle * fence)392 rbug_screen_fence_reference(struct pipe_screen *_screen,
393                             struct pipe_fence_handle **ptr,
394                             struct pipe_fence_handle *fence)
395 {
396    struct rbug_screen *rb_screen = rbug_screen(_screen);
397    struct pipe_screen *screen = rb_screen->screen;
398 
399    screen->fence_reference(screen,
400                            ptr,
401                            fence);
402 }
403 
404 static bool
rbug_screen_fence_finish(struct pipe_screen * _screen,struct pipe_context * _ctx,struct pipe_fence_handle * fence,uint64_t timeout)405 rbug_screen_fence_finish(struct pipe_screen *_screen,
406                          struct pipe_context *_ctx,
407                          struct pipe_fence_handle *fence,
408                          uint64_t timeout)
409 {
410    struct rbug_screen *rb_screen = rbug_screen(_screen);
411    struct pipe_screen *screen = rb_screen->screen;
412    struct pipe_context *ctx = _ctx ? rbug_context(_ctx)->pipe : NULL;
413 
414    return screen->fence_finish(screen, ctx, fence, timeout);
415 }
416 
417 static int
rbug_screen_fence_get_fd(struct pipe_screen * _screen,struct pipe_fence_handle * fence)418 rbug_screen_fence_get_fd(struct pipe_screen *_screen,
419                          struct pipe_fence_handle *fence)
420 {
421    struct rbug_screen *rb_screen = rbug_screen(_screen);
422    struct pipe_screen *screen = rb_screen->screen;
423 
424    return screen->fence_get_fd(screen, fence);
425 }
426 
427 static char *
rbug_screen_finalize_nir(struct pipe_screen * _screen,void * nir)428 rbug_screen_finalize_nir(struct pipe_screen *_screen, void *nir)
429 {
430    struct pipe_screen *screen = rbug_screen(_screen)->screen;
431 
432    return screen->finalize_nir(screen, nir);
433 }
434 
435 bool
rbug_enabled()436 rbug_enabled()
437 {
438    return debug_get_option_rbug();
439 }
440 
441 struct pipe_screen *
rbug_screen_create(struct pipe_screen * screen)442 rbug_screen_create(struct pipe_screen *screen)
443 {
444    struct rbug_screen *rb_screen;
445 
446    if (!debug_get_option_rbug())
447       return screen;
448 
449    rb_screen = CALLOC_STRUCT(rbug_screen);
450    if (!rb_screen)
451       return screen;
452 
453    (void) mtx_init(&rb_screen->list_mutex, mtx_plain);
454    list_inithead(&rb_screen->contexts);
455    list_inithead(&rb_screen->resources);
456    list_inithead(&rb_screen->surfaces);
457    list_inithead(&rb_screen->transfers);
458 
459 #define SCR_INIT(_member) \
460    rb_screen->base._member = screen->_member ? rbug_screen_##_member : NULL
461 
462    rb_screen->base.destroy = rbug_screen_destroy;
463    rb_screen->base.get_name = rbug_screen_get_name;
464    rb_screen->base.get_vendor = rbug_screen_get_vendor;
465    SCR_INIT(get_compiler_options);
466    SCR_INIT(get_disk_shader_cache);
467    rb_screen->base.get_device_vendor = rbug_screen_get_device_vendor;
468    rb_screen->base.get_param = rbug_screen_get_param;
469    rb_screen->base.get_shader_param = rbug_screen_get_shader_param;
470    rb_screen->base.get_paramf = rbug_screen_get_paramf;
471    rb_screen->base.is_format_supported = rbug_screen_is_format_supported;
472    SCR_INIT(query_dmabuf_modifiers);
473    SCR_INIT(is_dmabuf_modifier_supported);
474    SCR_INIT(get_dmabuf_modifier_planes);
475    rb_screen->base.context_create = rbug_screen_context_create;
476    SCR_INIT(can_create_resource);
477    rb_screen->base.resource_create = rbug_screen_resource_create;
478    SCR_INIT(resource_create_with_modifiers);
479    rb_screen->base.resource_from_handle = rbug_screen_resource_from_handle;
480    SCR_INIT(check_resource_capability);
481    rb_screen->base.resource_get_handle = rbug_screen_resource_get_handle;
482    SCR_INIT(resource_get_param);
483    SCR_INIT(resource_get_info);
484    SCR_INIT(resource_changed);
485    rb_screen->base.resource_destroy = rbug_screen_resource_destroy;
486    rb_screen->base.flush_frontbuffer = rbug_screen_flush_frontbuffer;
487    rb_screen->base.fence_reference = rbug_screen_fence_reference;
488    rb_screen->base.fence_finish = rbug_screen_fence_finish;
489    rb_screen->base.fence_get_fd = rbug_screen_fence_get_fd;
490    SCR_INIT(finalize_nir);
491    SCR_INIT(get_sparse_texture_virtual_page_size);
492 
493    rb_screen->screen = screen;
494 
495    rb_screen->private_context = screen->context_create(screen, NULL, 0);
496    if (!rb_screen->private_context)
497       goto err_free;
498 
499    rb_screen->rbug = rbug_start(rb_screen);
500 
501    if (!rb_screen->rbug)
502       goto err_context;
503 
504    return &rb_screen->base;
505 
506 err_context:
507    rb_screen->private_context->destroy(rb_screen->private_context);
508 err_free:
509    FREE(rb_screen);
510    return screen;
511 }
512