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