radeonsi_pipe.h revision 82cd9c0fc2838a153006a646b0d356ed54b8680e
1/* 2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: 24 * Jerome Glisse 25 */ 26#ifndef RADEONSI_PIPE_H 27#define RADEONSI_PIPE_H 28 29#include "../../winsys/radeon/drm/radeon_winsys.h" 30 31#include "pipe/p_state.h" 32#include "pipe/p_screen.h" 33#include "pipe/p_context.h" 34#include "util/u_format.h" 35#include "util/u_math.h" 36#include "util/u_slab.h" 37#include "r600.h" 38#include "radeonsi_public.h" 39#include "radeonsi_pm4.h" 40#include "si_state.h" 41#include "r600_resource.h" 42#include "sid.h" 43 44#define R600_MAX_CONST_BUFFERS 1 45#define R600_MAX_CONST_BUFFER_SIZE 4096 46 47#ifdef PIPE_ARCH_BIG_ENDIAN 48#define R600_BIG_ENDIAN 1 49#else 50#define R600_BIG_ENDIAN 0 51#endif 52 53enum r600_atom_flags { 54 /* When set, atoms are added at the beginning of the dirty list 55 * instead of the end. */ 56 EMIT_EARLY = (1 << 0) 57}; 58 59/* This encapsulates a state or an operation which can emitted into the GPU 60 * command stream. It's not limited to states only, it can be used for anything 61 * that wants to write commands into the CS (e.g. cache flushes). */ 62struct r600_atom { 63 void (*emit)(struct r600_context *ctx, struct r600_atom *state); 64 65 unsigned num_dw; 66 enum r600_atom_flags flags; 67 bool dirty; 68 69 struct list_head head; 70}; 71 72struct r600_atom_surface_sync { 73 struct r600_atom atom; 74 unsigned flush_flags; /* CP_COHER_CNTL */ 75}; 76 77struct r600_pipe_fences { 78 struct si_resource *bo; 79 unsigned *data; 80 unsigned next_index; 81 /* linked list of preallocated blocks */ 82 struct list_head blocks; 83 /* linked list of freed fences */ 84 struct list_head pool; 85 pipe_mutex mutex; 86}; 87 88struct r600_screen { 89 struct pipe_screen screen; 90 struct radeon_winsys *ws; 91 unsigned family; 92 enum chip_class chip_class; 93 struct radeon_info info; 94 struct r600_tiling_info tiling_info; 95 struct util_slab_mempool pool_buffers; 96 struct r600_pipe_fences fences; 97}; 98 99struct si_pipe_sampler_view { 100 struct pipe_sampler_view base; 101 uint32_t state[8]; 102}; 103 104struct si_pipe_sampler_state { 105 uint32_t val[4]; 106}; 107 108/* needed for blitter save */ 109#define NUM_TEX_UNITS 16 110 111struct r600_textures_info { 112 struct si_pipe_sampler_view *views[NUM_TEX_UNITS]; 113 struct si_pipe_sampler_state *samplers[NUM_TEX_UNITS]; 114 unsigned n_views; 115 unsigned n_samplers; 116 bool samplers_dirty; 117 bool is_array_sampler[NUM_TEX_UNITS]; 118}; 119 120struct r600_fence { 121 struct pipe_reference reference; 122 unsigned index; /* in the shared bo */ 123 struct si_resource *sleep_bo; 124 struct list_head head; 125}; 126 127#define FENCE_BLOCK_SIZE 16 128 129struct r600_fence_block { 130 struct r600_fence fences[FENCE_BLOCK_SIZE]; 131 struct list_head head; 132}; 133 134#define R600_CONSTANT_ARRAY_SIZE 256 135#define R600_RESOURCE_ARRAY_SIZE 160 136 137struct r600_context { 138 struct pipe_context context; 139 struct blitter_context *blitter; 140 enum radeon_family family; 141 enum chip_class chip_class; 142 void *custom_dsa_flush; 143 struct r600_screen *screen; 144 struct radeon_winsys *ws; 145 struct si_vertex_element *vertex_elements; 146 struct pipe_framebuffer_state framebuffer; 147 unsigned pa_sc_line_stipple; 148 unsigned pa_su_sc_mode_cntl; 149 unsigned pa_cl_clip_cntl; 150 unsigned pa_cl_vs_out_cntl; 151 /* for saving when using blitter */ 152 struct pipe_stencil_ref stencil_ref; 153 struct si_pipe_shader *ps_shader; 154 struct si_pipe_shader *vs_shader; 155 struct pipe_query *current_render_cond; 156 unsigned current_render_cond_mode; 157 struct pipe_query *saved_render_cond; 158 unsigned saved_render_cond_mode; 159 /* shader information */ 160 unsigned sprite_coord_enable; 161 boolean export_16bpc; 162 unsigned alpha_ref; 163 boolean alpha_ref_dirty; 164 struct r600_textures_info vs_samplers; 165 struct r600_textures_info ps_samplers; 166 boolean shader_dirty; 167 168 struct u_upload_mgr *uploader; 169 struct util_slab_mempool pool_transfers; 170 boolean have_depth_texture, have_depth_fb; 171 172 unsigned default_ps_gprs, default_vs_gprs; 173 174 /* States based on r600_state. */ 175 struct list_head dirty_states; 176 struct r600_atom_surface_sync atom_surface_sync; 177 struct r600_atom atom_r6xx_flush_and_inv; 178 179 /* Below are variables from the old r600_context. 180 */ 181 struct radeon_winsys_cs *cs; 182 183 unsigned pm4_dirty_cdwords; 184 unsigned init_dwords; 185 186 /* The list of active queries. Only one query of each type can be active. */ 187 struct list_head active_query_list; 188 unsigned num_cs_dw_queries_suspend; 189 unsigned num_cs_dw_streamout_end; 190 191 unsigned backend_mask; 192 unsigned max_db; /* for OQ */ 193 unsigned flags; 194 boolean predicate_drawing; 195 196 unsigned num_so_targets; 197 struct r600_so_target *so_targets[PIPE_MAX_SO_BUFFERS]; 198 boolean streamout_start; 199 unsigned streamout_append_bitmask; 200 unsigned *vs_so_stride_in_dw; 201 unsigned *vs_shader_so_strides; 202 203 /* Vertex and index buffers. */ 204 bool vertex_buffers_dirty; 205 struct pipe_index_buffer index_buffer; 206 struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; 207 unsigned nr_vertex_buffers; 208 209 /* With rasterizer discard, there doesn't have to be a pixel shader. 210 * In that case, we bind this one: */ 211 struct si_pipe_shader *dummy_pixel_shader; 212 213 /* SI state handling */ 214 union si_state queued; 215 union si_state emitted; 216}; 217 218static INLINE void r600_emit_atom(struct r600_context *rctx, struct r600_atom *atom) 219{ 220 atom->emit(rctx, atom); 221 atom->dirty = false; 222 if (atom->head.next && atom->head.prev) 223 LIST_DELINIT(&atom->head); 224} 225 226static INLINE void r600_atom_dirty(struct r600_context *rctx, struct r600_atom *state) 227{ 228 if (!state->dirty) { 229 if (state->flags & EMIT_EARLY) { 230 LIST_ADD(&state->head, &rctx->dirty_states); 231 } else { 232 LIST_ADDTAIL(&state->head, &rctx->dirty_states); 233 } 234 state->dirty = true; 235 } 236} 237 238/* r600_blit.c */ 239void r600_init_blit_functions(struct r600_context *rctx); 240void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *texture); 241void r600_blit_push_depth(struct pipe_context *ctx, struct r600_resource_texture *texture); 242void r600_flush_depth_textures(struct r600_context *rctx); 243 244/* r600_buffer.c */ 245bool r600_init_resource(struct r600_screen *rscreen, 246 struct si_resource *res, 247 unsigned size, unsigned alignment, 248 unsigned bind, unsigned usage); 249struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, 250 const struct pipe_resource *templ); 251void r600_upload_index_buffer(struct r600_context *rctx, 252 struct pipe_index_buffer *ib, unsigned count); 253 254 255/* r600_pipe.c */ 256void radeonsi_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence, 257 unsigned flags); 258 259/* r600_query.c */ 260void r600_init_query_functions(struct r600_context *rctx); 261 262/* r600_resource.c */ 263void r600_init_context_resource_functions(struct r600_context *r600); 264 265/* radeonsi_shader.c */ 266int si_pipe_shader_create(struct pipe_context *ctx, struct si_pipe_shader *shader); 267void si_pipe_shader_destroy(struct pipe_context *ctx, struct si_pipe_shader *shader); 268 269/* r600_texture.c */ 270void r600_init_screen_texture_functions(struct pipe_screen *screen); 271void r600_init_surface_functions(struct r600_context *r600); 272unsigned r600_texture_get_offset(struct r600_resource_texture *rtex, 273 unsigned level, unsigned layer); 274 275/* r600_translate.c */ 276void r600_translate_index_buffer(struct r600_context *r600, 277 struct pipe_index_buffer *ib, 278 unsigned count); 279 280/* r600_state_common.c */ 281void r600_init_common_atoms(struct r600_context *rctx); 282unsigned r600_get_cb_flush_flags(struct r600_context *rctx); 283 284/* 285 * common helpers 286 */ 287static INLINE uint32_t S_FIXED(float value, uint32_t frac_bits) 288{ 289 return value * (1 << frac_bits); 290} 291#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y)) 292 293static INLINE unsigned si_map_swizzle(unsigned swizzle) 294{ 295 switch (swizzle) { 296 case UTIL_FORMAT_SWIZZLE_Y: 297 return V_008F0C_SQ_SEL_Y; 298 case UTIL_FORMAT_SWIZZLE_Z: 299 return V_008F0C_SQ_SEL_Z; 300 case UTIL_FORMAT_SWIZZLE_W: 301 return V_008F0C_SQ_SEL_W; 302 case UTIL_FORMAT_SWIZZLE_0: 303 return V_008F0C_SQ_SEL_0; 304 case UTIL_FORMAT_SWIZZLE_1: 305 return V_008F0C_SQ_SEL_1; 306 default: /* UTIL_FORMAT_SWIZZLE_X */ 307 return V_008F0C_SQ_SEL_X; 308 } 309} 310 311static inline unsigned r600_tex_aniso_filter(unsigned filter) 312{ 313 if (filter <= 1) return 0; 314 if (filter <= 2) return 1; 315 if (filter <= 4) return 2; 316 if (filter <= 8) return 3; 317 /* else */ return 4; 318} 319 320/* 12.4 fixed-point */ 321static INLINE unsigned r600_pack_float_12p4(float x) 322{ 323 return x <= 0 ? 0 : 324 x >= 4096 ? 0xffff : x * 16; 325} 326 327static INLINE uint64_t r600_resource_va(struct pipe_screen *screen, struct pipe_resource *resource) 328{ 329 struct r600_screen *rscreen = (struct r600_screen*)screen; 330 struct si_resource *rresource = (struct si_resource*)resource; 331 332 return rscreen->ws->buffer_get_virtual_address(rresource->cs_buf); 333} 334 335#endif 336