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 #include "util/u_simple_list.h" 34 35 #include "rbug_public.h" 36 #include "rbug_screen.h" 37 #include "rbug_context.h" 38 #include "rbug_objects.h" 39 40 DEBUG_GET_ONCE_BOOL_OPTION(rbug, "GALLIUM_RBUG", FALSE) 41 42 static void 43 rbug_screen_destroy(struct pipe_screen *_screen) 44 { 45 struct rbug_screen *rb_screen = rbug_screen(_screen); 46 struct pipe_screen *screen = rb_screen->screen; 47 48 screen->destroy(screen); 49 50 FREE(rb_screen); 51 } 52 53 static const char * 54 rbug_screen_get_name(struct pipe_screen *_screen) 55 { 56 struct rbug_screen *rb_screen = rbug_screen(_screen); 57 struct pipe_screen *screen = rb_screen->screen; 58 59 return screen->get_name(screen); 60 } 61 62 static const char * 63 rbug_screen_get_vendor(struct pipe_screen *_screen) 64 { 65 struct rbug_screen *rb_screen = rbug_screen(_screen); 66 struct pipe_screen *screen = rb_screen->screen; 67 68 return screen->get_vendor(screen); 69 } 70 71 static int 72 rbug_screen_get_param(struct pipe_screen *_screen, 73 enum pipe_cap param) 74 { 75 struct rbug_screen *rb_screen = rbug_screen(_screen); 76 struct pipe_screen *screen = rb_screen->screen; 77 78 return screen->get_param(screen, 79 param); 80 } 81 82 static int 83 rbug_screen_get_shader_param(struct pipe_screen *_screen, 84 unsigned shader, enum pipe_shader_cap param) 85 { 86 struct rbug_screen *rb_screen = rbug_screen(_screen); 87 struct pipe_screen *screen = rb_screen->screen; 88 89 return screen->get_shader_param(screen, shader, 90 param); 91 } 92 93 static float 94 rbug_screen_get_paramf(struct pipe_screen *_screen, 95 enum pipe_capf param) 96 { 97 struct rbug_screen *rb_screen = rbug_screen(_screen); 98 struct pipe_screen *screen = rb_screen->screen; 99 100 return screen->get_paramf(screen, 101 param); 102 } 103 104 static boolean 105 rbug_screen_is_format_supported(struct pipe_screen *_screen, 106 enum pipe_format format, 107 enum pipe_texture_target target, 108 unsigned sample_count, 109 unsigned tex_usage) 110 { 111 struct rbug_screen *rb_screen = rbug_screen(_screen); 112 struct pipe_screen *screen = rb_screen->screen; 113 114 return screen->is_format_supported(screen, 115 format, 116 target, 117 sample_count, 118 tex_usage); 119 } 120 121 static struct pipe_context * 122 rbug_screen_context_create(struct pipe_screen *_screen, 123 void *priv) 124 { 125 struct rbug_screen *rb_screen = rbug_screen(_screen); 126 struct pipe_screen *screen = rb_screen->screen; 127 struct pipe_context *result; 128 129 result = screen->context_create(screen, priv); 130 if (result) 131 return rbug_context_create(_screen, result); 132 return NULL; 133 } 134 135 static struct pipe_resource * 136 rbug_screen_resource_create(struct pipe_screen *_screen, 137 const struct pipe_resource *templat) 138 { 139 struct rbug_screen *rb_screen = rbug_screen(_screen); 140 struct pipe_screen *screen = rb_screen->screen; 141 struct pipe_resource *result; 142 143 result = screen->resource_create(screen, 144 templat); 145 146 if (result) 147 return rbug_resource_create(rb_screen, result); 148 return NULL; 149 } 150 151 static struct pipe_resource * 152 rbug_screen_resource_from_handle(struct pipe_screen *_screen, 153 const struct pipe_resource *templ, 154 struct winsys_handle *handle) 155 { 156 struct rbug_screen *rb_screen = rbug_screen(_screen); 157 struct pipe_screen *screen = rb_screen->screen; 158 struct pipe_resource *result; 159 160 result = screen->resource_from_handle(screen, templ, handle); 161 162 result = rbug_resource_create(rbug_screen(_screen), result); 163 164 return result; 165 } 166 167 static boolean 168 rbug_screen_resource_get_handle(struct pipe_screen *_screen, 169 struct pipe_resource *_resource, 170 struct winsys_handle *handle) 171 { 172 struct rbug_screen *rb_screen = rbug_screen(_screen); 173 struct rbug_resource *rb_resource = rbug_resource(_resource); 174 struct pipe_screen *screen = rb_screen->screen; 175 struct pipe_resource *resource = rb_resource->resource; 176 177 return screen->resource_get_handle(screen, resource, handle); 178 } 179 180 181 182 static void 183 rbug_screen_resource_destroy(struct pipe_screen *screen, 184 struct pipe_resource *_resource) 185 { 186 rbug_resource_destroy(rbug_resource(_resource)); 187 } 188 189 static void 190 rbug_screen_flush_frontbuffer(struct pipe_screen *_screen, 191 struct pipe_resource *_resource, 192 unsigned level, unsigned layer, 193 void *context_private) 194 { 195 struct rbug_screen *rb_screen = rbug_screen(_screen); 196 struct rbug_resource *rb_resource = rbug_resource(_resource); 197 struct pipe_screen *screen = rb_screen->screen; 198 struct pipe_resource *resource = rb_resource->resource; 199 200 screen->flush_frontbuffer(screen, 201 resource, 202 level, layer, 203 context_private); 204 } 205 206 static void 207 rbug_screen_fence_reference(struct pipe_screen *_screen, 208 struct pipe_fence_handle **ptr, 209 struct pipe_fence_handle *fence) 210 { 211 struct rbug_screen *rb_screen = rbug_screen(_screen); 212 struct pipe_screen *screen = rb_screen->screen; 213 214 screen->fence_reference(screen, 215 ptr, 216 fence); 217 } 218 219 static boolean 220 rbug_screen_fence_signalled(struct pipe_screen *_screen, 221 struct pipe_fence_handle *fence) 222 { 223 struct rbug_screen *rb_screen = rbug_screen(_screen); 224 struct pipe_screen *screen = rb_screen->screen; 225 226 return screen->fence_signalled(screen, 227 fence); 228 } 229 230 static boolean 231 rbug_screen_fence_finish(struct pipe_screen *_screen, 232 struct pipe_fence_handle *fence, 233 uint64_t timeout) 234 { 235 struct rbug_screen *rb_screen = rbug_screen(_screen); 236 struct pipe_screen *screen = rb_screen->screen; 237 238 return screen->fence_finish(screen, 239 fence, 240 timeout); 241 } 242 243 boolean 244 rbug_enabled() 245 { 246 return debug_get_option_rbug(); 247 } 248 249 struct pipe_screen * 250 rbug_screen_create(struct pipe_screen *screen) 251 { 252 struct rbug_screen *rb_screen; 253 254 if (!debug_get_option_rbug()) 255 return screen; 256 257 rb_screen = CALLOC_STRUCT(rbug_screen); 258 if (!rb_screen) 259 return screen; 260 261 pipe_mutex_init(rb_screen->list_mutex); 262 make_empty_list(&rb_screen->contexts); 263 make_empty_list(&rb_screen->resources); 264 make_empty_list(&rb_screen->surfaces); 265 make_empty_list(&rb_screen->transfers); 266 267 rb_screen->base.destroy = rbug_screen_destroy; 268 rb_screen->base.get_name = rbug_screen_get_name; 269 rb_screen->base.get_vendor = rbug_screen_get_vendor; 270 rb_screen->base.get_param = rbug_screen_get_param; 271 rb_screen->base.get_shader_param = rbug_screen_get_shader_param; 272 rb_screen->base.get_paramf = rbug_screen_get_paramf; 273 rb_screen->base.is_format_supported = rbug_screen_is_format_supported; 274 rb_screen->base.context_create = rbug_screen_context_create; 275 rb_screen->base.resource_create = rbug_screen_resource_create; 276 rb_screen->base.resource_from_handle = rbug_screen_resource_from_handle; 277 rb_screen->base.resource_get_handle = rbug_screen_resource_get_handle; 278 rb_screen->base.resource_destroy = rbug_screen_resource_destroy; 279 rb_screen->base.flush_frontbuffer = rbug_screen_flush_frontbuffer; 280 rb_screen->base.fence_reference = rbug_screen_fence_reference; 281 rb_screen->base.fence_signalled = rbug_screen_fence_signalled; 282 rb_screen->base.fence_finish = rbug_screen_fence_finish; 283 284 rb_screen->screen = screen; 285 286 rb_screen->private_context = screen->context_create(screen, NULL); 287 if (!rb_screen->private_context) 288 goto err_free; 289 290 rb_screen->rbug = rbug_start(rb_screen); 291 292 if (!rb_screen->rbug) 293 goto err_context; 294 295 return &rb_screen->base; 296 297 err_context: 298 rb_screen->private_context->destroy(rb_screen->private_context); 299 err_free: 300 FREE(rb_screen); 301 return screen; 302 } 303