1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 8bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 9bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci#include "draw/draw_context.h" 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#include "util/u_memory.h" 26bf215546Sopenharmony_ci#include "util/u_sampler.h" 27bf215546Sopenharmony_ci#include "util/u_upload_mgr.h" 28bf215546Sopenharmony_ci#include "util/os_time.h" 29bf215546Sopenharmony_ci#include "vl/vl_decoder.h" 30bf215546Sopenharmony_ci#include "vl/vl_video_buffer.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "r300_cb.h" 33bf215546Sopenharmony_ci#include "r300_context.h" 34bf215546Sopenharmony_ci#include "r300_emit.h" 35bf215546Sopenharmony_ci#include "r300_screen.h" 36bf215546Sopenharmony_ci#include "r300_screen_buffer.h" 37bf215546Sopenharmony_ci#include "compiler/radeon_regalloc.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci#include <inttypes.h> 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_cistatic void r300_release_referenced_objects(struct r300_context *r300) 42bf215546Sopenharmony_ci{ 43bf215546Sopenharmony_ci struct pipe_framebuffer_state *fb = 44bf215546Sopenharmony_ci (struct pipe_framebuffer_state*)r300->fb_state.state; 45bf215546Sopenharmony_ci struct r300_textures_state *textures = 46bf215546Sopenharmony_ci (struct r300_textures_state*)r300->textures_state.state; 47bf215546Sopenharmony_ci unsigned i; 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci /* Framebuffer state. */ 50bf215546Sopenharmony_ci util_unreference_framebuffer_state(fb); 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci /* Textures. */ 53bf215546Sopenharmony_ci for (i = 0; i < textures->sampler_view_count; i++) 54bf215546Sopenharmony_ci pipe_sampler_view_reference( 55bf215546Sopenharmony_ci (struct pipe_sampler_view**)&textures->sampler_views[i], NULL); 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci /* The special dummy texture for texkill. */ 58bf215546Sopenharmony_ci if (r300->texkill_sampler) { 59bf215546Sopenharmony_ci pipe_sampler_view_reference( 60bf215546Sopenharmony_ci (struct pipe_sampler_view**)&r300->texkill_sampler, 61bf215546Sopenharmony_ci NULL); 62bf215546Sopenharmony_ci } 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci /* Manually-created vertex buffers. */ 65bf215546Sopenharmony_ci pipe_vertex_buffer_unreference(&r300->dummy_vb); 66bf215546Sopenharmony_ci pb_reference(&r300->vbo, NULL); 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci r300->context.delete_depth_stencil_alpha_state(&r300->context, 69bf215546Sopenharmony_ci r300->dsa_decompress_zmask); 70bf215546Sopenharmony_ci} 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_cistatic void r300_destroy_context(struct pipe_context* context) 73bf215546Sopenharmony_ci{ 74bf215546Sopenharmony_ci struct r300_context* r300 = r300_context(context); 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci if (r300->cs.priv && r300->hyperz_enabled) { 77bf215546Sopenharmony_ci r300->rws->cs_request_feature(&r300->cs, RADEON_FID_R300_HYPERZ_ACCESS, FALSE); 78bf215546Sopenharmony_ci } 79bf215546Sopenharmony_ci if (r300->cs.priv && r300->cmask_access) { 80bf215546Sopenharmony_ci r300->rws->cs_request_feature(&r300->cs, RADEON_FID_R300_CMASK_ACCESS, FALSE); 81bf215546Sopenharmony_ci } 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci if (r300->blitter) 84bf215546Sopenharmony_ci util_blitter_destroy(r300->blitter); 85bf215546Sopenharmony_ci if (r300->draw) 86bf215546Sopenharmony_ci draw_destroy(r300->draw); 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci if (r300->uploader) 89bf215546Sopenharmony_ci u_upload_destroy(r300->uploader); 90bf215546Sopenharmony_ci if (r300->context.stream_uploader) 91bf215546Sopenharmony_ci u_upload_destroy(r300->context.stream_uploader); 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci /* XXX: This function assumes r300->query_list was initialized */ 94bf215546Sopenharmony_ci r300_release_referenced_objects(r300); 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci r300->rws->cs_destroy(&r300->cs); 97bf215546Sopenharmony_ci if (r300->ctx) 98bf215546Sopenharmony_ci r300->rws->ctx_destroy(r300->ctx); 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci rc_destroy_regalloc_state(&r300->fs_regalloc_state); 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci /* XXX: No way to tell if this was initialized or not? */ 103bf215546Sopenharmony_ci slab_destroy_child(&r300->pool_transfers); 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci /* Free the structs allocated in r300_setup_atoms() */ 106bf215546Sopenharmony_ci if (r300->aa_state.state) { 107bf215546Sopenharmony_ci FREE(r300->aa_state.state); 108bf215546Sopenharmony_ci FREE(r300->blend_color_state.state); 109bf215546Sopenharmony_ci FREE(r300->clip_state.state); 110bf215546Sopenharmony_ci FREE(r300->fb_state.state); 111bf215546Sopenharmony_ci FREE(r300->gpu_flush.state); 112bf215546Sopenharmony_ci FREE(r300->hyperz_state.state); 113bf215546Sopenharmony_ci FREE(r300->invariant_state.state); 114bf215546Sopenharmony_ci FREE(r300->rs_block_state.state); 115bf215546Sopenharmony_ci FREE(r300->sample_mask.state); 116bf215546Sopenharmony_ci FREE(r300->scissor_state.state); 117bf215546Sopenharmony_ci FREE(r300->textures_state.state); 118bf215546Sopenharmony_ci FREE(r300->vap_invariant_state.state); 119bf215546Sopenharmony_ci FREE(r300->viewport_state.state); 120bf215546Sopenharmony_ci FREE(r300->ztop_state.state); 121bf215546Sopenharmony_ci FREE(r300->fs_constants.state); 122bf215546Sopenharmony_ci FREE(r300->vs_constants.state); 123bf215546Sopenharmony_ci if (!r300->screen->caps.has_tcl) { 124bf215546Sopenharmony_ci FREE(r300->vertex_stream_state.state); 125bf215546Sopenharmony_ci } 126bf215546Sopenharmony_ci } 127bf215546Sopenharmony_ci FREE(r300); 128bf215546Sopenharmony_ci} 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_cistatic void r300_flush_callback(void *data, unsigned flags, 131bf215546Sopenharmony_ci struct pipe_fence_handle **fence) 132bf215546Sopenharmony_ci{ 133bf215546Sopenharmony_ci struct r300_context* const cs_context_copy = data; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci r300_flush(&cs_context_copy->context, flags, fence); 136bf215546Sopenharmony_ci} 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci#define R300_INIT_ATOM(atomname, atomsize) \ 139bf215546Sopenharmony_ci do { \ 140bf215546Sopenharmony_ci r300->atomname.name = #atomname; \ 141bf215546Sopenharmony_ci r300->atomname.state = NULL; \ 142bf215546Sopenharmony_ci r300->atomname.size = atomsize; \ 143bf215546Sopenharmony_ci r300->atomname.emit = r300_emit_##atomname; \ 144bf215546Sopenharmony_ci r300->atomname.dirty = FALSE; \ 145bf215546Sopenharmony_ci } while (0) 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci#define R300_ALLOC_ATOM(atomname, statetype) \ 148bf215546Sopenharmony_cido { \ 149bf215546Sopenharmony_ci r300->atomname.state = CALLOC_STRUCT(statetype); \ 150bf215546Sopenharmony_ci if (r300->atomname.state == NULL) \ 151bf215546Sopenharmony_ci return FALSE; \ 152bf215546Sopenharmony_ci} while (0) 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_cistatic boolean r300_setup_atoms(struct r300_context* r300) 155bf215546Sopenharmony_ci{ 156bf215546Sopenharmony_ci boolean is_rv350 = r300->screen->caps.is_rv350; 157bf215546Sopenharmony_ci boolean is_r500 = r300->screen->caps.is_r500; 158bf215546Sopenharmony_ci boolean has_tcl = r300->screen->caps.has_tcl; 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci /* Create the actual atom list. 161bf215546Sopenharmony_ci * 162bf215546Sopenharmony_ci * Some atoms never change size, others change every emit - those have 163bf215546Sopenharmony_ci * the size of 0 here. 164bf215546Sopenharmony_ci * 165bf215546Sopenharmony_ci * NOTE: The framebuffer state is split into these atoms: 166bf215546Sopenharmony_ci * - gpu_flush (unpipelined regs) 167bf215546Sopenharmony_ci * - aa_state (unpipelined regs) 168bf215546Sopenharmony_ci * - fb_state (unpipelined regs) 169bf215546Sopenharmony_ci * - hyperz_state (unpipelined regs followed by pipelined ones) 170bf215546Sopenharmony_ci * - fb_state_pipelined (pipelined regs) 171bf215546Sopenharmony_ci * The motivation behind this is to be able to emit a strict 172bf215546Sopenharmony_ci * subset of the regs, and to have reasonable register ordering. */ 173bf215546Sopenharmony_ci /* SC, GB (unpipelined), RB3D (unpipelined), ZB (unpipelined). */ 174bf215546Sopenharmony_ci R300_INIT_ATOM(gpu_flush, 9); 175bf215546Sopenharmony_ci R300_INIT_ATOM(aa_state, 4); 176bf215546Sopenharmony_ci R300_INIT_ATOM(fb_state, 0); 177bf215546Sopenharmony_ci R300_INIT_ATOM(hyperz_state, is_r500 || is_rv350 ? 10 : 8); 178bf215546Sopenharmony_ci /* ZB (unpipelined), SC. */ 179bf215546Sopenharmony_ci R300_INIT_ATOM(ztop_state, 2); 180bf215546Sopenharmony_ci /* ZB, FG. */ 181bf215546Sopenharmony_ci R300_INIT_ATOM(dsa_state, is_r500 ? 10 : 6); 182bf215546Sopenharmony_ci /* RB3D. */ 183bf215546Sopenharmony_ci R300_INIT_ATOM(blend_state, 8); 184bf215546Sopenharmony_ci R300_INIT_ATOM(blend_color_state, is_r500 ? 3 : 2); 185bf215546Sopenharmony_ci /* SC. */ 186bf215546Sopenharmony_ci R300_INIT_ATOM(sample_mask, 2); 187bf215546Sopenharmony_ci R300_INIT_ATOM(scissor_state, 3); 188bf215546Sopenharmony_ci /* GB, FG, GA, SU, SC, RB3D. */ 189bf215546Sopenharmony_ci R300_INIT_ATOM(invariant_state, 14 + (is_rv350 ? 4 : 0) + (is_r500 ? 4 : 0)); 190bf215546Sopenharmony_ci /* VAP. */ 191bf215546Sopenharmony_ci R300_INIT_ATOM(viewport_state, 9); 192bf215546Sopenharmony_ci R300_INIT_ATOM(pvs_flush, 2); 193bf215546Sopenharmony_ci R300_INIT_ATOM(vap_invariant_state, is_r500 || !has_tcl ? 11 : 9); 194bf215546Sopenharmony_ci R300_INIT_ATOM(vertex_stream_state, 0); 195bf215546Sopenharmony_ci R300_INIT_ATOM(vs_state, 0); 196bf215546Sopenharmony_ci R300_INIT_ATOM(vs_constants, 0); 197bf215546Sopenharmony_ci R300_INIT_ATOM(clip_state, has_tcl ? 3 + (6 * 4) : 0); 198bf215546Sopenharmony_ci /* VAP, RS, GA, GB, SU, SC. */ 199bf215546Sopenharmony_ci R300_INIT_ATOM(rs_block_state, 0); 200bf215546Sopenharmony_ci R300_INIT_ATOM(rs_state, 0); 201bf215546Sopenharmony_ci /* SC, US. */ 202bf215546Sopenharmony_ci R300_INIT_ATOM(fb_state_pipelined, 8); 203bf215546Sopenharmony_ci /* US. */ 204bf215546Sopenharmony_ci R300_INIT_ATOM(fs, 0); 205bf215546Sopenharmony_ci R300_INIT_ATOM(fs_rc_constant_state, 0); 206bf215546Sopenharmony_ci R300_INIT_ATOM(fs_constants, 0); 207bf215546Sopenharmony_ci /* TX. */ 208bf215546Sopenharmony_ci R300_INIT_ATOM(texture_cache_inval, 2); 209bf215546Sopenharmony_ci R300_INIT_ATOM(textures_state, 0); 210bf215546Sopenharmony_ci /* Clear commands */ 211bf215546Sopenharmony_ci R300_INIT_ATOM(hiz_clear, r300->screen->caps.hiz_ram > 0 ? 4 : 0); 212bf215546Sopenharmony_ci R300_INIT_ATOM(zmask_clear, r300->screen->caps.zmask_ram > 0 ? 4 : 0); 213bf215546Sopenharmony_ci R300_INIT_ATOM(cmask_clear, 4); 214bf215546Sopenharmony_ci /* ZB (unpipelined), SU. */ 215bf215546Sopenharmony_ci R300_INIT_ATOM(query_start, 4); 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci /* Replace emission functions for r500. */ 218bf215546Sopenharmony_ci if (is_r500) { 219bf215546Sopenharmony_ci r300->fs.emit = r500_emit_fs; 220bf215546Sopenharmony_ci r300->fs_rc_constant_state.emit = r500_emit_fs_rc_constant_state; 221bf215546Sopenharmony_ci r300->fs_constants.emit = r500_emit_fs_constants; 222bf215546Sopenharmony_ci } 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci /* Some non-CSO atoms need explicit space to store the state locally. */ 225bf215546Sopenharmony_ci R300_ALLOC_ATOM(aa_state, r300_aa_state); 226bf215546Sopenharmony_ci R300_ALLOC_ATOM(blend_color_state, r300_blend_color_state); 227bf215546Sopenharmony_ci R300_ALLOC_ATOM(clip_state, r300_clip_state); 228bf215546Sopenharmony_ci R300_ALLOC_ATOM(hyperz_state, r300_hyperz_state); 229bf215546Sopenharmony_ci R300_ALLOC_ATOM(invariant_state, r300_invariant_state); 230bf215546Sopenharmony_ci R300_ALLOC_ATOM(textures_state, r300_textures_state); 231bf215546Sopenharmony_ci R300_ALLOC_ATOM(vap_invariant_state, r300_vap_invariant_state); 232bf215546Sopenharmony_ci R300_ALLOC_ATOM(viewport_state, r300_viewport_state); 233bf215546Sopenharmony_ci R300_ALLOC_ATOM(ztop_state, r300_ztop_state); 234bf215546Sopenharmony_ci R300_ALLOC_ATOM(fb_state, pipe_framebuffer_state); 235bf215546Sopenharmony_ci R300_ALLOC_ATOM(gpu_flush, pipe_framebuffer_state); 236bf215546Sopenharmony_ci r300->sample_mask.state = malloc(4); 237bf215546Sopenharmony_ci R300_ALLOC_ATOM(scissor_state, pipe_scissor_state); 238bf215546Sopenharmony_ci R300_ALLOC_ATOM(rs_block_state, r300_rs_block); 239bf215546Sopenharmony_ci R300_ALLOC_ATOM(fs_constants, r300_constant_buffer); 240bf215546Sopenharmony_ci R300_ALLOC_ATOM(vs_constants, r300_constant_buffer); 241bf215546Sopenharmony_ci if (!r300->screen->caps.has_tcl) { 242bf215546Sopenharmony_ci R300_ALLOC_ATOM(vertex_stream_state, r300_vertex_stream_state); 243bf215546Sopenharmony_ci } 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci /* Some non-CSO atoms don't use the state pointer. */ 246bf215546Sopenharmony_ci r300->fb_state_pipelined.allow_null_state = TRUE; 247bf215546Sopenharmony_ci r300->fs_rc_constant_state.allow_null_state = TRUE; 248bf215546Sopenharmony_ci r300->pvs_flush.allow_null_state = TRUE; 249bf215546Sopenharmony_ci r300->query_start.allow_null_state = TRUE; 250bf215546Sopenharmony_ci r300->texture_cache_inval.allow_null_state = TRUE; 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci /* Some states must be marked as dirty here to properly set up 253bf215546Sopenharmony_ci * hardware in the first command stream. */ 254bf215546Sopenharmony_ci r300_mark_atom_dirty(r300, &r300->invariant_state); 255bf215546Sopenharmony_ci r300_mark_atom_dirty(r300, &r300->pvs_flush); 256bf215546Sopenharmony_ci r300_mark_atom_dirty(r300, &r300->vap_invariant_state); 257bf215546Sopenharmony_ci r300_mark_atom_dirty(r300, &r300->texture_cache_inval); 258bf215546Sopenharmony_ci r300_mark_atom_dirty(r300, &r300->textures_state); 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci return TRUE; 261bf215546Sopenharmony_ci} 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci/* Not every gallium frontend calls every driver function before the first draw 264bf215546Sopenharmony_ci * call and we must initialize the command buffers somehow. */ 265bf215546Sopenharmony_cistatic void r300_init_states(struct pipe_context *pipe) 266bf215546Sopenharmony_ci{ 267bf215546Sopenharmony_ci struct r300_context *r300 = r300_context(pipe); 268bf215546Sopenharmony_ci struct pipe_blend_color bc = {{0}}; 269bf215546Sopenharmony_ci struct pipe_clip_state cs = {{{0}}}; 270bf215546Sopenharmony_ci struct pipe_scissor_state ss = {0}; 271bf215546Sopenharmony_ci struct r300_gpu_flush *gpuflush = 272bf215546Sopenharmony_ci (struct r300_gpu_flush*)r300->gpu_flush.state; 273bf215546Sopenharmony_ci struct r300_vap_invariant_state *vap_invariant = 274bf215546Sopenharmony_ci (struct r300_vap_invariant_state*)r300->vap_invariant_state.state; 275bf215546Sopenharmony_ci struct r300_invariant_state *invariant = 276bf215546Sopenharmony_ci (struct r300_invariant_state*)r300->invariant_state.state; 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci CB_LOCALS; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci pipe->set_blend_color(pipe, &bc); 281bf215546Sopenharmony_ci pipe->set_clip_state(pipe, &cs); 282bf215546Sopenharmony_ci pipe->set_scissor_states(pipe, 0, 1, &ss); 283bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, ~0); 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci /* Initialize the GPU flush. */ 286bf215546Sopenharmony_ci { 287bf215546Sopenharmony_ci BEGIN_CB(gpuflush->cb_flush_clean, 6); 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci /* Flush and free renderbuffer caches. */ 290bf215546Sopenharmony_ci OUT_CB_REG(R300_RB3D_DSTCACHE_CTLSTAT, 291bf215546Sopenharmony_ci R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | 292bf215546Sopenharmony_ci R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); 293bf215546Sopenharmony_ci OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT, 294bf215546Sopenharmony_ci R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | 295bf215546Sopenharmony_ci R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci /* Wait until the GPU is idle. 298bf215546Sopenharmony_ci * This fixes random pixels sometimes appearing probably caused 299bf215546Sopenharmony_ci * by incomplete rendering. */ 300bf215546Sopenharmony_ci OUT_CB_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); 301bf215546Sopenharmony_ci END_CB; 302bf215546Sopenharmony_ci } 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci /* Initialize the VAP invariant state. */ 305bf215546Sopenharmony_ci { 306bf215546Sopenharmony_ci BEGIN_CB(vap_invariant->cb, r300->vap_invariant_state.size); 307bf215546Sopenharmony_ci OUT_CB_REG(VAP_PVS_VTX_TIMEOUT_REG, 0xffff); 308bf215546Sopenharmony_ci OUT_CB_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4); 309bf215546Sopenharmony_ci OUT_CB_32F(1.0); 310bf215546Sopenharmony_ci OUT_CB_32F(1.0); 311bf215546Sopenharmony_ci OUT_CB_32F(1.0); 312bf215546Sopenharmony_ci OUT_CB_32F(1.0); 313bf215546Sopenharmony_ci OUT_CB_REG(R300_VAP_PSC_SGN_NORM_CNTL, R300_SGN_NORM_NO_ZERO); 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci if (r300->screen->caps.is_r500) { 316bf215546Sopenharmony_ci OUT_CB_REG(R500_VAP_TEX_TO_COLOR_CNTL, 0); 317bf215546Sopenharmony_ci } else if (!r300->screen->caps.has_tcl) { 318bf215546Sopenharmony_ci /* RSxxx: 319bf215546Sopenharmony_ci * Static VAP setup since r300_emit_vs_state() is never called. 320bf215546Sopenharmony_ci */ 321bf215546Sopenharmony_ci OUT_CB_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(10) | 322bf215546Sopenharmony_ci R300_PVS_NUM_CNTLRS(5) | 323bf215546Sopenharmony_ci R300_PVS_NUM_FPUS(2) | 324bf215546Sopenharmony_ci R300_PVS_VF_MAX_VTX_NUM(5)); 325bf215546Sopenharmony_ci } 326bf215546Sopenharmony_ci END_CB; 327bf215546Sopenharmony_ci } 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci /* Initialize the invariant state. */ 330bf215546Sopenharmony_ci { 331bf215546Sopenharmony_ci BEGIN_CB(invariant->cb, r300->invariant_state.size); 332bf215546Sopenharmony_ci OUT_CB_REG(R300_GB_SELECT, 0); 333bf215546Sopenharmony_ci OUT_CB_REG(R300_FG_FOG_BLEND, 0); 334bf215546Sopenharmony_ci OUT_CB_REG(R300_GA_OFFSET, 0); 335bf215546Sopenharmony_ci OUT_CB_REG(R300_SU_TEX_WRAP, 0); 336bf215546Sopenharmony_ci OUT_CB_REG(R300_SU_DEPTH_SCALE, 0x4B7FFFFF); 337bf215546Sopenharmony_ci OUT_CB_REG(R300_SU_DEPTH_OFFSET, 0); 338bf215546Sopenharmony_ci OUT_CB_REG(R300_SC_EDGERULE, 0x2DA49525); 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci if (r300->screen->caps.is_rv350) { 341bf215546Sopenharmony_ci OUT_CB_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x01010101); 342bf215546Sopenharmony_ci OUT_CB_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFEFEFEFE); 343bf215546Sopenharmony_ci } 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci if (r300->screen->caps.is_r500) { 346bf215546Sopenharmony_ci OUT_CB_REG(R500_GA_COLOR_CONTROL_PS3, 0); 347bf215546Sopenharmony_ci OUT_CB_REG(R500_SU_TEX_WRAP_PS3, 0); 348bf215546Sopenharmony_ci } 349bf215546Sopenharmony_ci END_CB; 350bf215546Sopenharmony_ci } 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci /* Initialize the hyperz state. */ 353bf215546Sopenharmony_ci { 354bf215546Sopenharmony_ci struct r300_hyperz_state *hyperz = 355bf215546Sopenharmony_ci (struct r300_hyperz_state*)r300->hyperz_state.state; 356bf215546Sopenharmony_ci BEGIN_CB(&hyperz->cb_flush_begin, r300->hyperz_state.size); 357bf215546Sopenharmony_ci OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT, 358bf215546Sopenharmony_ci R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE); 359bf215546Sopenharmony_ci OUT_CB_REG(R300_ZB_BW_CNTL, 0); 360bf215546Sopenharmony_ci OUT_CB_REG(R300_ZB_DEPTHCLEARVALUE, 0); 361bf215546Sopenharmony_ci OUT_CB_REG(R300_SC_HYPERZ, R300_SC_HYPERZ_ADJ_2); 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci if (r300->screen->caps.is_r500 || r300->screen->caps.is_rv350) { 364bf215546Sopenharmony_ci OUT_CB_REG(R300_GB_Z_PEQ_CONFIG, 0); 365bf215546Sopenharmony_ci } 366bf215546Sopenharmony_ci END_CB; 367bf215546Sopenharmony_ci } 368bf215546Sopenharmony_ci} 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_cistatic void 371bf215546Sopenharmony_cir300_set_debug_callback(struct pipe_context *context, 372bf215546Sopenharmony_ci const struct util_debug_callback *cb) 373bf215546Sopenharmony_ci{ 374bf215546Sopenharmony_ci struct r300_context *r300 = r300_context(context); 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci if (cb) 377bf215546Sopenharmony_ci r300->debug = *cb; 378bf215546Sopenharmony_ci else 379bf215546Sopenharmony_ci memset(&r300->debug, 0, sizeof(r300->debug)); 380bf215546Sopenharmony_ci} 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_cistruct pipe_context* r300_create_context(struct pipe_screen* screen, 383bf215546Sopenharmony_ci void *priv, unsigned flags) 384bf215546Sopenharmony_ci{ 385bf215546Sopenharmony_ci struct r300_context* r300 = CALLOC_STRUCT(r300_context); 386bf215546Sopenharmony_ci struct r300_screen* r300screen = r300_screen(screen); 387bf215546Sopenharmony_ci struct radeon_winsys *rws = r300screen->rws; 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci if (!r300) 390bf215546Sopenharmony_ci return NULL; 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci r300->rws = rws; 393bf215546Sopenharmony_ci r300->screen = r300screen; 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci r300->context.screen = screen; 396bf215546Sopenharmony_ci r300->context.priv = priv; 397bf215546Sopenharmony_ci r300->context.set_debug_callback = r300_set_debug_callback; 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ci r300->context.destroy = r300_destroy_context; 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci slab_create_child(&r300->pool_transfers, &r300screen->pool_transfers); 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci r300->ctx = rws->ctx_create(rws, RADEON_CTX_PRIORITY_MEDIUM); 404bf215546Sopenharmony_ci if (!r300->ctx) 405bf215546Sopenharmony_ci goto fail; 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci if (!rws->cs_create(&r300->cs, r300->ctx, AMD_IP_GFX, r300_flush_callback, r300, false)) 409bf215546Sopenharmony_ci goto fail; 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci if (!r300screen->caps.has_tcl) { 412bf215546Sopenharmony_ci /* Create a Draw. This is used for SW TCL. */ 413bf215546Sopenharmony_ci r300->draw = draw_create(&r300->context); 414bf215546Sopenharmony_ci if (r300->draw == NULL) 415bf215546Sopenharmony_ci goto fail; 416bf215546Sopenharmony_ci /* Enable our renderer. */ 417bf215546Sopenharmony_ci draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300)); 418bf215546Sopenharmony_ci /* Disable converting points/lines to triangles. */ 419bf215546Sopenharmony_ci draw_wide_line_threshold(r300->draw, 10000000.f); 420bf215546Sopenharmony_ci draw_wide_point_threshold(r300->draw, 10000000.f); 421bf215546Sopenharmony_ci draw_wide_point_sprites(r300->draw, FALSE); 422bf215546Sopenharmony_ci draw_enable_line_stipple(r300->draw, TRUE); 423bf215546Sopenharmony_ci draw_enable_point_sprites(r300->draw, FALSE); 424bf215546Sopenharmony_ci } 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci if (!r300_setup_atoms(r300)) 427bf215546Sopenharmony_ci goto fail; 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci r300_init_blit_functions(r300); 430bf215546Sopenharmony_ci r300_init_flush_functions(r300); 431bf215546Sopenharmony_ci r300_init_query_functions(r300); 432bf215546Sopenharmony_ci r300_init_state_functions(r300); 433bf215546Sopenharmony_ci r300_init_resource_functions(r300); 434bf215546Sopenharmony_ci r300_init_render_functions(r300); 435bf215546Sopenharmony_ci r300_init_states(&r300->context); 436bf215546Sopenharmony_ci 437bf215546Sopenharmony_ci r300->context.create_video_codec = vl_create_decoder; 438bf215546Sopenharmony_ci r300->context.create_video_buffer = vl_video_buffer_create; 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci r300->uploader = u_upload_create(&r300->context, 128 * 1024, 441bf215546Sopenharmony_ci PIPE_BIND_CUSTOM, PIPE_USAGE_STREAM, 0); 442bf215546Sopenharmony_ci r300->context.stream_uploader = u_upload_create(&r300->context, 1024 * 1024, 443bf215546Sopenharmony_ci 0, PIPE_USAGE_STREAM, 0); 444bf215546Sopenharmony_ci r300->context.const_uploader = u_upload_create(&r300->context, 1024 * 1024, 445bf215546Sopenharmony_ci PIPE_BIND_CONSTANT_BUFFER, 446bf215546Sopenharmony_ci PIPE_USAGE_STREAM, 0); 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_ci r300->blitter = util_blitter_create(&r300->context); 449bf215546Sopenharmony_ci if (r300->blitter == NULL) 450bf215546Sopenharmony_ci goto fail; 451bf215546Sopenharmony_ci r300->blitter->draw_rectangle = r300_blitter_draw_rectangle; 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_ci /* The KIL opcode needs the first texture unit to be enabled 454bf215546Sopenharmony_ci * on r3xx-r4xx. In order to calm down the CS checker, we bind this 455bf215546Sopenharmony_ci * dummy texture there. */ 456bf215546Sopenharmony_ci if (!r300->screen->caps.is_r500) { 457bf215546Sopenharmony_ci struct pipe_resource *tex; 458bf215546Sopenharmony_ci struct pipe_resource rtempl = {0}; 459bf215546Sopenharmony_ci struct pipe_sampler_view vtempl = {0}; 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_ci rtempl.target = PIPE_TEXTURE_2D; 462bf215546Sopenharmony_ci rtempl.format = PIPE_FORMAT_I8_UNORM; 463bf215546Sopenharmony_ci rtempl.usage = PIPE_USAGE_IMMUTABLE; 464bf215546Sopenharmony_ci rtempl.width0 = 1; 465bf215546Sopenharmony_ci rtempl.height0 = 1; 466bf215546Sopenharmony_ci rtempl.depth0 = 1; 467bf215546Sopenharmony_ci tex = screen->resource_create(screen, &rtempl); 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci u_sampler_view_default_template(&vtempl, tex, tex->format); 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_ci r300->texkill_sampler = (struct r300_sampler_view*) 472bf215546Sopenharmony_ci r300->context.create_sampler_view(&r300->context, tex, &vtempl); 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci pipe_resource_reference(&tex, NULL); 475bf215546Sopenharmony_ci } 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci if (r300screen->caps.has_tcl) { 478bf215546Sopenharmony_ci struct pipe_resource vb; 479bf215546Sopenharmony_ci memset(&vb, 0, sizeof(vb)); 480bf215546Sopenharmony_ci vb.target = PIPE_BUFFER; 481bf215546Sopenharmony_ci vb.format = PIPE_FORMAT_R8_UNORM; 482bf215546Sopenharmony_ci vb.usage = PIPE_USAGE_DEFAULT; 483bf215546Sopenharmony_ci vb.width0 = sizeof(float) * 16; 484bf215546Sopenharmony_ci vb.height0 = 1; 485bf215546Sopenharmony_ci vb.depth0 = 1; 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci r300->dummy_vb.buffer.resource = screen->resource_create(screen, &vb); 488bf215546Sopenharmony_ci r300->context.set_vertex_buffers(&r300->context, 0, 1, 0, false, &r300->dummy_vb); 489bf215546Sopenharmony_ci } 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci { 492bf215546Sopenharmony_ci struct pipe_depth_stencil_alpha_state dsa; 493bf215546Sopenharmony_ci memset(&dsa, 0, sizeof(dsa)); 494bf215546Sopenharmony_ci dsa.depth_writemask = 1; 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci r300->dsa_decompress_zmask = 497bf215546Sopenharmony_ci r300->context.create_depth_stencil_alpha_state(&r300->context, 498bf215546Sopenharmony_ci &dsa); 499bf215546Sopenharmony_ci } 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci r300->hyperz_time_of_last_flush = os_time_get(); 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci /* Register allocator state */ 504bf215546Sopenharmony_ci rc_init_regalloc_state(&r300->fs_regalloc_state); 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci /* Print driver info. */ 507bf215546Sopenharmony_ci#ifdef DEBUG 508bf215546Sopenharmony_ci { 509bf215546Sopenharmony_ci#else 510bf215546Sopenharmony_ci if (DBG_ON(r300, DBG_INFO)) { 511bf215546Sopenharmony_ci#endif 512bf215546Sopenharmony_ci fprintf(stderr, 513bf215546Sopenharmony_ci "r300: DRM version: %d.%d.%d, Name: %s, ID: 0x%04x, GB: %d, Z: %d\n" 514bf215546Sopenharmony_ci "r300: GART size: %u MB, VRAM size: %u MB\n" 515bf215546Sopenharmony_ci "r300: AA compression RAM: %s, Z compression RAM: %s, HiZ RAM: %s\n", 516bf215546Sopenharmony_ci r300->screen->info.drm_major, 517bf215546Sopenharmony_ci r300->screen->info.drm_minor, 518bf215546Sopenharmony_ci r300->screen->info.drm_patchlevel, 519bf215546Sopenharmony_ci screen->get_name(screen), 520bf215546Sopenharmony_ci r300->screen->info.pci_id, 521bf215546Sopenharmony_ci r300->screen->info.r300_num_gb_pipes, 522bf215546Sopenharmony_ci r300->screen->info.r300_num_z_pipes, 523bf215546Sopenharmony_ci r300->screen->info.gart_size_kb >> 10, 524bf215546Sopenharmony_ci r300->screen->info.vram_size_kb >> 10, 525bf215546Sopenharmony_ci "YES", /* XXX really? */ 526bf215546Sopenharmony_ci r300->screen->caps.zmask_ram ? "YES" : "NO", 527bf215546Sopenharmony_ci r300->screen->caps.hiz_ram ? "YES" : "NO"); 528bf215546Sopenharmony_ci } 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_ci return &r300->context; 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_cifail: 533bf215546Sopenharmony_ci r300_destroy_context(&r300->context); 534bf215546Sopenharmony_ci return NULL; 535bf215546Sopenharmony_ci} 536