14a49301eSmrg/* 24a49301eSmrg * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 34a49301eSmrg * 44a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 54a49301eSmrg * copy of this software and associated documentation files (the "Software"), 64a49301eSmrg * to deal in the Software without restriction, including without limitation 74a49301eSmrg * on the rights to use, copy, modify, merge, publish, distribute, sub 84a49301eSmrg * license, and/or sell copies of the Software, and to permit persons to whom 94a49301eSmrg * the Software is furnished to do so, subject to the following conditions: 104a49301eSmrg * 114a49301eSmrg * The above copyright notice and this permission notice (including the next 124a49301eSmrg * paragraph) shall be included in all copies or substantial portions of the 134a49301eSmrg * Software. 144a49301eSmrg * 154a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 164a49301eSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 174a49301eSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 184a49301eSmrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 194a49301eSmrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 204a49301eSmrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 214a49301eSmrg * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 224a49301eSmrg 234a49301eSmrg#include "draw/draw_context.h" 244a49301eSmrg 254a49301eSmrg#include "util/u_memory.h" 263464ebd5Sriastradh#include "util/u_sampler.h" 2701e04c3fSmrg#include "util/simple_list.h" 283464ebd5Sriastradh#include "util/u_upload_mgr.h" 2901e04c3fSmrg#include "util/os_time.h" 30af69d88dSmrg#include "vl/vl_decoder.h" 31af69d88dSmrg#include "vl/vl_video_buffer.h" 324a49301eSmrg 333464ebd5Sriastradh#include "r300_cb.h" 344a49301eSmrg#include "r300_context.h" 35cdc920a0Smrg#include "r300_emit.h" 364a49301eSmrg#include "r300_screen.h" 373464ebd5Sriastradh#include "r300_screen_buffer.h" 38af69d88dSmrg#include "compiler/radeon_regalloc.h" 394a49301eSmrg 40af69d88dSmrg#include <inttypes.h> 413464ebd5Sriastradh 423464ebd5Sriastradhstatic void r300_release_referenced_objects(struct r300_context *r300) 433464ebd5Sriastradh{ 443464ebd5Sriastradh struct pipe_framebuffer_state *fb = 453464ebd5Sriastradh (struct pipe_framebuffer_state*)r300->fb_state.state; 463464ebd5Sriastradh struct r300_textures_state *textures = 473464ebd5Sriastradh (struct r300_textures_state*)r300->textures_state.state; 483464ebd5Sriastradh unsigned i; 493464ebd5Sriastradh 503464ebd5Sriastradh /* Framebuffer state. */ 513464ebd5Sriastradh util_unreference_framebuffer_state(fb); 523464ebd5Sriastradh 533464ebd5Sriastradh /* Textures. */ 543464ebd5Sriastradh for (i = 0; i < textures->sampler_view_count; i++) 553464ebd5Sriastradh pipe_sampler_view_reference( 563464ebd5Sriastradh (struct pipe_sampler_view**)&textures->sampler_views[i], NULL); 573464ebd5Sriastradh 583464ebd5Sriastradh /* The special dummy texture for texkill. */ 593464ebd5Sriastradh if (r300->texkill_sampler) { 603464ebd5Sriastradh pipe_sampler_view_reference( 613464ebd5Sriastradh (struct pipe_sampler_view**)&r300->texkill_sampler, 623464ebd5Sriastradh NULL); 633464ebd5Sriastradh } 643464ebd5Sriastradh 653464ebd5Sriastradh /* Manually-created vertex buffers. */ 6601e04c3fSmrg pipe_vertex_buffer_unreference(&r300->dummy_vb); 67af69d88dSmrg pb_reference(&r300->vbo, NULL); 684a49301eSmrg 693464ebd5Sriastradh r300->context.delete_depth_stencil_alpha_state(&r300->context, 703464ebd5Sriastradh r300->dsa_decompress_zmask); 714a49301eSmrg} 724a49301eSmrg 733464ebd5Sriastradhstatic void r300_destroy_context(struct pipe_context* context) 744a49301eSmrg{ 753464ebd5Sriastradh struct r300_context* r300 = r300_context(context); 764a49301eSmrg 777ec681f3Smrg if (r300->cs.priv && r300->hyperz_enabled) { 787ec681f3Smrg r300->rws->cs_request_feature(&r300->cs, RADEON_FID_R300_HYPERZ_ACCESS, FALSE); 79af69d88dSmrg } 807ec681f3Smrg if (r300->cs.priv && r300->cmask_access) { 817ec681f3Smrg r300->rws->cs_request_feature(&r300->cs, RADEON_FID_R300_CMASK_ACCESS, FALSE); 823464ebd5Sriastradh } 834a49301eSmrg 843464ebd5Sriastradh if (r300->blitter) 853464ebd5Sriastradh util_blitter_destroy(r300->blitter); 863464ebd5Sriastradh if (r300->draw) 873464ebd5Sriastradh draw_destroy(r300->draw); 883464ebd5Sriastradh 89af69d88dSmrg if (r300->uploader) 90af69d88dSmrg u_upload_destroy(r300->uploader); 9101e04c3fSmrg if (r300->context.stream_uploader) 9201e04c3fSmrg u_upload_destroy(r300->context.stream_uploader); 933464ebd5Sriastradh 943464ebd5Sriastradh /* XXX: This function assumes r300->query_list was initialized */ 953464ebd5Sriastradh r300_release_referenced_objects(r300); 963464ebd5Sriastradh 977ec681f3Smrg r300->rws->cs_destroy(&r300->cs); 9801e04c3fSmrg if (r300->ctx) 9901e04c3fSmrg r300->rws->ctx_destroy(r300->ctx); 1003464ebd5Sriastradh 101af69d88dSmrg rc_destroy_regalloc_state(&r300->fs_regalloc_state); 102af69d88dSmrg 1033464ebd5Sriastradh /* XXX: No way to tell if this was initialized or not? */ 10401e04c3fSmrg slab_destroy_child(&r300->pool_transfers); 1053464ebd5Sriastradh 1063464ebd5Sriastradh /* Free the structs allocated in r300_setup_atoms() */ 1073464ebd5Sriastradh if (r300->aa_state.state) { 1083464ebd5Sriastradh FREE(r300->aa_state.state); 1093464ebd5Sriastradh FREE(r300->blend_color_state.state); 1103464ebd5Sriastradh FREE(r300->clip_state.state); 1113464ebd5Sriastradh FREE(r300->fb_state.state); 1123464ebd5Sriastradh FREE(r300->gpu_flush.state); 1133464ebd5Sriastradh FREE(r300->hyperz_state.state); 1143464ebd5Sriastradh FREE(r300->invariant_state.state); 1153464ebd5Sriastradh FREE(r300->rs_block_state.state); 116af69d88dSmrg FREE(r300->sample_mask.state); 1173464ebd5Sriastradh FREE(r300->scissor_state.state); 1183464ebd5Sriastradh FREE(r300->textures_state.state); 1193464ebd5Sriastradh FREE(r300->vap_invariant_state.state); 1203464ebd5Sriastradh FREE(r300->viewport_state.state); 1213464ebd5Sriastradh FREE(r300->ztop_state.state); 1223464ebd5Sriastradh FREE(r300->fs_constants.state); 1233464ebd5Sriastradh FREE(r300->vs_constants.state); 1243464ebd5Sriastradh if (!r300->screen->caps.has_tcl) { 1253464ebd5Sriastradh FREE(r300->vertex_stream_state.state); 1263464ebd5Sriastradh } 1273464ebd5Sriastradh } 1283464ebd5Sriastradh FREE(r300); 1294a49301eSmrg} 1304a49301eSmrg 131af69d88dSmrgstatic void r300_flush_callback(void *data, unsigned flags, 132af69d88dSmrg struct pipe_fence_handle **fence) 1334a49301eSmrg{ 1344a49301eSmrg struct r300_context* const cs_context_copy = data; 1354a49301eSmrg 136af69d88dSmrg r300_flush(&cs_context_copy->context, flags, fence); 1374a49301eSmrg} 1384a49301eSmrg 139cdc920a0Smrg#define R300_INIT_ATOM(atomname, atomsize) \ 1403464ebd5Sriastradh do { \ 141cdc920a0Smrg r300->atomname.name = #atomname; \ 142cdc920a0Smrg r300->atomname.state = NULL; \ 143cdc920a0Smrg r300->atomname.size = atomsize; \ 144cdc920a0Smrg r300->atomname.emit = r300_emit_##atomname; \ 145cdc920a0Smrg r300->atomname.dirty = FALSE; \ 1463464ebd5Sriastradh } while (0) 147cdc920a0Smrg 1483464ebd5Sriastradh#define R300_ALLOC_ATOM(atomname, statetype) \ 1493464ebd5Sriastradhdo { \ 1503464ebd5Sriastradh r300->atomname.state = CALLOC_STRUCT(statetype); \ 1513464ebd5Sriastradh if (r300->atomname.state == NULL) \ 1523464ebd5Sriastradh return FALSE; \ 1533464ebd5Sriastradh} while (0) 1543464ebd5Sriastradh 1553464ebd5Sriastradhstatic boolean r300_setup_atoms(struct r300_context* r300) 156cdc920a0Smrg{ 1573464ebd5Sriastradh boolean is_rv350 = r300->screen->caps.is_rv350; 1583464ebd5Sriastradh boolean is_r500 = r300->screen->caps.is_r500; 1593464ebd5Sriastradh boolean has_tcl = r300->screen->caps.has_tcl; 160cdc920a0Smrg 161cdc920a0Smrg /* Create the actual atom list. 162cdc920a0Smrg * 163cdc920a0Smrg * Some atoms never change size, others change every emit - those have 1643464ebd5Sriastradh * the size of 0 here. 1653464ebd5Sriastradh * 1663464ebd5Sriastradh * NOTE: The framebuffer state is split into these atoms: 1673464ebd5Sriastradh * - gpu_flush (unpipelined regs) 1683464ebd5Sriastradh * - aa_state (unpipelined regs) 1693464ebd5Sriastradh * - fb_state (unpipelined regs) 1703464ebd5Sriastradh * - hyperz_state (unpipelined regs followed by pipelined ones) 1713464ebd5Sriastradh * - fb_state_pipelined (pipelined regs) 1723464ebd5Sriastradh * The motivation behind this is to be able to emit a strict 1733464ebd5Sriastradh * subset of the regs, and to have reasonable register ordering. */ 1743464ebd5Sriastradh /* SC, GB (unpipelined), RB3D (unpipelined), ZB (unpipelined). */ 1753464ebd5Sriastradh R300_INIT_ATOM(gpu_flush, 9); 1763464ebd5Sriastradh R300_INIT_ATOM(aa_state, 4); 1773464ebd5Sriastradh R300_INIT_ATOM(fb_state, 0); 17801e04c3fSmrg R300_INIT_ATOM(hyperz_state, is_r500 || is_rv350 ? 10 : 8); 1793464ebd5Sriastradh /* ZB (unpipelined), SC. */ 180cdc920a0Smrg R300_INIT_ATOM(ztop_state, 2); 1813464ebd5Sriastradh /* ZB, FG. */ 18201e04c3fSmrg R300_INIT_ATOM(dsa_state, is_r500 ? 10 : 6); 1833464ebd5Sriastradh /* RB3D. */ 184cdc920a0Smrg R300_INIT_ATOM(blend_state, 8); 185cdc920a0Smrg R300_INIT_ATOM(blend_color_state, is_r500 ? 3 : 2); 1863464ebd5Sriastradh /* SC. */ 187af69d88dSmrg R300_INIT_ATOM(sample_mask, 2); 188cdc920a0Smrg R300_INIT_ATOM(scissor_state, 3); 1893464ebd5Sriastradh /* GB, FG, GA, SU, SC, RB3D. */ 190af69d88dSmrg R300_INIT_ATOM(invariant_state, 14 + (is_rv350 ? 4 : 0) + (is_r500 ? 4 : 0)); 1913464ebd5Sriastradh /* VAP. */ 192cdc920a0Smrg R300_INIT_ATOM(viewport_state, 9); 193cdc920a0Smrg R300_INIT_ATOM(pvs_flush, 2); 19401e04c3fSmrg R300_INIT_ATOM(vap_invariant_state, is_r500 || !has_tcl ? 11 : 9); 1953464ebd5Sriastradh R300_INIT_ATOM(vertex_stream_state, 0); 196cdc920a0Smrg R300_INIT_ATOM(vs_state, 0); 1973464ebd5Sriastradh R300_INIT_ATOM(vs_constants, 0); 198af69d88dSmrg R300_INIT_ATOM(clip_state, has_tcl ? 3 + (6 * 4) : 0); 1993464ebd5Sriastradh /* VAP, RS, GA, GB, SU, SC. */ 2003464ebd5Sriastradh R300_INIT_ATOM(rs_block_state, 0); 2013464ebd5Sriastradh R300_INIT_ATOM(rs_state, 0); 2023464ebd5Sriastradh /* SC, US. */ 2033464ebd5Sriastradh R300_INIT_ATOM(fb_state_pipelined, 8); 2043464ebd5Sriastradh /* US. */ 2053464ebd5Sriastradh R300_INIT_ATOM(fs, 0); 2063464ebd5Sriastradh R300_INIT_ATOM(fs_rc_constant_state, 0); 2073464ebd5Sriastradh R300_INIT_ATOM(fs_constants, 0); 2083464ebd5Sriastradh /* TX. */ 209cdc920a0Smrg R300_INIT_ATOM(texture_cache_inval, 2); 210cdc920a0Smrg R300_INIT_ATOM(textures_state, 0); 211af69d88dSmrg /* Clear commands */ 2123464ebd5Sriastradh R300_INIT_ATOM(hiz_clear, r300->screen->caps.hiz_ram > 0 ? 4 : 0); 2133464ebd5Sriastradh R300_INIT_ATOM(zmask_clear, r300->screen->caps.zmask_ram > 0 ? 4 : 0); 214af69d88dSmrg R300_INIT_ATOM(cmask_clear, 4); 2153464ebd5Sriastradh /* ZB (unpipelined), SU. */ 2163464ebd5Sriastradh R300_INIT_ATOM(query_start, 4); 2173464ebd5Sriastradh 2183464ebd5Sriastradh /* Replace emission functions for r500. */ 2193464ebd5Sriastradh if (is_r500) { 2203464ebd5Sriastradh r300->fs.emit = r500_emit_fs; 2213464ebd5Sriastradh r300->fs_rc_constant_state.emit = r500_emit_fs_rc_constant_state; 2223464ebd5Sriastradh r300->fs_constants.emit = r500_emit_fs_constants; 2233464ebd5Sriastradh } 224cdc920a0Smrg 225cdc920a0Smrg /* Some non-CSO atoms need explicit space to store the state locally. */ 2263464ebd5Sriastradh R300_ALLOC_ATOM(aa_state, r300_aa_state); 2273464ebd5Sriastradh R300_ALLOC_ATOM(blend_color_state, r300_blend_color_state); 2283464ebd5Sriastradh R300_ALLOC_ATOM(clip_state, r300_clip_state); 2293464ebd5Sriastradh R300_ALLOC_ATOM(hyperz_state, r300_hyperz_state); 2303464ebd5Sriastradh R300_ALLOC_ATOM(invariant_state, r300_invariant_state); 2313464ebd5Sriastradh R300_ALLOC_ATOM(textures_state, r300_textures_state); 2323464ebd5Sriastradh R300_ALLOC_ATOM(vap_invariant_state, r300_vap_invariant_state); 2333464ebd5Sriastradh R300_ALLOC_ATOM(viewport_state, r300_viewport_state); 2343464ebd5Sriastradh R300_ALLOC_ATOM(ztop_state, r300_ztop_state); 2353464ebd5Sriastradh R300_ALLOC_ATOM(fb_state, pipe_framebuffer_state); 2363464ebd5Sriastradh R300_ALLOC_ATOM(gpu_flush, pipe_framebuffer_state); 237af69d88dSmrg r300->sample_mask.state = malloc(4); 2383464ebd5Sriastradh R300_ALLOC_ATOM(scissor_state, pipe_scissor_state); 2393464ebd5Sriastradh R300_ALLOC_ATOM(rs_block_state, r300_rs_block); 2403464ebd5Sriastradh R300_ALLOC_ATOM(fs_constants, r300_constant_buffer); 2413464ebd5Sriastradh R300_ALLOC_ATOM(vs_constants, r300_constant_buffer); 2423464ebd5Sriastradh if (!r300->screen->caps.has_tcl) { 2433464ebd5Sriastradh R300_ALLOC_ATOM(vertex_stream_state, r300_vertex_stream_state); 2443464ebd5Sriastradh } 2453464ebd5Sriastradh 2463464ebd5Sriastradh /* Some non-CSO atoms don't use the state pointer. */ 2473464ebd5Sriastradh r300->fb_state_pipelined.allow_null_state = TRUE; 2483464ebd5Sriastradh r300->fs_rc_constant_state.allow_null_state = TRUE; 2493464ebd5Sriastradh r300->pvs_flush.allow_null_state = TRUE; 2503464ebd5Sriastradh r300->query_start.allow_null_state = TRUE; 2513464ebd5Sriastradh r300->texture_cache_inval.allow_null_state = TRUE; 2523464ebd5Sriastradh 2533464ebd5Sriastradh /* Some states must be marked as dirty here to properly set up 2543464ebd5Sriastradh * hardware in the first command stream. */ 2553464ebd5Sriastradh r300_mark_atom_dirty(r300, &r300->invariant_state); 2563464ebd5Sriastradh r300_mark_atom_dirty(r300, &r300->pvs_flush); 2573464ebd5Sriastradh r300_mark_atom_dirty(r300, &r300->vap_invariant_state); 2583464ebd5Sriastradh r300_mark_atom_dirty(r300, &r300->texture_cache_inval); 2593464ebd5Sriastradh r300_mark_atom_dirty(r300, &r300->textures_state); 2603464ebd5Sriastradh 2613464ebd5Sriastradh return TRUE; 2623464ebd5Sriastradh} 2633464ebd5Sriastradh 2647ec681f3Smrg/* Not every gallium frontend calls every driver function before the first draw 2653464ebd5Sriastradh * call and we must initialize the command buffers somehow. */ 2663464ebd5Sriastradhstatic void r300_init_states(struct pipe_context *pipe) 2673464ebd5Sriastradh{ 2683464ebd5Sriastradh struct r300_context *r300 = r300_context(pipe); 2693464ebd5Sriastradh struct pipe_blend_color bc = {{0}}; 2703464ebd5Sriastradh struct pipe_clip_state cs = {{{0}}}; 2713464ebd5Sriastradh struct pipe_scissor_state ss = {0}; 2723464ebd5Sriastradh struct r300_gpu_flush *gpuflush = 2733464ebd5Sriastradh (struct r300_gpu_flush*)r300->gpu_flush.state; 2743464ebd5Sriastradh struct r300_vap_invariant_state *vap_invariant = 2753464ebd5Sriastradh (struct r300_vap_invariant_state*)r300->vap_invariant_state.state; 2763464ebd5Sriastradh struct r300_invariant_state *invariant = 2773464ebd5Sriastradh (struct r300_invariant_state*)r300->invariant_state.state; 2783464ebd5Sriastradh 2793464ebd5Sriastradh CB_LOCALS; 2803464ebd5Sriastradh 2813464ebd5Sriastradh pipe->set_blend_color(pipe, &bc); 282af69d88dSmrg pipe->set_clip_state(pipe, &cs); 283af69d88dSmrg pipe->set_scissor_states(pipe, 0, 1, &ss); 284af69d88dSmrg pipe->set_sample_mask(pipe, ~0); 2853464ebd5Sriastradh 2863464ebd5Sriastradh /* Initialize the GPU flush. */ 2873464ebd5Sriastradh { 2883464ebd5Sriastradh BEGIN_CB(gpuflush->cb_flush_clean, 6); 2893464ebd5Sriastradh 2903464ebd5Sriastradh /* Flush and free renderbuffer caches. */ 2913464ebd5Sriastradh OUT_CB_REG(R300_RB3D_DSTCACHE_CTLSTAT, 2923464ebd5Sriastradh R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | 2933464ebd5Sriastradh R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); 2943464ebd5Sriastradh OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT, 2953464ebd5Sriastradh R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | 2963464ebd5Sriastradh R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); 2973464ebd5Sriastradh 2983464ebd5Sriastradh /* Wait until the GPU is idle. 2993464ebd5Sriastradh * This fixes random pixels sometimes appearing probably caused 3003464ebd5Sriastradh * by incomplete rendering. */ 3013464ebd5Sriastradh OUT_CB_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); 3023464ebd5Sriastradh END_CB; 3033464ebd5Sriastradh } 3043464ebd5Sriastradh 3053464ebd5Sriastradh /* Initialize the VAP invariant state. */ 3063464ebd5Sriastradh { 3073464ebd5Sriastradh BEGIN_CB(vap_invariant->cb, r300->vap_invariant_state.size); 3083464ebd5Sriastradh OUT_CB_REG(VAP_PVS_VTX_TIMEOUT_REG, 0xffff); 3093464ebd5Sriastradh OUT_CB_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4); 3103464ebd5Sriastradh OUT_CB_32F(1.0); 3113464ebd5Sriastradh OUT_CB_32F(1.0); 3123464ebd5Sriastradh OUT_CB_32F(1.0); 3133464ebd5Sriastradh OUT_CB_32F(1.0); 3143464ebd5Sriastradh OUT_CB_REG(R300_VAP_PSC_SGN_NORM_CNTL, R300_SGN_NORM_NO_ZERO); 3153464ebd5Sriastradh 3163464ebd5Sriastradh if (r300->screen->caps.is_r500) { 3173464ebd5Sriastradh OUT_CB_REG(R500_VAP_TEX_TO_COLOR_CNTL, 0); 31801e04c3fSmrg } else if (!r300->screen->caps.has_tcl) { 31901e04c3fSmrg /* RSxxx: 32001e04c3fSmrg * Static VAP setup since r300_emit_vs_state() is never called. 32101e04c3fSmrg */ 32201e04c3fSmrg OUT_CB_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(10) | 32301e04c3fSmrg R300_PVS_NUM_CNTLRS(5) | 32401e04c3fSmrg R300_PVS_NUM_FPUS(2) | 32501e04c3fSmrg R300_PVS_VF_MAX_VTX_NUM(5)); 3263464ebd5Sriastradh } 3273464ebd5Sriastradh END_CB; 3283464ebd5Sriastradh } 3293464ebd5Sriastradh 3303464ebd5Sriastradh /* Initialize the invariant state. */ 3313464ebd5Sriastradh { 3323464ebd5Sriastradh BEGIN_CB(invariant->cb, r300->invariant_state.size); 3333464ebd5Sriastradh OUT_CB_REG(R300_GB_SELECT, 0); 3343464ebd5Sriastradh OUT_CB_REG(R300_FG_FOG_BLEND, 0); 3353464ebd5Sriastradh OUT_CB_REG(R300_GA_OFFSET, 0); 3363464ebd5Sriastradh OUT_CB_REG(R300_SU_TEX_WRAP, 0); 3373464ebd5Sriastradh OUT_CB_REG(R300_SU_DEPTH_SCALE, 0x4B7FFFFF); 3383464ebd5Sriastradh OUT_CB_REG(R300_SU_DEPTH_OFFSET, 0); 3393464ebd5Sriastradh OUT_CB_REG(R300_SC_EDGERULE, 0x2DA49525); 3403464ebd5Sriastradh 3413464ebd5Sriastradh if (r300->screen->caps.is_rv350) { 3423464ebd5Sriastradh OUT_CB_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x01010101); 3433464ebd5Sriastradh OUT_CB_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFEFEFEFE); 3443464ebd5Sriastradh } 3453464ebd5Sriastradh 3463464ebd5Sriastradh if (r300->screen->caps.is_r500) { 3473464ebd5Sriastradh OUT_CB_REG(R500_GA_COLOR_CONTROL_PS3, 0); 3483464ebd5Sriastradh OUT_CB_REG(R500_SU_TEX_WRAP_PS3, 0); 3493464ebd5Sriastradh } 3503464ebd5Sriastradh END_CB; 3513464ebd5Sriastradh } 3523464ebd5Sriastradh 3533464ebd5Sriastradh /* Initialize the hyperz state. */ 3543464ebd5Sriastradh { 3553464ebd5Sriastradh struct r300_hyperz_state *hyperz = 3563464ebd5Sriastradh (struct r300_hyperz_state*)r300->hyperz_state.state; 3573464ebd5Sriastradh BEGIN_CB(&hyperz->cb_flush_begin, r300->hyperz_state.size); 3583464ebd5Sriastradh OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT, 3593464ebd5Sriastradh R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE); 3603464ebd5Sriastradh OUT_CB_REG(R300_ZB_BW_CNTL, 0); 3613464ebd5Sriastradh OUT_CB_REG(R300_ZB_DEPTHCLEARVALUE, 0); 3623464ebd5Sriastradh OUT_CB_REG(R300_SC_HYPERZ, R300_SC_HYPERZ_ADJ_2); 3633464ebd5Sriastradh 36401e04c3fSmrg if (r300->screen->caps.is_r500 || r300->screen->caps.is_rv350) { 3653464ebd5Sriastradh OUT_CB_REG(R300_GB_Z_PEQ_CONFIG, 0); 3663464ebd5Sriastradh } 3673464ebd5Sriastradh END_CB; 3683464ebd5Sriastradh } 369cdc920a0Smrg} 370cdc920a0Smrg 3714a49301eSmrgstruct pipe_context* r300_create_context(struct pipe_screen* screen, 37201e04c3fSmrg void *priv, unsigned flags) 3734a49301eSmrg{ 3744a49301eSmrg struct r300_context* r300 = CALLOC_STRUCT(r300_context); 3754a49301eSmrg struct r300_screen* r300screen = r300_screen(screen); 3763464ebd5Sriastradh struct radeon_winsys *rws = r300screen->rws; 3774a49301eSmrg 3784a49301eSmrg if (!r300) 3794a49301eSmrg return NULL; 3804a49301eSmrg 3813464ebd5Sriastradh r300->rws = rws; 3823464ebd5Sriastradh r300->screen = r300screen; 3833464ebd5Sriastradh 3844a49301eSmrg r300->context.screen = screen; 385cdc920a0Smrg r300->context.priv = priv; 3864a49301eSmrg 3874a49301eSmrg r300->context.destroy = r300_destroy_context; 3884a49301eSmrg 38901e04c3fSmrg slab_create_child(&r300->pool_transfers, &r300screen->pool_transfers); 3903464ebd5Sriastradh 39101e04c3fSmrg r300->ctx = rws->ctx_create(rws); 39201e04c3fSmrg if (!r300->ctx) 39301e04c3fSmrg goto fail; 39401e04c3fSmrg 3957ec681f3Smrg 3967ec681f3Smrg if (!rws->cs_create(&r300->cs, r300->ctx, RING_GFX, r300_flush_callback, r300, false)) 3973464ebd5Sriastradh goto fail; 398cdc920a0Smrg 3993464ebd5Sriastradh if (!r300screen->caps.has_tcl) { 400cdc920a0Smrg /* Create a Draw. This is used for SW TCL. */ 401cdc920a0Smrg r300->draw = draw_create(&r300->context); 4023464ebd5Sriastradh if (r300->draw == NULL) 4033464ebd5Sriastradh goto fail; 404cdc920a0Smrg /* Enable our renderer. */ 405cdc920a0Smrg draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300)); 4063464ebd5Sriastradh /* Disable converting points/lines to triangles. */ 4073464ebd5Sriastradh draw_wide_line_threshold(r300->draw, 10000000.f); 4083464ebd5Sriastradh draw_wide_point_threshold(r300->draw, 10000000.f); 409af69d88dSmrg draw_wide_point_sprites(r300->draw, FALSE); 410af69d88dSmrg draw_enable_line_stipple(r300->draw, TRUE); 411af69d88dSmrg draw_enable_point_sprites(r300->draw, FALSE); 4124a49301eSmrg } 4134a49301eSmrg 4143464ebd5Sriastradh if (!r300_setup_atoms(r300)) 4153464ebd5Sriastradh goto fail; 4164a49301eSmrg 4173464ebd5Sriastradh r300_init_blit_functions(r300); 4184a49301eSmrg r300_init_flush_functions(r300); 4194a49301eSmrg r300_init_query_functions(r300); 4203464ebd5Sriastradh r300_init_state_functions(r300); 4213464ebd5Sriastradh r300_init_resource_functions(r300); 422af69d88dSmrg r300_init_render_functions(r300); 423af69d88dSmrg r300_init_states(&r300->context); 4244a49301eSmrg 425af69d88dSmrg r300->context.create_video_codec = vl_create_decoder; 426af69d88dSmrg r300->context.create_video_buffer = vl_video_buffer_create; 427af69d88dSmrg 42801e04c3fSmrg r300->uploader = u_upload_create(&r300->context, 128 * 1024, 42901e04c3fSmrg PIPE_BIND_CUSTOM, PIPE_USAGE_STREAM, 0); 43001e04c3fSmrg r300->context.stream_uploader = u_upload_create(&r300->context, 1024 * 1024, 43101e04c3fSmrg 0, PIPE_USAGE_STREAM, 0); 43201e04c3fSmrg r300->context.const_uploader = r300->context.stream_uploader; 4334a49301eSmrg 4343464ebd5Sriastradh r300->blitter = util_blitter_create(&r300->context); 4353464ebd5Sriastradh if (r300->blitter == NULL) 4363464ebd5Sriastradh goto fail; 437af69d88dSmrg r300->blitter->draw_rectangle = r300_blitter_draw_rectangle; 4383464ebd5Sriastradh 4393464ebd5Sriastradh /* The KIL opcode needs the first texture unit to be enabled 4403464ebd5Sriastradh * on r3xx-r4xx. In order to calm down the CS checker, we bind this 4413464ebd5Sriastradh * dummy texture there. */ 4423464ebd5Sriastradh if (!r300->screen->caps.is_r500) { 4433464ebd5Sriastradh struct pipe_resource *tex; 4447ec681f3Smrg struct pipe_resource rtempl = {0}; 4457ec681f3Smrg struct pipe_sampler_view vtempl = {0}; 4463464ebd5Sriastradh 4473464ebd5Sriastradh rtempl.target = PIPE_TEXTURE_2D; 4483464ebd5Sriastradh rtempl.format = PIPE_FORMAT_I8_UNORM; 4493464ebd5Sriastradh rtempl.usage = PIPE_USAGE_IMMUTABLE; 4503464ebd5Sriastradh rtempl.width0 = 1; 4513464ebd5Sriastradh rtempl.height0 = 1; 4523464ebd5Sriastradh rtempl.depth0 = 1; 4533464ebd5Sriastradh tex = screen->resource_create(screen, &rtempl); 4543464ebd5Sriastradh 4553464ebd5Sriastradh u_sampler_view_default_template(&vtempl, tex, tex->format); 4563464ebd5Sriastradh 4573464ebd5Sriastradh r300->texkill_sampler = (struct r300_sampler_view*) 4583464ebd5Sriastradh r300->context.create_sampler_view(&r300->context, tex, &vtempl); 4593464ebd5Sriastradh 4603464ebd5Sriastradh pipe_resource_reference(&tex, NULL); 4613464ebd5Sriastradh } 4624a49301eSmrg 463af69d88dSmrg if (r300screen->caps.has_tcl) { 4643464ebd5Sriastradh struct pipe_resource vb; 4653464ebd5Sriastradh memset(&vb, 0, sizeof(vb)); 4663464ebd5Sriastradh vb.target = PIPE_BUFFER; 4673464ebd5Sriastradh vb.format = PIPE_FORMAT_R8_UNORM; 468af69d88dSmrg vb.usage = PIPE_USAGE_DEFAULT; 4693464ebd5Sriastradh vb.width0 = sizeof(float) * 16; 4703464ebd5Sriastradh vb.height0 = 1; 4713464ebd5Sriastradh vb.depth0 = 1; 4723464ebd5Sriastradh 47301e04c3fSmrg r300->dummy_vb.buffer.resource = screen->resource_create(screen, &vb); 4747ec681f3Smrg r300->context.set_vertex_buffers(&r300->context, 0, 1, 0, false, &r300->dummy_vb); 4753464ebd5Sriastradh } 4764a49301eSmrg 4773464ebd5Sriastradh { 4783464ebd5Sriastradh struct pipe_depth_stencil_alpha_state dsa; 4793464ebd5Sriastradh memset(&dsa, 0, sizeof(dsa)); 4807ec681f3Smrg dsa.depth_writemask = 1; 481cdc920a0Smrg 4823464ebd5Sriastradh r300->dsa_decompress_zmask = 4833464ebd5Sriastradh r300->context.create_depth_stencil_alpha_state(&r300->context, 4843464ebd5Sriastradh &dsa); 4853464ebd5Sriastradh } 4863464ebd5Sriastradh 4873464ebd5Sriastradh r300->hyperz_time_of_last_flush = os_time_get(); 4883464ebd5Sriastradh 489af69d88dSmrg /* Register allocator state */ 490af69d88dSmrg rc_init_regalloc_state(&r300->fs_regalloc_state); 491af69d88dSmrg 4923464ebd5Sriastradh /* Print driver info. */ 4933464ebd5Sriastradh#ifdef DEBUG 4943464ebd5Sriastradh { 4953464ebd5Sriastradh#else 4963464ebd5Sriastradh if (DBG_ON(r300, DBG_INFO)) { 4973464ebd5Sriastradh#endif 4983464ebd5Sriastradh fprintf(stderr, 4993464ebd5Sriastradh "r300: DRM version: %d.%d.%d, Name: %s, ID: 0x%04x, GB: %d, Z: %d\n" 500af69d88dSmrg "r300: GART size: %"PRIu64" MB, VRAM size: %"PRIu64" MB\n" 5013464ebd5Sriastradh "r300: AA compression RAM: %s, Z compression RAM: %s, HiZ RAM: %s\n", 502af69d88dSmrg r300->screen->info.drm_major, 503af69d88dSmrg r300->screen->info.drm_minor, 504af69d88dSmrg r300->screen->info.drm_patchlevel, 5053464ebd5Sriastradh screen->get_name(screen), 506af69d88dSmrg r300->screen->info.pci_id, 507af69d88dSmrg r300->screen->info.r300_num_gb_pipes, 508af69d88dSmrg r300->screen->info.r300_num_z_pipes, 509af69d88dSmrg r300->screen->info.gart_size >> 20, 510af69d88dSmrg r300->screen->info.vram_size >> 20, 5113464ebd5Sriastradh "YES", /* XXX really? */ 5123464ebd5Sriastradh r300->screen->caps.zmask_ram ? "YES" : "NO", 5133464ebd5Sriastradh r300->screen->caps.hiz_ram ? "YES" : "NO"); 5143464ebd5Sriastradh } 515cdc920a0Smrg 5164a49301eSmrg return &r300->context; 5173464ebd5Sriastradh 5183464ebd5Sriastradhfail: 5193464ebd5Sriastradh r300_destroy_context(&r300->context); 5203464ebd5Sriastradh return NULL; 5214a49301eSmrg} 522