1/*
2	Haiku ATI video driver adapted from the X.org ATI driver which has the
3	following copyright:
4
5	Copyright 2003 through 2004 by Marc Aurele La France, tsi@xfree86.org
6
7	Copyright 2011 Haiku, Inc.  All rights reserved.
8	Distributed under the terms of the MIT license.
9
10	Authors:
11	Gerald Zajac
12*/
13
14#include "accelerant.h"
15#include "mach64.h"
16
17
18
19bool
20Mach64_DisplayOverlay(const overlay_window* window,
21						const overlay_buffer* buffer)
22{
23	// Return true if setup is successful.
24
25	SharedInfo& si = *gInfo.sharedInfo;
26
27	if (window == NULL || buffer == NULL)
28		return false;
29
30	uint32 videoFormat;
31
32	if (buffer->space == B_YCbCr422)
33		videoFormat = SCALE_IN_VYUY422;
34	else
35		return false;	// color space not supported
36
37	int32 x1 = (window->h_start < 0) ? 0 : window->h_start;
38	int32 y1 = (window->v_start < 0) ? 0 : window->v_start;
39
40	int32 x2 = window->h_start + window->width - 1;
41	int32 y2 = window->v_start + window->height - 1;
42
43	if (x2 > si.displayMode.timing.h_display)
44		x2 = si.displayMode.timing.h_display;
45
46	if (y2 > si.displayMode.timing.v_display)
47		y2 = si.displayMode.timing.v_display;
48
49	// If window is moved beyond edge of screen, do not allow width < 4 or
50	// height < 4;  otherwise there is a possibilty of divide by zero when
51	// computing the scale factors..
52	if (x2 < x1 + 4)
53		x2 = x1 + 4;
54
55	if (y2 < y1 + 4)
56		y2 = y1 + 4;
57
58	// Calculate overlay scale factors.
59	uint32 horzScale = (buffer->width << 12) / (x2 - x1 + 1);
60	uint32 vertScale = (buffer->height << 12) / (y2 - y1 + 1);
61
62	if (horzScale > 0xffff)		// only 16 bits are used for scale factors
63		horzScale = 0xffff;
64	if (vertScale > 0xffff)
65		vertScale = 0xffff;
66
67	gInfo.WaitForFifo(2);
68	OUTREG(BUS_CNTL, INREG(BUS_CNTL) | BUS_EXT_REG_EN);	// enable reg block 1
69	OUTREG(OVERLAY_SCALE_CNTL, SCALE_EN);	// reset the video
70
71	if (si.chipType >= MACH64_264GTPRO) {
72		const uint32 brightness = 0;
73		const uint32 saturation = 12;
74
75		gInfo.WaitForFifo(6);
76		OUTREG(SCALER_COLOUR_CNTL, brightness | saturation << 8
77			| saturation << 16);
78		OUTREG(SCALER_H_COEFF0, 0x0002000);
79		OUTREG(SCALER_H_COEFF1, 0xd06200d);
80		OUTREG(SCALER_H_COEFF2, 0xd0a1c0d);
81		OUTREG(SCALER_H_COEFF3, 0xc0e1a0c);
82		OUTREG(SCALER_H_COEFF4, 0xc14140c);
83	}
84
85	uint32 keyColor = 0;
86	uint32 keyMask = 0;
87
88	switch (si.displayMode.bitsPerPixel) {
89		case 15:
90			keyMask = 0x7fff;
91			keyColor = (window->blue.value & window->blue.mask) << 0
92				| (window->green.value & window->green.mask) << 5
93				| (window->red.value & window->red.mask) << 10;
94				// 15 bit color has no alpha bits
95			break;
96		case 16:
97			keyMask = 0xffff;
98			keyColor = (window->blue.value & window->blue.mask) << 0
99				| (window->green.value & window->green.mask) << 5
100				| (window->red.value & window->red.mask) << 11;
101				// 16 bit color has no alpha bits
102			break;
103		default:
104			keyMask = 0xffffffff;
105			keyColor = (window->blue.value & window->blue.mask) << 0
106				| (window->green.value & window->green.mask) << 8
107				| (window->red.value & window->red.mask) << 16
108				| (window->alpha.value & window->alpha.mask) << 24;
109			break;
110	}
111
112	gInfo.WaitForFifo(3);
113	OUTREG(OVERLAY_GRAPHICS_KEY_MSK, keyMask);
114	OUTREG(OVERLAY_GRAPHICS_KEY_CLR, keyColor);
115	OUTREG(OVERLAY_KEY_CNTL, OVERLAY_MIX_FALSE | OVERLAY_MIX_EQUAL);
116
117	gInfo.WaitForFifo(8);
118	OUTREG(OVERLAY_Y_X_START, OVERLAY_LOCK_START | (x1 << 16) | y1);
119	OUTREG(OVERLAY_Y_X_END, (x2 << 16) | y2);
120	OUTREG(OVERLAY_SCALE_INC, (horzScale << 16) | vertScale);
121	OUTREG(SCALER_HEIGHT_WIDTH, (buffer->width << 16) | buffer->height);
122	OUTREG(VIDEO_FORMAT, videoFormat);
123
124	// Compute offset of overlay buffer in the video memory.
125	uint32 offset = (uint32)((addr_t)buffer->buffer - si.videoMemAddr);
126
127	if (si.chipType < MACH64_264VTB) {
128		OUTREG(BUF0_OFFSET, offset);
129		OUTREG(BUF0_PITCH, buffer->width);
130	} else {
131		OUTREG(SCALER_BUF0_OFFSET, offset);
132		OUTREG(SCALER_BUF0_PITCH, buffer->width);
133	}
134
135	OUTREG(OVERLAY_SCALE_CNTL, SCALE_PIX_EXPAND | OVERLAY_EN | SCALE_EN);
136
137	return true;
138}
139
140
141void
142Mach64_StopOverlay(void)
143{
144	OUTREG(OVERLAY_SCALE_CNTL, SCALE_EN);	// reset the video
145}
146