1 /* 2 * Copyright 2010 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * Gerald Zajac 7 */ 8 9 #include "accelerant.h" 10 #include "3dfx.h" 11 12 13 14 bool 15 TDFX_DisplayOverlay(const overlay_window* window, 16 const overlay_buffer* buffer, 17 const overlay_view* view) 18 { 19 // Return true if setup is successful. 20 21 SharedInfo& si = *gInfo.sharedInfo; 22 23 if (window == NULL || buffer == NULL || view == NULL) 24 return false; 25 26 if (window->flags & B_OVERLAY_COLOR_KEY) { 27 uint32 color = 0; 28 29 if (si.displayMode.bitsPerPixel == 16) { 30 color = (window->blue.value & window->blue.mask) << 0 31 | (window->green.value & window->green.mask) << 5 32 | (window->red.value & window->red.mask) << 11; 33 // 16 bit color has no alpha bits 34 } else { 35 color = (window->blue.value & window->blue.mask) << 0 36 | (window->green.value & window->green.mask) << 8 37 | (window->red.value & window->red.mask) << 16 38 | (window->alpha.value & window->alpha.mask) << 24; 39 } 40 41 TDFX_WaitForFifo(2); 42 OUTREG32(VIDEO_CHROMA_MIN, color); 43 OUTREG32(VIDEO_CHROMA_MAX, color); 44 } 45 46 uint32 videoConfig = INREG32(VIDEO_PROC_CONFIG); 47 videoConfig &= ~VIDEO_PROC_CONFIG_MASK; 48 videoConfig |= (0x00000320 | OVERLAY_CLUT_BYPASS); 49 50 // Scale image if window dimension is larger than the buffer dimension. 51 // Scaling is not done if window dimension is smaller since the chip only 52 // scales up to a larger dimension, and does not scale down to a smaller 53 // dimension. 54 55 if (window->width > buffer->width) 56 videoConfig |= (1 << 14); 57 if (window->height > buffer->height) 58 videoConfig |= (1 << 15); 59 60 switch (buffer->space) { 61 case B_YCbCr422: 62 videoConfig |= VIDCFG_OVL_FMT_YUYV422; 63 break; 64 case B_RGB16: 65 videoConfig |= VIDCFG_OVL_FMT_RGB565; 66 break; 67 default: 68 return false; // color space not supported 69 } 70 71 // can't do bilinear filtering when in 2X mode 72 if ((videoConfig & VIDEO_2X_MODE_ENABLE) == 0) 73 videoConfig |= (3 << 16); 74 75 TDFX_WaitForFifo(1); 76 OUTREG32(VIDEO_PROC_CONFIG, videoConfig); 77 78 // Subtract 1 from height to eliminate junk on last line of image. 79 int32 dudx = (buffer->width << 20) / window->width; 80 int32 dudy = ((buffer->height - 1) << 20) / window->height; 81 82 int32 x1 = (window->h_start < 0) ? 0 : window->h_start; 83 int32 y1 = (window->v_start < 0) ? 0 : window->v_start; 84 85 int32 x2 = x1 + window->width - 1; 86 int32 y2 = y1 + window->height - 1; 87 88 TDFX_WaitForFifo(6); 89 90 // Set up coordinates of overlay window on screen. 91 OUTREG32(VIDEO_OVERLAY_START_COORDS, x1 | (y1 << 12)); 92 OUTREG32(VIDEO_OVERLAY_END_COORDS, x2 | (y2 << 12)); 93 // Set up scale and position of overlay in graphics memory. 94 OUTREG32(VIDEO_OVERLAY_DUDX, dudx); 95 OUTREG32(VIDEO_OVERLAY_DUDX_OFFSET_SRC_WIDTH, ((x1 & 0x0001ffff) << 3) 96 | (buffer->width << 20)); 97 OUTREG32(VIDEO_OVERLAY_DVDY, dudy); 98 OUTREG32(VIDEO_OVERLAY_DVDY_OFFSET, (y1 & 0x0000ffff) << 3); 99 100 // Add width of overlay buffer to stride. 101 uint32 stride = INREG32(VIDEO_DESKTOP_OVERLAY_STRIDE) & 0x0000ffff; 102 stride |= (buffer->width << 1) << 16; 103 uint32 offset = (uint32)(addr_t)buffer->buffer_dma; 104 105 TDFX_WaitForFifo(2); 106 107 OUTREG32(VIDEO_DESKTOP_OVERLAY_STRIDE, stride); 108 OUTREG32(VIDEO_IN_ADDR0, offset); 109 110 return true; 111 } 112 113 114 void 115 TDFX_StopOverlay(void) 116 { 117 // reset the video 118 uint32 videoConfig = INREG32(VIDEO_PROC_CONFIG) & ~VIDEO_PROC_CONFIG_MASK; 119 OUTREG32(VIDEO_PROC_CONFIG, videoConfig); 120 OUTREG32(RGB_MAX_DELTA, 0x0080808); 121 } 122