1/************************************************************************** 2 * 3 * Copyright 2015 Advanced Micro Devices, Inc. 4 * Copyright 2008 VMware, Inc. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * on the rights to use, copy, modify, merge, publish, distribute, sub 11 * license, and/or sell copies of the Software, and to permit persons to whom 12 * the Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the next 15 * paragraph) shall be included in all copies or substantial portions of the 16 * Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24 * USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#ifndef DD_H_ 29#define DD_H_ 30 31#include "pipe/p_context.h" 32#include "pipe/p_state.h" 33#include "pipe/p_screen.h" 34#include "dd_util.h" 35#include "os/os_thread.h" 36 37enum dd_mode { 38 DD_DETECT_HANGS, 39 DD_DETECT_HANGS_PIPELINED, 40 DD_DUMP_ALL_CALLS, 41 DD_DUMP_APITRACE_CALL, 42}; 43 44struct dd_screen 45{ 46 struct pipe_screen base; 47 struct pipe_screen *screen; 48 unsigned timeout_ms; 49 enum dd_mode mode; 50 bool no_flush; 51 bool verbose; 52 unsigned skip_count; 53 unsigned apitrace_dump_call; 54}; 55 56enum call_type 57{ 58 CALL_DRAW_VBO, 59 CALL_LAUNCH_GRID, 60 CALL_RESOURCE_COPY_REGION, 61 CALL_BLIT, 62 CALL_FLUSH_RESOURCE, 63 CALL_CLEAR, 64 CALL_CLEAR_BUFFER, 65 CALL_CLEAR_RENDER_TARGET, 66 CALL_CLEAR_DEPTH_STENCIL, 67 CALL_GENERATE_MIPMAP, 68}; 69 70struct call_resource_copy_region 71{ 72 struct pipe_resource *dst; 73 unsigned dst_level; 74 unsigned dstx, dsty, dstz; 75 struct pipe_resource *src; 76 unsigned src_level; 77 struct pipe_box src_box; 78}; 79 80struct call_clear 81{ 82 unsigned buffers; 83 union pipe_color_union color; 84 double depth; 85 unsigned stencil; 86}; 87 88struct call_clear_buffer 89{ 90 struct pipe_resource *res; 91 unsigned offset; 92 unsigned size; 93 const void *clear_value; 94 int clear_value_size; 95}; 96 97struct call_generate_mipmap { 98 struct pipe_resource *res; 99 enum pipe_format format; 100 unsigned base_level; 101 unsigned last_level; 102 unsigned first_layer; 103 unsigned last_layer; 104}; 105 106struct dd_call 107{ 108 enum call_type type; 109 110 union { 111 struct pipe_draw_info draw_vbo; 112 struct pipe_grid_info launch_grid; 113 struct call_resource_copy_region resource_copy_region; 114 struct pipe_blit_info blit; 115 struct pipe_resource *flush_resource; 116 struct call_clear clear; 117 struct call_clear_buffer clear_buffer; 118 struct call_generate_mipmap generate_mipmap; 119 } info; 120}; 121 122struct dd_query 123{ 124 unsigned type; 125 struct pipe_query *query; 126}; 127 128struct dd_state 129{ 130 void *cso; 131 132 union { 133 struct pipe_blend_state blend; 134 struct pipe_depth_stencil_alpha_state dsa; 135 struct pipe_rasterizer_state rs; 136 struct pipe_sampler_state sampler; 137 struct { 138 struct pipe_vertex_element velems[PIPE_MAX_ATTRIBS]; 139 unsigned count; 140 } velems; 141 struct pipe_shader_state shader; 142 } state; 143}; 144 145struct dd_draw_state 146{ 147 struct { 148 struct dd_query *query; 149 bool condition; 150 unsigned mode; 151 } render_cond; 152 153 struct pipe_index_buffer index_buffer; 154 struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; 155 156 unsigned num_so_targets; 157 struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS]; 158 unsigned so_offsets[PIPE_MAX_SO_BUFFERS]; 159 160 struct dd_state *shaders[PIPE_SHADER_TYPES]; 161 struct pipe_constant_buffer constant_buffers[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; 162 struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; 163 struct dd_state *sampler_states[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; 164 struct pipe_image_view shader_images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES]; 165 struct pipe_shader_buffer shader_buffers[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS]; 166 167 struct dd_state *velems; 168 struct dd_state *rs; 169 struct dd_state *dsa; 170 struct dd_state *blend; 171 172 struct pipe_blend_color blend_color; 173 struct pipe_stencil_ref stencil_ref; 174 unsigned sample_mask; 175 unsigned min_samples; 176 struct pipe_clip_state clip_state; 177 struct pipe_framebuffer_state framebuffer_state; 178 struct pipe_poly_stipple polygon_stipple; 179 struct pipe_scissor_state scissors[PIPE_MAX_VIEWPORTS]; 180 struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS]; 181 float tess_default_levels[6]; 182 183 unsigned apitrace_call_number; 184}; 185 186struct dd_draw_state_copy 187{ 188 struct dd_draw_state base; 189 190 /* dd_draw_state_copy does not reference real CSOs. Instead, it points to 191 * these variables, which serve as storage. 192 */ 193 struct dd_query render_cond; 194 struct dd_state shaders[PIPE_SHADER_TYPES]; 195 struct dd_state sampler_states[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; 196 struct dd_state velems; 197 struct dd_state rs; 198 struct dd_state dsa; 199 struct dd_state blend; 200}; 201 202struct dd_draw_record { 203 struct dd_draw_record *next; 204 205 int64_t timestamp; 206 uint32_t sequence_no; 207 208 struct dd_call call; 209 struct dd_draw_state_copy draw_state; 210 char *driver_state_log; 211}; 212 213struct dd_context 214{ 215 struct pipe_context base; 216 struct pipe_context *pipe; 217 218 struct dd_draw_state draw_state; 219 unsigned num_draw_calls; 220 221 /* Pipelined hang detection. 222 * 223 * This is without unnecessary flushes and waits. There is a memory-based 224 * fence that is incremented by clear_buffer every draw call. Driver fences 225 * are not used. 226 * 227 * After each draw call, a new dd_draw_record is created that contains 228 * a copy of all states, the output of pipe_context::dump_debug_state, 229 * and it has a fence number assigned. That's done without knowing whether 230 * that draw call is problematic or not. The record is added into the list 231 * of all records. 232 * 233 * An independent, separate thread loops over the list of records and checks 234 * their fences. Records with signalled fences are freed. On fence timeout, 235 * the thread dumps the record of the oldest unsignalled fence. 236 */ 237 pipe_thread thread; 238 pipe_mutex mutex; 239 int kill_thread; 240 struct pipe_resource *fence; 241 struct pipe_transfer *fence_transfer; 242 uint32_t *mapped_fence; 243 uint32_t sequence_no; 244 struct dd_draw_record *records; 245 int max_log_buffer_size; 246}; 247 248 249struct pipe_context * 250dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe); 251 252void 253dd_init_draw_functions(struct dd_context *dctx); 254PIPE_THREAD_ROUTINE(dd_thread_pipelined_hang_detect, input); 255 256 257static inline struct dd_context * 258dd_context(struct pipe_context *pipe) 259{ 260 return (struct dd_context *)pipe; 261} 262 263static inline struct dd_screen * 264dd_screen(struct pipe_screen *screen) 265{ 266 return (struct dd_screen*)screen; 267} 268 269 270#define CTX_INIT(_member) \ 271 dctx->base._member = dctx->pipe->_member ? dd_context_##_member : NULL 272 273#endif /* DD_H_ */ 274