📄 r128_state.c
字号:
/* r128_state.c -- State support for r128 -*- linux-c -*- * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com * * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * 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 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 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 NONINFRINGEMENT. IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS 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: * Gareth Hughes <gareth@valinux.com> */#include "drmP.h"#include "drm.h"#include "r128_drm.h"#include "r128_drv.h"/* ================================================================ * CCE hardware state programming functions */static void r128_emit_clip_rects(drm_r128_private_t * dev_priv, drm_clip_rect_t * boxes, int count){ u32 aux_sc_cntl = 0x00000000; RING_LOCALS; DRM_DEBUG(" %s\n", __FUNCTION__); BEGIN_RING((count < 3 ? count : 3) * 5 + 2); if (count >= 1) { OUT_RING(CCE_PACKET0(R128_AUX1_SC_LEFT, 3)); OUT_RING(boxes[0].x1); OUT_RING(boxes[0].x2 - 1); OUT_RING(boxes[0].y1); OUT_RING(boxes[0].y2 - 1); aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR); } if (count >= 2) { OUT_RING(CCE_PACKET0(R128_AUX2_SC_LEFT, 3)); OUT_RING(boxes[1].x1); OUT_RING(boxes[1].x2 - 1); OUT_RING(boxes[1].y1); OUT_RING(boxes[1].y2 - 1); aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR); } if (count >= 3) { OUT_RING(CCE_PACKET0(R128_AUX3_SC_LEFT, 3)); OUT_RING(boxes[2].x1); OUT_RING(boxes[2].x2 - 1); OUT_RING(boxes[2].y1); OUT_RING(boxes[2].y2 - 1); aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR); } OUT_RING(CCE_PACKET0(R128_AUX_SC_CNTL, 0)); OUT_RING(aux_sc_cntl); ADVANCE_RING();}static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv){ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG(" %s\n", __FUNCTION__); BEGIN_RING(2); OUT_RING(CCE_PACKET0(R128_SCALE_3D_CNTL, 0)); OUT_RING(ctx->scale_3d_cntl); ADVANCE_RING();}static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv){ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG(" %s\n", __FUNCTION__); BEGIN_RING(13); OUT_RING(CCE_PACKET0(R128_DST_PITCH_OFFSET_C, 11)); OUT_RING(ctx->dst_pitch_offset_c); OUT_RING(ctx->dp_gui_master_cntl_c); OUT_RING(ctx->sc_top_left_c); OUT_RING(ctx->sc_bottom_right_c); OUT_RING(ctx->z_offset_c); OUT_RING(ctx->z_pitch_c); OUT_RING(ctx->z_sten_cntl_c); OUT_RING(ctx->tex_cntl_c); OUT_RING(ctx->misc_3d_state_cntl_reg); OUT_RING(ctx->texture_clr_cmp_clr_c); OUT_RING(ctx->texture_clr_cmp_msk_c); OUT_RING(ctx->fog_color_c); ADVANCE_RING();}static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv){ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG(" %s\n", __FUNCTION__); BEGIN_RING(3); OUT_RING(CCE_PACKET1(R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP)); OUT_RING(ctx->setup_cntl); OUT_RING(ctx->pm4_vc_fpu_setup); ADVANCE_RING();}static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv){ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG(" %s\n", __FUNCTION__); BEGIN_RING(5); OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0)); OUT_RING(ctx->dp_write_mask); OUT_RING(CCE_PACKET0(R128_STEN_REF_MASK_C, 1)); OUT_RING(ctx->sten_ref_mask_c); OUT_RING(ctx->plane_3d_mask_c); ADVANCE_RING();}static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv){ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG(" %s\n", __FUNCTION__); BEGIN_RING(2); OUT_RING(CCE_PACKET0(R128_WINDOW_XY_OFFSET, 0)); OUT_RING(ctx->window_xy_offset); ADVANCE_RING();}static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv){ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0]; int i; RING_LOCALS; DRM_DEBUG(" %s\n", __FUNCTION__); BEGIN_RING(7 + R128_MAX_TEXTURE_LEVELS); OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C, 2 + R128_MAX_TEXTURE_LEVELS)); OUT_RING(tex->tex_cntl); OUT_RING(tex->tex_combine_cntl); OUT_RING(ctx->tex_size_pitch_c); for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) { OUT_RING(tex->tex_offset[i]); } OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1)); OUT_RING(ctx->constant_color_c); OUT_RING(tex->tex_border_color); ADVANCE_RING();}static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv){ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1]; int i; RING_LOCALS; DRM_DEBUG(" %s\n", __FUNCTION__); BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS); OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS)); OUT_RING(tex->tex_cntl); OUT_RING(tex->tex_combine_cntl); for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) { OUT_RING(tex->tex_offset[i]); } OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0)); OUT_RING(tex->tex_border_color); ADVANCE_RING();}static __inline__ void r128_emit_state(drm_r128_private_t * dev_priv){ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; DRM_DEBUG("%s: dirty=0x%08x\n", __FUNCTION__, dirty); if (dirty & R128_UPLOAD_CORE) { r128_emit_core(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_CORE; } if (dirty & R128_UPLOAD_CONTEXT) { r128_emit_context(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT; } if (dirty & R128_UPLOAD_SETUP) { r128_emit_setup(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_SETUP; } if (dirty & R128_UPLOAD_MASKS) { r128_emit_masks(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_MASKS; } if (dirty & R128_UPLOAD_WINDOW) { r128_emit_window(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_WINDOW; } if (dirty & R128_UPLOAD_TEX0) { r128_emit_tex0(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_TEX0; } if (dirty & R128_UPLOAD_TEX1) { r128_emit_tex1(dev_priv); sarea_priv->dirty &= ~R128_UPLOAD_TEX1; } /* Turn off the texture cache flushing */ sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE;}#if R128_PERFORMANCE_BOXES/* ================================================================ * Performance monitoring functions */static void r128_clear_box(drm_r128_private_t * dev_priv, int x, int y, int w, int h, int r, int g, int b){ u32 pitch, offset; u32 fb_bpp, color; RING_LOCALS; switch (dev_priv->fb_bpp) { case 16: fb_bpp = R128_GMC_DST_16BPP; color = (((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); break; case 24: fb_bpp = R128_GMC_DST_24BPP; color = ((r << 16) | (g << 8) | b); break; case 32: fb_bpp = R128_GMC_DST_32BPP; color = (((0xff) << 24) | (r << 16) | (g << 8) | b); break; default: return; } offset = dev_priv->back_offset; pitch = dev_priv->back_pitch >> 3; BEGIN_RING(6); OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | fb_bpp | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS); OUT_RING((pitch << 21) | (offset >> 5)); OUT_RING(color); OUT_RING((x << 16) | y); OUT_RING((w << 16) | h); ADVANCE_RING();}static void r128_cce_performance_boxes(drm_r128_private_t * dev_priv){ if (atomic_read(&dev_priv->idle_count) == 0) { r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); } else { atomic_set(&dev_priv->idle_count, 0); }}#endif/* ================================================================ * CCE command dispatch functions */static void r128_print_dirty(const char *msg, unsigned int flags){ DRM_INFO("%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", msg, flags, (flags & R128_UPLOAD_CORE) ? "core, " : "", (flags & R128_UPLOAD_CONTEXT) ? "context, " : "", (flags & R128_UPLOAD_SETUP) ? "setup, " : "", (flags & R128_UPLOAD_TEX0) ? "tex0, " : "", (flags & R128_UPLOAD_TEX1) ? "tex1, " : "", (flags & R128_UPLOAD_MASKS) ? "masks, " : "", (flags & R128_UPLOAD_WINDOW) ? "window, " : "", (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "");}static void r128_cce_dispatch_clear(drm_device_t * dev, drm_r128_clear_t * clear){ drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; unsigned int flags = clear->flags; int i; RING_LOCALS; DRM_DEBUG("%s\n", __FUNCTION__); if (dev_priv->page_flipping && dev_priv->current_page == 1) { unsigned int tmp = flags; flags &= ~(R128_FRONT | R128_BACK); if (tmp & R128_FRONT) flags |= R128_BACK; if (tmp & R128_BACK) flags |= R128_FRONT; } for (i = 0; i < nbox; i++) { int x = pbox[i].x1; int y = pbox[i].y1; int w = pbox[i].x2 - x; int h = pbox[i].y2 - y; DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n", pbox[i].x1, pbox[i].y1, pbox[i].x2, pbox[i].y2, flags); if (flags & (R128_FRONT | R128_BACK)) { BEGIN_RING(2); OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0)); OUT_RING(clear->color_mask); ADVANCE_RING(); } if (flags & R128_FRONT) { BEGIN_RING(6); OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | (dev_priv->color_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS); OUT_RING(dev_priv->front_pitch_offset_c); OUT_RING(clear->clear_color); OUT_RING((x << 16) | y); OUT_RING((w << 16) | h); ADVANCE_RING(); } if (flags & R128_BACK) { BEGIN_RING(6); OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | (dev_priv->color_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS); OUT_RING(dev_priv->back_pitch_offset_c); OUT_RING(clear->clear_color); OUT_RING((x << 16) | y); OUT_RING((w << 16) | h); ADVANCE_RING(); } if (flags & R128_DEPTH) { BEGIN_RING(6); OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | (dev_priv->depth_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS); OUT_RING(dev_priv->depth_pitch_offset_c); OUT_RING(clear->clear_depth); OUT_RING((x << 16) | y); OUT_RING((w << 16) | h); ADVANCE_RING(); } }}static void r128_cce_dispatch_swap(drm_device_t * dev){ drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; int i; RING_LOCALS; DRM_DEBUG("%s\n", __FUNCTION__);#if R128_PERFORMANCE_BOXES /* Do some trivial performance monitoring... */ r128_cce_performance_boxes(dev_priv);#endif for (i = 0; i < nbox; i++) { int x = pbox[i].x1; int y = pbox[i].y1; int w = pbox[i].x2 - x; int h = pbox[i].y2 - y; BEGIN_RING(7); OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_NONE | (dev_priv->color_fmt << 8) | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_S | R128_DP_SRC_SOURCE_MEMORY | R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS); /* Make this work even if front & back are flipped: */ if (dev_priv->current_page == 0) { OUT_RING(dev_priv->back_pitch_offset_c); OUT_RING(dev_priv->front_pitch_offset_c); } else { OUT_RING(dev_priv->front_pitch_offset_c); OUT_RING(dev_priv->back_pitch_offset_c); } OUT_RING((x << 16) | y); OUT_RING((x << 16) | y); OUT_RING((w << 16) | h); ADVANCE_RING(); } /* Increment the frame counter. The client-side 3D driver must * throttle the framerate by waiting for this value before * performing the swapbuffer ioctl. */ dev_priv->sarea_priv->last_frame++; BEGIN_RING(2); OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0)); OUT_RING(dev_priv->sarea_priv->last_frame); ADVANCE_RING();}static void r128_cce_dispatch_flip(drm_device_t * dev){ drm_r128_private_t *dev_priv = dev->dev_private; RING_LOCALS; DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", __FUNCTION__, dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage);#if R128_PERFORMANCE_BOXES /* Do some trivial performance monitoring... */ r128_cce_performance_boxes(dev_priv);#endif BEGIN_RING(4); R128_WAIT_UNTIL_PAGE_FLIPPED(); OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0)); if (dev_priv->current_page == 0) { OUT_RING(dev_priv->back_offset); } else { OUT_RING(dev_priv->front_offset); } ADVANCE_RING(); /* Increment the frame counter. The client-side 3D driver must * throttle the framerate by waiting for this value before * performing the swapbuffer ioctl. */ dev_priv->sarea_priv->last_frame++; dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = 1 - dev_priv->current_page; BEGIN_RING(2); OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0)); OUT_RING(dev_priv->sarea_priv->last_frame); ADVANCE_RING();}static void r128_cce_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf){ drm_r128_private_t *dev_priv = dev->dev_private;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -