/* * Copyright 2010 Jerome Glisse * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Jerome Glisse */ #include "radeon_bo.h" #include "r600.h" #include "r600_clear.h" #include "r600d.h" static u32 vsconstants[16] = { 0x3C03126F, 0x00000000, 0x00000000, 0xBF800000, 0x00000000, 0x3C03126F, 0x00000000, 0xBF800000, 0x00000000, 0x00000000, 0xBF800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3F800000, }; static u32 vsshaders[64] = { 0x0000001C, 0x81000400, 0x00000005, 0x80000000, 0x00000007, 0xA04C0000, 0xC001A03C, 0x94000688, 0xC0024000, 0x94200688, 0x900000F8, 0x00A80C90, 0x00000000, 0x00000000, 0x00200001, 0x006C2810, 0x00A00401, 0x206C2800, 0x01200801, 0x406C2800, 0x81A00C01, 0x606C2800, 0x00202001, 0x006C2800, 0x00A02401, 0x206C2810, 0x01202801, 0x406C2800, 0x81A02C01, 0x606C2800, 0x00204001, 0x006C2800, 0x00A04401, 0x206C2800, 0x01204801, 0x406C2810, 0x81A04C01, 0x606C2800, 0x00206001, 0x006C2800, 0x00A06401, 0x206C2800, 0x01206801, 0x406C2800, 0x81A06C01, 0x606C2810, 0x00000002, 0x00940C90, 0x00000402, 0x20940C90, 0x00000802, 0x40940C90, 0x80000C02, 0x60940C90, 0x00000000, 0x00000000, 0x7C000000, 0x1C351001, 0x00080000, 0x0BEADEAF, 0x7C000100, 0x18ED1002, 0x00080000, 0x0BEADEAF, }; static u32 fsshaders[20] = { 0x00000003, 0x80000000, 0x00000005, 0xA00C0000, 0xC0008000, 0x94200688, 0x900000F8, 0x00480C90, 0x00000000, 0x00000000, 0x00000000, 0x00340C90, 0x00000400, 0x20340C90, 0x00000800, 0x40340C90, 0x80000C00, 0x60340C90, 0x00000000, 0x00000000, }; static float rvbo[32] = { 0.000000, 0.000000, -1.000000, 0.500000, 0.500000, 0.500000, 0.000000, 250.000000, 0.000000, -1.000000, 0.500000, 0.500000, 0.500000, 0.000000, 250.000000, 250.000000, -1.000000, 0.500000, 0.500000, 0.500000, 0.000000, 0.000000, 250.000000, -1.000000, 0.500000, 0.500000, 0.500000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, }; int r600_clear_queue(struct r600_winsys *rw, struct r600_atom *fb, struct r600_clear_data *rclear, unsigned buffers, const float *rgba, float depth, unsigned stencil) { struct r600_scissor scissor; struct r600_framebuffer *pfb; struct r600_request rq; int r; pfb = r600_atom_state(fb); rclear->batch.scissor = r600_atom_destroy(rclear->batch.scissor); rclear->batch.framebuffer = fb; /* scissor */ scissor.pa_sc_vport_scissor_0_tl = 0x80000000; scissor.pa_sc_vport_scissor_0_br = S_028244_BR_X(pfb->width) | S_028244_BR_Y(pfb->height); rq.type = R600_ATOM_SCISSOR; rq.data = &scissor; rq.nbo = 0; rclear->batch.scissor = r600_atom_create(rw, &rq); /* queue batch */ rq.type = 0; rq.data = &rclear->batch; rq.nbo = 0; r = r600_scheduler_queue(rw, &rq); if (r) return r; r = r600_scheduler_flush(rw); return r; } void r600_clear_destroy(struct r600_clear_data *rclear) { rclear->batch.framebuffer = NULL; rclear->batch.scissor = r600_atom_destroy(rclear->batch.scissor); rclear->batch.rasterizer = r600_atom_destroy(rclear->batch.rasterizer); rclear->batch.cb_cntl = r600_atom_destroy(rclear->batch.cb_cntl); rclear->batch.viewport = r600_atom_destroy(rclear->batch.viewport); rclear->batch.blend = r600_atom_destroy(rclear->batch.blend); rclear->batch.vs_constants = r600_atom_destroy(rclear->batch.vs_constants); rclear->batch.dsa = r600_atom_destroy(rclear->batch.dsa); rclear->batch.vs_shader = r600_atom_destroy(rclear->batch.vs_shader); rclear->batch.fs_shader = r600_atom_destroy(rclear->batch.fs_shader); } int r600_clear_init(struct r600_winsys *rw, struct radeon_bo_manager *bom, struct r600_clear_data *rclear) { struct r600_blend blend; struct r600_framebuffer fb; struct r600_cb_cntl cb_cntl; struct r600_dsa dsa; struct r600_rasterizer rasterizer; struct r600_viewport vport; struct r600_constants vs_constants; struct r600_vs_shader vs_shader; struct r600_fs_shader fs_shader; struct r600_shader_resource vs_resource; struct r600_request rq; struct radeon_bo *vbo = NULL; struct radeon_bo *vs = NULL; struct radeon_bo *fs = NULL; int r = 0; vbo = radeon_bo_open(bom, 0, 4096, 0, RADEON_GEM_DOMAIN_GTT, 0); if (vbo == NULL) { r = -ENOMEM; goto out_err; } r600_memcpy_bo(vbo, (u32*)rvbo, 32 * 4); vs = radeon_bo_open(bom, 0, 4096, 0, RADEON_GEM_DOMAIN_GTT, 0); if (vs == NULL) { r = -ENOMEM; goto out_err; } r600_memcpy_bo(vs, (u32*)vsshaders, 64 * 4); fs = radeon_bo_open(bom, 0, 4096, 0, RADEON_GEM_DOMAIN_GTT, 0); if (fs == NULL) { r = -ENOMEM; goto out_err; } r600_memcpy_bo(fs, (u32*)fsshaders, 20 * 4); /* rasterizer state */ rasterizer.pa_sc_mpass_ps_cntl = 0x00000000; rasterizer.pa_sc_line_cntl = 0x00000400; rasterizer.pa_sc_aa_config = 0x00000000; rasterizer.pa_sc_aa_sample_locs_mctx = 0x00000000; rasterizer.pa_sc_aa_mask = 0xffffffff; rasterizer.pa_cl_clip_cntl = 0x00000000; rasterizer.pa_cl_vs_out_cntl = 0x00000000; rasterizer.pa_cl_naninf_cntl = 0x00000000; rasterizer.pa_cl_gb_vert_clip_adj = 0x3f800000; rasterizer.pa_cl_gb_vert_disc_adj = 0x3f800000; rasterizer.pa_cl_gb_horz_clip_adj = 0x3f800000; rasterizer.pa_cl_gb_horz_disc_adj = 0x3f800000; rasterizer.pa_su_sc_mode_cntl = 0x00080000; rasterizer.pa_su_point_size = 0x00080008; rasterizer.pa_su_point_minmax = 0x80000000; rasterizer.pa_su_line_cntl = 0x00000008; rasterizer.pa_sc_line_stipple = 0x00000005; rasterizer.pa_su_poly_offset_db_fmt_cntl = 0x00000000; rasterizer.pa_su_poly_offset_clamp = 0x00000000; rasterizer.pa_su_poly_offset_front_scale = 0x00000000; rasterizer.pa_su_poly_offset_front_offset = 0x00000000; rasterizer.pa_su_poly_offset_back_scale = 0x00000000; rasterizer.pa_su_poly_offset_back_offset = 0x00000000; rq.type = R600_ATOM_RASTERIZER; rq.data = &rasterizer; rq.nbo = 0; rclear->batch.rasterizer = r600_atom_create(rw, &rq); /* cb cntl */ cb_cntl.cb_clrcmp_control = 0x01000000; cb_cntl.cb_clrcmp_src = 0x00000000; cb_cntl.cb_clrcmp_dst = 0x000000ff; cb_cntl.cb_clrcmp_msk = 0xffffffff; cb_cntl.cb_color_control = 0x00cc0000; cb_cntl.cb_clear_alpha = 0x00000000; cb_cntl.cb_clear_blue = 0x00000000; cb_cntl.cb_clear_green = 0x00000000; cb_cntl.cb_clear_red = 0x00000000; cb_cntl.cb_blend_alpha = 0x00000000; cb_cntl.cb_blend_blue = 0x00000000; cb_cntl.cb_blend_green = 0x00000000; cb_cntl.cb_blend_red = 0x00000000; cb_cntl.cb_fog_blue = 0x00000000; cb_cntl.cb_fog_green = 0x00000000; cb_cntl.cb_fog_red = 0x00000000; rq.type = R600_ATOM_CB_CNTL; rq.data = &cb_cntl; rq.nbo = 0; rclear->batch.cb_cntl = r600_atom_create(rw, &rq); /* viewport */ vport.pa_cl_vte_cntl = 0x0000043f; vport.pa_cl_vport_xscale_0 = 0x42fa0000; vport.pa_cl_vport_xoffset_0 = 0x42fa0000; vport.pa_cl_vport_yscale_0 = 0xc2fa0000; vport.pa_cl_vport_yoffset_0 = 0x42fa0000; vport.pa_cl_vport_zscale_0 = 0x3f000000; vport.pa_cl_vport_zoffset_0 = 0x3f000000; rq.type = R600_ATOM_VIEWPORT; rq.data = &vport; rq.nbo = 0; rclear->batch.viewport = r600_atom_create(rw, &rq); /* blend */ blend.cb_blend0_control = 0x00010001; blend.cb_blend1_control = 0x00000000; blend.cb_blend2_control = 0x00000000; blend.cb_blend3_control = 0x00000000; blend.cb_blend4_control = 0x00000000; blend.cb_blend5_control = 0x00000000; blend.cb_blend6_control = 0x00000000; blend.cb_blend7_control = 0x00000000; blend.cb_blend_control = 0x00010001; rq.type = R600_ATOM_BLEND; rq.data = &blend; rq.nbo = 0; rclear->batch.blend = r600_atom_create(rw, &rq); /* ps constant */ rclear->batch.ps_constants = NULL; /* vs constant */ vs_constants.nconstants = 4; vs_constants.offset = 0x400; memcpy(vs_constants.constants, vsconstants, vs_constants.nconstants * 4 * 4); rq.type = R600_ATOM_CONSTANTS; rq.data = &vs_constants; rq.nbo = 0; rclear->batch.vs_constants = r600_atom_create(rw, &rq); /* depth stencil alpha */ dsa.db_stencil_clear = 0x00000000; dsa.db_depth_clear = 0x3F800000; dsa.db_stencilrefmask = 0xFFFFFF00; dsa.db_stencilrefmask_bf = 0xFFFFFF00; dsa.db_depth_control = 0x00700700; dsa.db_shader_control = 0x00000210; dsa.db_render_control = 0x00000060; dsa.db_render_override = 0x0000002A; dsa.db_alpha_to_mask = 0x0000AA00; dsa.db_sresults_compare_state1 = 0x00000000; dsa.db_preload_control = 0x00000000; rq.type = R600_ATOM_DSA; rq.data = &dsa; rq.nbo = 0; rclear->batch.dsa = r600_atom_create(rw, &rq); /* vs_shader */ vs_shader.ninputs = 2; vs_shader.input_semantic[0] = 1; vs_shader.input_gpr[0] = 1; vs_shader.input_semantic[1] = 2; vs_shader.input_gpr[1] = 2; vs_shader.noutputs = 1; vs_shader.output_semantic[0] = 4; vs_shader.sq_pgm_resources_vs = 0x00000006; vs_shader.ndwords = 64; vs_shader.handle = vs->handle; vs_shader.offset = 0; rq.bo[0] = vs; rq.nbo = 1; rq.type = R600_ATOM_VS_SHADER; rq.data = &vs_shader; rclear->batch.vs_shader = r600_atom_create(rw, &rq); /* ps_shader */ fs_shader.spi_ps_input_cntl[0] = 0x00000804; fs_shader.spi_ps_input_cntl[1] = 0x00000000; fs_shader.spi_ps_in_control_0 = 0x10000001; fs_shader.spi_ps_in_control_1 = 0x00000000; fs_shader.sq_pgm_resources_ps = 0x00000003; fs_shader.sq_pgm_exports_ps = 0x00000002; fs_shader.ndwords = 20; fs_shader.handle = fs->handle; fs_shader.offset = 0; rq.bo[0] = fs; rq.nbo = 1; rq.type = R600_ATOM_FS_SHADER; rq.data = &fs_shader; rclear->batch.fs_shader = r600_atom_create(rw, &rq); /* inputs */ vs_resource.nresource = 2; vs_resource.resource[0].handle = vbo->handle; vs_resource.resource[0].resource_id = 0; vs_resource.resource[0].sq_vtx_constant_word0 = 0x00000000; vs_resource.resource[0].sq_vtx_constant_word1 = vbo->size; vs_resource.resource[0].sq_vtx_constant_word2 = 0x03001C00; vs_resource.resource[0].sq_vtx_constant_word3 = 0x00000001; vs_resource.resource[0].sq_vtx_constant_word4 = 0x00000000; vs_resource.resource[0].sq_vtx_constant_word5 = 0x00000000; vs_resource.resource[0].sq_vtx_constant_word6 = 0xC0000000; vs_resource.resource[1].handle = vbo->handle; vs_resource.resource[1].resource_id = 1; vs_resource.resource[1].sq_vtx_constant_word0 = 0x0000000C; vs_resource.resource[1].sq_vtx_constant_word1 = vbo->size - 0xC; vs_resource.resource[1].sq_vtx_constant_word2 = 0x02301C00; vs_resource.resource[1].sq_vtx_constant_word3 = 0x00000001; vs_resource.resource[1].sq_vtx_constant_word4 = 0x00000000; vs_resource.resource[1].sq_vtx_constant_word5 = 0x00000000; vs_resource.resource[1].sq_vtx_constant_word6 = 0xC0000000; rq.bo[0] = vbo; rq.bo[1] = vbo; rq.nbo = 2; rq.type = R600_ATOM_SHADER_RESOURCE; rq.data = &vs_resource; rclear->batch.vs_resource = r600_atom_create(rw, &rq); rclear->batch.vgt_primitive_type = 5; rclear->batch.vgt_dma_index_type = 0; rclear->batch.vgt_dma_num_instances = 1; rclear->batch.vgt_num_indices = 4; rclear->batch.vgt_draw_initiator = 2; out_err: radeon_bo_unref(vbo); radeon_bo_unref(fs); radeon_bo_unref(vs); return r; }