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 40DEBUG_GET_ONCE_BOOL_OPTION(rbug, "GALLIUM_RBUG", FALSE) 41 42static void 43rbug_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 53static const char * 54rbug_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 62static const char * 63rbug_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 71static int 72rbug_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 82static int 83rbug_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 93static float 94rbug_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 104static boolean 105rbug_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 121static struct pipe_context * 122rbug_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 135static struct pipe_resource * 136rbug_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 151static struct pipe_resource * 152rbug_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 167static boolean 168rbug_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 182static void 183rbug_screen_resource_destroy(struct pipe_screen *screen, 184 struct pipe_resource *_resource) 185{ 186 rbug_resource_destroy(rbug_resource(_resource)); 187} 188 189static void 190rbug_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 206static void 207rbug_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 219static boolean 220rbug_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 230static boolean 231rbug_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 243boolean 244rbug_enabled() 245{ 246 return debug_get_option_rbug(); 247} 248 249struct pipe_screen * 250rbug_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 297err_context: 298 rb_screen->private_context->destroy(rb_screen->private_context); 299err_free: 300 FREE(rb_screen); 301 return screen; 302} 303