1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2012-2013 LunarG, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Chia-I Wu <olv (at) lunarg.com> 26 */ 27 28 #include "util/u_upload_mgr.h" 29 30 #include "ilo_blit.h" 31 #include "ilo_blitter.h" 32 #include "ilo_cp.h" 33 #include "ilo_draw.h" 34 #include "ilo_gpgpu.h" 35 #include "ilo_query.h" 36 #include "ilo_render.h" 37 #include "ilo_resource.h" 38 #include "ilo_screen.h" 39 #include "ilo_shader.h" 40 #include "ilo_state.h" 41 #include "ilo_transfer.h" 42 #include "ilo_video.h" 43 #include "ilo_context.h" 44 45 static void 46 ilo_context_cp_submitted(struct ilo_cp *cp, void *data) 47 { 48 struct ilo_context *ilo = ilo_context(data); 49 50 /* builder buffers are reallocated */ 51 ilo_render_invalidate_builder(ilo->render); 52 } 53 54 static void 55 ilo_flush(struct pipe_context *pipe, 56 struct pipe_fence_handle **f, 57 unsigned flags) 58 { 59 struct ilo_context *ilo = ilo_context(pipe); 60 61 ilo_cp_submit(ilo->cp, 62 (flags & PIPE_FLUSH_END_OF_FRAME) ? "frame end" : "user request"); 63 64 if (f) { 65 struct pipe_screen *screen = pipe->screen; 66 screen->fence_reference(screen, f, NULL); 67 *f = ilo_screen_fence_create(pipe->screen, ilo->cp->last_submitted_bo); 68 } 69 } 70 71 static void 72 ilo_render_condition(struct pipe_context *pipe, 73 struct pipe_query *query, 74 boolean condition, 75 uint mode) 76 { 77 struct ilo_context *ilo = ilo_context(pipe); 78 79 /* reference count? */ 80 ilo->render_condition.query = query; 81 ilo->render_condition.condition = condition; 82 ilo->render_condition.mode = mode; 83 } 84 85 bool 86 ilo_skip_rendering(struct ilo_context *ilo) 87 { 88 uint64_t result; 89 bool wait; 90 91 if (!ilo->render_condition.query) 92 return false; 93 94 switch (ilo->render_condition.mode) { 95 case PIPE_RENDER_COND_WAIT: 96 case PIPE_RENDER_COND_BY_REGION_WAIT: 97 wait = true; 98 break; 99 case PIPE_RENDER_COND_NO_WAIT: 100 case PIPE_RENDER_COND_BY_REGION_NO_WAIT: 101 default: 102 wait = false; 103 break; 104 } 105 106 if (ilo->base.get_query_result(&ilo->base, ilo->render_condition.query, 107 wait, (union pipe_query_result *) &result)) 108 return ((bool) result == ilo->render_condition.condition); 109 else 110 return false; 111 } 112 113 static void 114 ilo_context_destroy(struct pipe_context *pipe) 115 { 116 struct ilo_context *ilo = ilo_context(pipe); 117 118 ilo_state_vector_cleanup(&ilo->state_vector); 119 120 if (ilo->uploader) 121 u_upload_destroy(ilo->uploader); 122 123 if (ilo->blitter) 124 ilo_blitter_destroy(ilo->blitter); 125 if (ilo->render) 126 ilo_render_destroy(ilo->render); 127 if (ilo->shader_cache) 128 ilo_shader_cache_destroy(ilo->shader_cache); 129 if (ilo->cp) 130 ilo_cp_destroy(ilo->cp); 131 132 slab_destroy(&ilo->transfer_mempool); 133 134 FREE(ilo); 135 } 136 137 static struct pipe_context * 138 ilo_context_create(struct pipe_screen *screen, void *priv, unsigned flags) 139 { 140 struct ilo_screen *is = ilo_screen(screen); 141 struct ilo_context *ilo; 142 143 ilo = CALLOC_STRUCT(ilo_context); 144 if (!ilo) 145 return NULL; 146 147 ilo->winsys = is->dev.winsys; 148 ilo->dev = &is->dev; 149 150 /* 151 * initialize first, otherwise it may not be safe to call 152 * ilo_context_destroy() on errors 153 */ 154 slab_create(&ilo->transfer_mempool, 155 sizeof(struct ilo_transfer), 64); 156 157 ilo->shader_cache = ilo_shader_cache_create(); 158 ilo->cp = ilo_cp_create(ilo->dev, ilo->winsys, ilo->shader_cache); 159 if (ilo->cp) 160 ilo->render = ilo_render_create(&ilo->cp->builder); 161 162 if (!ilo->cp || !ilo->shader_cache || !ilo->render) { 163 ilo_context_destroy(&ilo->base); 164 return NULL; 165 } 166 167 ilo_cp_set_submit_callback(ilo->cp, 168 ilo_context_cp_submitted, (void *) ilo); 169 170 ilo->base.screen = screen; 171 ilo->base.priv = priv; 172 173 ilo->base.destroy = ilo_context_destroy; 174 ilo->base.flush = ilo_flush; 175 ilo->base.render_condition = ilo_render_condition; 176 177 ilo_init_draw_functions(ilo); 178 ilo_init_query_functions(ilo); 179 ilo_init_state_functions(ilo); 180 ilo_init_blit_functions(ilo); 181 ilo_init_transfer_functions(ilo); 182 ilo_init_video_functions(ilo); 183 ilo_init_gpgpu_functions(ilo); 184 185 ilo_init_draw(ilo); 186 ilo_state_vector_init(ilo->dev, &ilo->state_vector); 187 188 /* 189 * These must be called last as u_upload/u_blitter are clients of the pipe 190 * context. 191 */ 192 ilo->uploader = u_upload_create(&ilo->base, 1024 * 1024, 193 PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_INDEX_BUFFER, 194 PIPE_USAGE_STREAM); 195 if (!ilo->uploader) { 196 ilo_context_destroy(&ilo->base); 197 return NULL; 198 } 199 200 ilo->blitter = ilo_blitter_create(ilo); 201 if (!ilo->blitter) { 202 ilo_context_destroy(&ilo->base); 203 return NULL; 204 } 205 206 return &ilo->base; 207 } 208 209 /** 210 * Initialize context-related functions. 211 */ 212 void 213 ilo_init_context_functions(struct ilo_screen *is) 214 { 215 is->base.context_create = ilo_context_create; 216 } 217