r600_pipe.h revision f71f5edf78572ae87b9efb897df49efab1a53558
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 R600_PIPE_H 27#define R600_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_math.h" 35#include "util/u_slab.h" 36#include "util/u_vbuf.h" 37#include "r600.h" 38#include "r600_public.h" 39#include "r600_shader.h" 40#include "r600_resource.h" 41 42#define R600_MAX_CONST_BUFFERS 2 43#define R600_MAX_CONST_BUFFER_SIZE 4096 44 45#ifdef PIPE_ARCH_BIG_ENDIAN 46#define R600_BIG_ENDIAN 1 47#else 48#define R600_BIG_ENDIAN 0 49#endif 50 51enum r600_atom_flags { 52 /* When set, atoms are added at the beginning of the dirty list 53 * instead of the end. */ 54 EMIT_EARLY = (1 << 0) 55}; 56 57/* This encapsulates a state or an operation which can emitted into the GPU 58 * command stream. It's not limited to states only, it can be used for anything 59 * that wants to write commands into the CS (e.g. cache flushes). */ 60struct r600_atom { 61 void (*emit)(struct r600_context *ctx, struct r600_atom *state); 62 63 unsigned num_dw; 64 enum r600_atom_flags flags; 65 bool dirty; 66 67 struct list_head head; 68}; 69 70/* This is an atom containing GPU commands that never change. 71 * This is supposed to be copied directly into the CS. */ 72struct r600_command_buffer { 73 struct r600_atom atom; 74 uint32_t *buf; 75 unsigned max_num_dw; 76}; 77 78struct r600_atom_surface_sync { 79 struct r600_atom atom; 80 unsigned flush_flags; /* CP_COHER_CNTL */ 81}; 82 83struct r600_atom_db_misc_state { 84 struct r600_atom atom; 85 bool occlusion_query_enabled; 86 bool flush_depthstencil_enabled; 87}; 88 89struct r600_atom_eg_strmout_config { 90 struct r600_atom atom; 91 bool rasterizer_discard; 92 bool stream0_enable; 93}; 94 95enum r600_pipe_state_id { 96 R600_PIPE_STATE_BLEND = 0, 97 R600_PIPE_STATE_BLEND_COLOR, 98 R600_PIPE_STATE_CONFIG, 99 R600_PIPE_STATE_SEAMLESS_CUBEMAP, 100 R600_PIPE_STATE_CLIP, 101 R600_PIPE_STATE_SCISSOR, 102 R600_PIPE_STATE_VIEWPORT, 103 R600_PIPE_STATE_RASTERIZER, 104 R600_PIPE_STATE_VGT, 105 R600_PIPE_STATE_FRAMEBUFFER, 106 R600_PIPE_STATE_DSA, 107 R600_PIPE_STATE_STENCIL_REF, 108 R600_PIPE_STATE_PS_SHADER, 109 R600_PIPE_STATE_VS_SHADER, 110 R600_PIPE_STATE_CONSTANT, 111 R600_PIPE_STATE_SAMPLER, 112 R600_PIPE_STATE_RESOURCE, 113 R600_PIPE_STATE_POLYGON_OFFSET, 114 R600_PIPE_STATE_FETCH_SHADER, 115 R600_PIPE_NSTATES 116}; 117 118struct r600_pipe_fences { 119 struct r600_resource *bo; 120 unsigned *data; 121 unsigned next_index; 122 /* linked list of preallocated blocks */ 123 struct list_head blocks; 124 /* linked list of freed fences */ 125 struct list_head pool; 126 pipe_mutex mutex; 127}; 128 129struct r600_screen { 130 struct pipe_screen screen; 131 struct radeon_winsys *ws; 132 unsigned family; 133 enum chip_class chip_class; 134 struct radeon_info info; 135 struct r600_tiling_info tiling_info; 136 struct util_slab_mempool pool_buffers; 137 struct r600_pipe_fences fences; 138 139 unsigned num_contexts; 140 bool use_surface_alloc; 141 142 /* for thread-safe write accessing to num_contexts */ 143 pipe_mutex mutex_num_contexts; 144}; 145 146struct r600_pipe_sampler_view { 147 struct pipe_sampler_view base; 148 struct r600_pipe_resource_state state; 149}; 150 151struct r600_pipe_rasterizer { 152 struct r600_pipe_state rstate; 153 boolean flatshade; 154 boolean two_side; 155 unsigned sprite_coord_enable; 156 unsigned clip_plane_enable; 157 unsigned pa_sc_line_stipple; 158 unsigned pa_cl_clip_cntl; 159 float offset_units; 160 float offset_scale; 161 bool scissor_enable; 162 bool rasterizer_discard; 163}; 164 165struct r600_pipe_blend { 166 struct r600_pipe_state rstate; 167 unsigned cb_target_mask; 168 unsigned cb_color_control; 169}; 170 171struct r600_pipe_dsa { 172 struct r600_pipe_state rstate; 173 unsigned alpha_ref; 174 ubyte valuemask[2]; 175 ubyte writemask[2]; 176 bool is_flush; 177}; 178 179struct r600_vertex_element 180{ 181 unsigned count; 182 struct pipe_vertex_element elements[PIPE_MAX_ATTRIBS]; 183 struct u_vbuf_elements *vmgr_elements; 184 struct r600_resource *fetch_shader; 185 unsigned fs_size; 186 struct r600_pipe_state rstate; 187 /* if offset is to big for fetch instructio we need to alterate 188 * offset of vertex buffer, record here the offset need to add 189 */ 190 unsigned vbuffer_need_offset; 191 unsigned vbuffer_offset[PIPE_MAX_ATTRIBS]; 192}; 193 194struct r600_pipe_shader { 195 struct r600_shader shader; 196 struct r600_pipe_state rstate; 197 struct r600_resource *bo; 198 struct r600_resource *bo_fetch; 199 struct r600_vertex_element vertex_elements; 200 struct tgsi_token *tokens; 201 unsigned sprite_coord_enable; 202 unsigned flatshade; 203 unsigned pa_cl_vs_out_cntl; 204 struct pipe_stream_output_info so; 205}; 206 207struct r600_pipe_sampler_state { 208 struct r600_pipe_state rstate; 209 boolean seamless_cube_map; 210}; 211 212/* needed for blitter save */ 213#define NUM_TEX_UNITS 16 214 215struct r600_textures_info { 216 struct r600_pipe_sampler_view *views[NUM_TEX_UNITS]; 217 struct r600_pipe_sampler_state *samplers[NUM_TEX_UNITS]; 218 unsigned n_views; 219 unsigned n_samplers; 220 bool samplers_dirty; 221 bool is_array_sampler[NUM_TEX_UNITS]; 222}; 223 224struct r600_fence { 225 struct pipe_reference reference; 226 unsigned index; /* in the shared bo */ 227 struct r600_resource *sleep_bo; 228 struct list_head head; 229}; 230 231#define FENCE_BLOCK_SIZE 16 232 233struct r600_fence_block { 234 struct r600_fence fences[FENCE_BLOCK_SIZE]; 235 struct list_head head; 236}; 237 238#define R600_CONSTANT_ARRAY_SIZE 256 239#define R600_RESOURCE_ARRAY_SIZE 160 240 241struct r600_stencil_ref 242{ 243 ubyte ref_value[2]; 244 ubyte valuemask[2]; 245 ubyte writemask[2]; 246}; 247 248struct r600_context { 249 struct pipe_context context; 250 struct blitter_context *blitter; 251 enum radeon_family family; 252 enum chip_class chip_class; 253 unsigned r6xx_num_clause_temp_gprs; 254 void *custom_dsa_flush; 255 struct r600_screen *screen; 256 struct radeon_winsys *ws; 257 struct r600_pipe_state *states[R600_PIPE_NSTATES]; 258 struct r600_vertex_element *vertex_elements; 259 struct r600_pipe_resource_state fs_resource[PIPE_MAX_ATTRIBS]; 260 struct pipe_framebuffer_state framebuffer; 261 unsigned cb_target_mask; 262 unsigned cb_color_control; 263 unsigned pa_sc_line_stipple; 264 unsigned pa_cl_clip_cntl; 265 /* for saving when using blitter */ 266 struct pipe_stencil_ref stencil_ref; 267 struct pipe_viewport_state viewport; 268 struct pipe_clip_state clip; 269 struct r600_pipe_shader *ps_shader; 270 struct r600_pipe_shader *vs_shader; 271 struct r600_pipe_state vs_const_buffer; 272 struct r600_pipe_resource_state vs_const_buffer_resource[R600_MAX_CONST_BUFFERS]; 273 struct r600_pipe_state ps_const_buffer; 274 struct r600_pipe_resource_state ps_const_buffer_resource[R600_MAX_CONST_BUFFERS]; 275 struct r600_pipe_rasterizer *rasterizer; 276 struct r600_pipe_state vgt; 277 struct r600_pipe_state spi; 278 struct pipe_query *current_render_cond; 279 unsigned current_render_cond_mode; 280 struct pipe_query *saved_render_cond; 281 unsigned saved_render_cond_mode; 282 /* shader information */ 283 boolean two_side; 284 unsigned sprite_coord_enable; 285 boolean export_16bpc; 286 unsigned alpha_ref; 287 boolean alpha_ref_dirty; 288 unsigned nr_cbufs; 289 struct r600_textures_info vs_samplers; 290 struct r600_textures_info ps_samplers; 291 292 struct u_vbuf *vbuf_mgr; 293 struct util_slab_mempool pool_transfers; 294 boolean have_depth_texture, have_depth_fb; 295 296 unsigned default_ps_gprs, default_vs_gprs; 297 298 /* States based on r600_state. */ 299 struct list_head dirty_states; 300 struct r600_command_buffer atom_start_cs; /* invariant state mostly */ 301 struct r600_atom_surface_sync atom_surface_sync; 302 struct r600_atom atom_r6xx_flush_and_inv; 303 struct r600_atom_db_misc_state atom_db_misc_state; 304 struct r600_atom_eg_strmout_config atom_eg_strmout_config; 305 306 /* Below are variables from the old r600_context. 307 */ 308 struct radeon_winsys_cs *cs; 309 310 struct r600_range *range; 311 unsigned nblocks; 312 struct r600_block **blocks; 313 struct list_head dirty; 314 struct list_head resource_dirty; 315 struct list_head enable_list; 316 unsigned pm4_dirty_cdwords; 317 unsigned ctx_pm4_ndwords; 318 319 /* The list of active queries. Only one query of each type can be active. */ 320 int num_occlusion_queries; 321 322 /* Manage queries in two separate groups: 323 * The timer ones and the others (streamout, occlusion). 324 * 325 * We do this because we should only suspend non-timer queries for u_blitter, 326 * and later if the non-timer queries are suspended, the context flush should 327 * only suspend and resume the timer queries. */ 328 struct list_head active_timer_queries; 329 unsigned num_cs_dw_timer_queries_suspend; 330 struct list_head active_nontimer_queries; 331 unsigned num_cs_dw_nontimer_queries_suspend; 332 333 unsigned num_cs_dw_streamout_end; 334 335 unsigned backend_mask; 336 unsigned max_db; /* for OQ */ 337 unsigned flags; 338 boolean predicate_drawing; 339 struct r600_range ps_resources; 340 struct r600_range vs_resources; 341 struct r600_range fs_resources; 342 int num_ps_resources, num_vs_resources, num_fs_resources; 343 344 unsigned num_so_targets; 345 struct r600_so_target *so_targets[PIPE_MAX_SO_BUFFERS]; 346 boolean streamout_start; 347 unsigned streamout_append_bitmask; 348 349 /* There is no scissor enable bit on r6xx, so we must use a workaround. 350 * These track the current scissor state. */ 351 bool scissor_enable; 352 struct pipe_scissor_state scissor_state; 353 354 /* With rasterizer discard, there doesn't have to be a pixel shader. 355 * In that case, we bind this one: */ 356 void *dummy_pixel_shader; 357}; 358 359static INLINE void r600_emit_atom(struct r600_context *rctx, struct r600_atom *atom) 360{ 361 atom->emit(rctx, atom); 362 atom->dirty = false; 363 if (atom->head.next && atom->head.prev) 364 LIST_DELINIT(&atom->head); 365} 366 367static INLINE void r600_atom_dirty(struct r600_context *rctx, struct r600_atom *state) 368{ 369 if (!state->dirty) { 370 if (state->flags & EMIT_EARLY) { 371 LIST_ADD(&state->head, &rctx->dirty_states); 372 } else { 373 LIST_ADDTAIL(&state->head, &rctx->dirty_states); 374 } 375 state->dirty = true; 376 } 377} 378 379/* evergreen_state.c */ 380void evergreen_init_state_functions(struct r600_context *rctx); 381void evergreen_init_atom_start_cs(struct r600_context *rctx); 382void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); 383void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader); 384void evergreen_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element *ve); 385void *evergreen_create_db_flush_dsa(struct r600_context *rctx); 386void evergreen_polygon_offset_update(struct r600_context *rctx); 387void evergreen_pipe_init_buffer_resource(struct r600_context *rctx, 388 struct r600_pipe_resource_state *rstate); 389void evergreen_pipe_mod_buffer_resource(struct pipe_context *ctx, 390 struct r600_pipe_resource_state *rstate, 391 struct r600_resource *rbuffer, 392 unsigned offset, unsigned stride, 393 enum radeon_bo_usage usage); 394boolean evergreen_is_format_supported(struct pipe_screen *screen, 395 enum pipe_format format, 396 enum pipe_texture_target target, 397 unsigned sample_count, 398 unsigned usage); 399void evergreen_set_rasterizer_discard(struct pipe_context *ctx, boolean discard); 400 401/* r600_blit.c */ 402void r600_init_blit_functions(struct r600_context *rctx); 403void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *texture); 404void r600_blit_push_depth(struct pipe_context *ctx, struct r600_resource_texture *texture); 405void r600_flush_depth_textures(struct r600_context *rctx); 406 407/* r600_buffer.c */ 408bool r600_init_resource(struct r600_screen *rscreen, 409 struct r600_resource *res, 410 unsigned size, unsigned alignment, 411 unsigned bind, unsigned usage); 412struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, 413 const struct pipe_resource *templ); 414struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, 415 void *ptr, unsigned bytes, 416 unsigned bind); 417void r600_upload_index_buffer(struct r600_context *rctx, 418 struct pipe_index_buffer *ib, unsigned count); 419 420 421/* r600_pipe.c */ 422void r600_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence, 423 unsigned flags); 424 425/* r600_query.c */ 426void r600_init_query_functions(struct r600_context *rctx); 427void r600_suspend_nontimer_queries(struct r600_context *ctx); 428void r600_resume_nontimer_queries(struct r600_context *ctx); 429void r600_suspend_timer_queries(struct r600_context *ctx); 430void r600_resume_timer_queries(struct r600_context *ctx); 431 432/* r600_resource.c */ 433void r600_init_context_resource_functions(struct r600_context *r600); 434 435/* r600_shader.c */ 436int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader); 437void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *shader); 438int r600_find_vs_semantic_index(struct r600_shader *vs, 439 struct r600_shader *ps, int id); 440 441/* r600_state.c */ 442void r600_set_scissor_state(struct r600_context *rctx, 443 const struct pipe_scissor_state *state); 444void r600_update_sampler_states(struct r600_context *rctx); 445void r600_init_state_functions(struct r600_context *rctx); 446void r600_init_atom_start_cs(struct r600_context *rctx); 447void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); 448void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader); 449void r600_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element *ve); 450void *r600_create_db_flush_dsa(struct r600_context *rctx); 451void r600_polygon_offset_update(struct r600_context *rctx); 452void r600_pipe_init_buffer_resource(struct r600_context *rctx, 453 struct r600_pipe_resource_state *rstate); 454void r600_pipe_mod_buffer_resource(struct r600_pipe_resource_state *rstate, 455 struct r600_resource *rbuffer, 456 unsigned offset, unsigned stride, 457 enum radeon_bo_usage usage); 458void r600_adjust_gprs(struct r600_context *rctx); 459boolean r600_is_format_supported(struct pipe_screen *screen, 460 enum pipe_format format, 461 enum pipe_texture_target target, 462 unsigned sample_count, 463 unsigned usage); 464 465/* r600_texture.c */ 466void r600_init_screen_texture_functions(struct pipe_screen *screen); 467void r600_init_surface_functions(struct r600_context *r600); 468uint32_t r600_translate_texformat(struct pipe_screen *screen, enum pipe_format format, 469 const unsigned char *swizzle_view, 470 uint32_t *word4_p, uint32_t *yuv_format_p); 471unsigned r600_texture_get_offset(struct r600_resource_texture *rtex, 472 unsigned level, unsigned layer); 473 474/* r600_translate.c */ 475void r600_translate_index_buffer(struct r600_context *r600, 476 struct pipe_index_buffer *ib, 477 unsigned count); 478 479/* r600_state_common.c */ 480void r600_init_atom(struct r600_atom *atom, 481 void (*emit)(struct r600_context *ctx, struct r600_atom *state), 482 unsigned num_dw, enum r600_atom_flags flags); 483void r600_init_common_atoms(struct r600_context *rctx); 484unsigned r600_get_cb_flush_flags(struct r600_context *rctx); 485void r600_texture_barrier(struct pipe_context *ctx); 486void r600_set_index_buffer(struct pipe_context *ctx, 487 const struct pipe_index_buffer *ib); 488void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, 489 const struct pipe_vertex_buffer *buffers); 490void *r600_create_vertex_elements(struct pipe_context *ctx, 491 unsigned count, 492 const struct pipe_vertex_element *elements); 493void r600_delete_vertex_element(struct pipe_context *ctx, void *state); 494void r600_bind_blend_state(struct pipe_context *ctx, void *state); 495void r600_set_blend_color(struct pipe_context *ctx, 496 const struct pipe_blend_color *state); 497void r600_bind_dsa_state(struct pipe_context *ctx, void *state); 498void r600_set_max_scissor(struct r600_context *rctx); 499void r600_bind_rs_state(struct pipe_context *ctx, void *state); 500void r600_delete_rs_state(struct pipe_context *ctx, void *state); 501void r600_sampler_view_destroy(struct pipe_context *ctx, 502 struct pipe_sampler_view *state); 503void r600_delete_state(struct pipe_context *ctx, void *state); 504void r600_bind_vertex_elements(struct pipe_context *ctx, void *state); 505void *r600_create_shader_state(struct pipe_context *ctx, 506 const struct pipe_shader_state *state); 507void r600_bind_ps_shader(struct pipe_context *ctx, void *state); 508void r600_bind_vs_shader(struct pipe_context *ctx, void *state); 509void r600_delete_ps_shader(struct pipe_context *ctx, void *state); 510void r600_delete_vs_shader(struct pipe_context *ctx, void *state); 511void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, 512 struct pipe_resource *buffer); 513struct pipe_stream_output_target * 514r600_create_so_target(struct pipe_context *ctx, 515 struct pipe_resource *buffer, 516 unsigned buffer_offset, 517 unsigned buffer_size); 518void r600_so_target_destroy(struct pipe_context *ctx, 519 struct pipe_stream_output_target *target); 520void r600_set_so_targets(struct pipe_context *ctx, 521 unsigned num_targets, 522 struct pipe_stream_output_target **targets, 523 unsigned append_bitmask); 524void r600_set_pipe_stencil_ref(struct pipe_context *ctx, 525 const struct pipe_stencil_ref *state); 526void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info); 527uint32_t r600_translate_stencil_op(int s_op); 528uint32_t r600_translate_fill(uint32_t func); 529unsigned r600_tex_wrap(unsigned wrap); 530unsigned r600_tex_filter(unsigned filter); 531unsigned r600_tex_mipfilter(unsigned filter); 532unsigned r600_tex_compare(unsigned compare); 533 534/* 535 * Helpers for building command buffers 536 */ 537 538#define PKT3_SET_CONFIG_REG 0x68 539#define PKT3_SET_CONTEXT_REG 0x69 540#define PKT3_SET_CTL_CONST 0x6F 541#define PKT3_SET_LOOP_CONST 0x6C 542 543#define R600_CONFIG_REG_OFFSET 0x08000 544#define R600_CONTEXT_REG_OFFSET 0x28000 545#define R600_CTL_CONST_OFFSET 0x3CFF0 546#define R600_LOOP_CONST_OFFSET 0X0003E200 547#define EG_LOOP_CONST_OFFSET 0x0003A200 548 549#define PKT_TYPE_S(x) (((x) & 0x3) << 30) 550#define PKT_COUNT_S(x) (((x) & 0x3FFF) << 16) 551#define PKT3_IT_OPCODE_S(x) (((x) & 0xFF) << 8) 552#define PKT3_PREDICATE(x) (((x) >> 0) & 0x1) 553#define PKT3(op, count, predicate) (PKT_TYPE_S(3) | PKT_COUNT_S(count) | PKT3_IT_OPCODE_S(op) | PKT3_PREDICATE(predicate)) 554 555static INLINE void r600_store_value(struct r600_command_buffer *cb, unsigned value) 556{ 557 cb->buf[cb->atom.num_dw++] = value; 558} 559 560static INLINE void r600_store_config_reg_seq(struct r600_command_buffer *cb, unsigned reg, unsigned num) 561{ 562 assert(reg < R600_CONTEXT_REG_OFFSET); 563 assert(cb->atom.num_dw+2+num <= cb->max_num_dw); 564 cb->buf[cb->atom.num_dw++] = PKT3(PKT3_SET_CONFIG_REG, num, 0); 565 cb->buf[cb->atom.num_dw++] = (reg - R600_CONFIG_REG_OFFSET) >> 2; 566} 567 568static INLINE void r600_store_context_reg_seq(struct r600_command_buffer *cb, unsigned reg, unsigned num) 569{ 570 assert(reg >= R600_CONTEXT_REG_OFFSET && reg < R600_CTL_CONST_OFFSET); 571 assert(cb->atom.num_dw+2+num <= cb->max_num_dw); 572 cb->buf[cb->atom.num_dw++] = PKT3(PKT3_SET_CONTEXT_REG, num, 0); 573 cb->buf[cb->atom.num_dw++] = (reg - R600_CONTEXT_REG_OFFSET) >> 2; 574} 575 576static INLINE void r600_store_ctl_const_seq(struct r600_command_buffer *cb, unsigned reg, unsigned num) 577{ 578 assert(reg >= R600_CTL_CONST_OFFSET); 579 assert(cb->atom.num_dw+2+num <= cb->max_num_dw); 580 cb->buf[cb->atom.num_dw++] = PKT3(PKT3_SET_CTL_CONST, num, 0); 581 cb->buf[cb->atom.num_dw++] = (reg - R600_CTL_CONST_OFFSET) >> 2; 582} 583 584static INLINE void r600_store_loop_const_seq(struct r600_command_buffer *cb, unsigned reg, unsigned num) 585{ 586 assert(reg >= R600_LOOP_CONST_OFFSET); 587 assert(cb->atom.num_dw+2+num <= cb->max_num_dw); 588 cb->buf[cb->atom.num_dw++] = PKT3(PKT3_SET_LOOP_CONST, num, 0); 589 cb->buf[cb->atom.num_dw++] = (reg - R600_LOOP_CONST_OFFSET) >> 2; 590} 591 592static INLINE void eg_store_loop_const_seq(struct r600_command_buffer *cb, unsigned reg, unsigned num) 593{ 594 assert(reg >= EG_LOOP_CONST_OFFSET); 595 assert(cb->atom.num_dw+2+num <= cb->max_num_dw); 596 cb->buf[cb->atom.num_dw++] = PKT3(PKT3_SET_LOOP_CONST, num, 0); 597 cb->buf[cb->atom.num_dw++] = (reg - EG_LOOP_CONST_OFFSET) >> 2; 598} 599 600static INLINE void r600_store_config_reg(struct r600_command_buffer *cb, unsigned reg, unsigned value) 601{ 602 r600_store_config_reg_seq(cb, reg, 1); 603 r600_store_value(cb, value); 604} 605 606static INLINE void r600_store_context_reg(struct r600_command_buffer *cb, unsigned reg, unsigned value) 607{ 608 r600_store_context_reg_seq(cb, reg, 1); 609 r600_store_value(cb, value); 610} 611 612static INLINE void r600_store_ctl_const(struct r600_command_buffer *cb, unsigned reg, unsigned value) 613{ 614 r600_store_ctl_const_seq(cb, reg, 1); 615 r600_store_value(cb, value); 616} 617 618static INLINE void r600_store_loop_const(struct r600_command_buffer *cb, unsigned reg, unsigned value) 619{ 620 r600_store_loop_const_seq(cb, reg, 1); 621 r600_store_value(cb, value); 622} 623 624static INLINE void eg_store_loop_const(struct r600_command_buffer *cb, unsigned reg, unsigned value) 625{ 626 eg_store_loop_const_seq(cb, reg, 1); 627 r600_store_value(cb, value); 628} 629 630void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw, enum r600_atom_flags flags); 631void r600_release_command_buffer(struct r600_command_buffer *cb); 632 633/* 634 * Helpers for emitting state into a command stream directly. 635 */ 636 637static INLINE void r600_write_value(struct radeon_winsys_cs *cs, unsigned value) 638{ 639 cs->buf[cs->cdw++] = value; 640} 641 642static INLINE void r600_write_config_reg_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num) 643{ 644 assert(reg < R600_CONTEXT_REG_OFFSET); 645 assert(cs->cdw+2+num <= RADEON_MAX_CMDBUF_DWORDS); 646 cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONFIG_REG, num, 0); 647 cs->buf[cs->cdw++] = (reg - R600_CONFIG_REG_OFFSET) >> 2; 648} 649 650static INLINE void r600_write_context_reg_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num) 651{ 652 assert(reg >= R600_CONTEXT_REG_OFFSET && reg < R600_CTL_CONST_OFFSET); 653 assert(cs->cdw+2+num <= RADEON_MAX_CMDBUF_DWORDS); 654 cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONTEXT_REG, num, 0); 655 cs->buf[cs->cdw++] = (reg - R600_CONTEXT_REG_OFFSET) >> 2; 656} 657 658static INLINE void r600_write_ctl_const_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num) 659{ 660 assert(reg >= R600_CTL_CONST_OFFSET); 661 assert(cs->cdw+2+num <= RADEON_MAX_CMDBUF_DWORDS); 662 cs->buf[cs->cdw++] = PKT3(PKT3_SET_CTL_CONST, num, 0); 663 cs->buf[cs->cdw++] = (reg - R600_CTL_CONST_OFFSET) >> 2; 664} 665 666static INLINE void r600_write_config_reg(struct radeon_winsys_cs *cs, unsigned reg, unsigned value) 667{ 668 r600_write_config_reg_seq(cs, reg, 1); 669 r600_write_value(cs, value); 670} 671 672static INLINE void r600_write_context_reg(struct radeon_winsys_cs *cs, unsigned reg, unsigned value) 673{ 674 r600_write_context_reg_seq(cs, reg, 1); 675 r600_write_value(cs, value); 676} 677 678static INLINE void r600_write_ctl_const(struct radeon_winsys_cs *cs, unsigned reg, unsigned value) 679{ 680 r600_write_ctl_const_seq(cs, reg, 1); 681 r600_write_value(cs, value); 682} 683 684/* 685 * common helpers 686 */ 687static INLINE uint32_t S_FIXED(float value, uint32_t frac_bits) 688{ 689 return value * (1 << frac_bits); 690} 691#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y)) 692 693static inline unsigned r600_tex_aniso_filter(unsigned filter) 694{ 695 if (filter <= 1) return 0; 696 if (filter <= 2) return 1; 697 if (filter <= 4) return 2; 698 if (filter <= 8) return 3; 699 /* else */ return 4; 700} 701 702/* 12.4 fixed-point */ 703static INLINE unsigned r600_pack_float_12p4(float x) 704{ 705 return x <= 0 ? 0 : 706 x >= 4096 ? 0xffff : x * 16; 707} 708 709#endif 710