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