* Fixed some warnings.
* I forgot to mention it before, but this driver seems to have been written by Erdi Chen. * Some cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18979 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
b9ecaef57a
commit
b83fe28463
@ -2,12 +2,13 @@
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#if !defined(GLOBALDATA_H)
|
||||
#ifndef GLOBALDATA_H
|
||||
#define GLOBALDATA_H
|
||||
|
||||
|
||||
#include "DriverInterface.h"
|
||||
|
||||
|
||||
extern int fd;
|
||||
extern shared_info *si;
|
||||
extern area_id shared_info_area;
|
||||
@ -22,4 +23,10 @@ extern int accelerantIsClone;
|
||||
/* Print debug message through kernel driver. Should move to other location later. */
|
||||
extern void dpf (const char * format, ...);
|
||||
|
||||
/* ProposeDisplayMode.c */
|
||||
extern status_t create_mode_list(void);
|
||||
|
||||
/* Cursor.c */
|
||||
extern void set_cursor_colors(void);
|
||||
|
||||
#endif
|
||||
|
@ -12,31 +12,35 @@
|
||||
#include "s3mmio.h"
|
||||
#include "s3accel.h"
|
||||
|
||||
#include "errno.h"
|
||||
#include "fcntl.h"
|
||||
#include "string.h"
|
||||
#include "unistd.h"
|
||||
#include "sys/types.h"
|
||||
#include "sys/stat.h"
|
||||
#include "fcntl.h"
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/* defined in ProposeDisplayMode.c */
|
||||
extern status_t create_mode_list(void);
|
||||
/* defined in Cursor.c */
|
||||
extern void set_cursor_colors(void);
|
||||
|
||||
/* Get the linear address of an area. Workaround for BeOS bug that
|
||||
returns invalid pointer from clone_area. */
|
||||
static void * __get_area_address (area_id area)
|
||||
/*!
|
||||
Get the linear address of an area. Workaround for BeOS bug that
|
||||
returns invalid pointer from clone_area.
|
||||
*/
|
||||
static void *
|
||||
get_area_address(area_id area)
|
||||
{
|
||||
area_info ai;
|
||||
get_area_info (area, &ai);
|
||||
get_area_info(area, &ai);
|
||||
return ai.address;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// unused!
|
||||
// Determines the amount of card memory available by seeing how far up
|
||||
// the frame buffer data can be written and read back reliably. Does a
|
||||
// paranoia check to make sure that it isn't just wrapping, either.
|
||||
unsigned long Get_Card_Mem_Size()
|
||||
unsigned long
|
||||
Get_Card_Mem_Size()
|
||||
{
|
||||
// Allowed sizes actually go up to 16 megs, but clip at the
|
||||
// register window for now.
|
||||
@ -115,13 +119,12 @@ unsigned long Get_Card_Mem_Size()
|
||||
|
||||
return MaxMem;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static status_t init_common(int the_fd);
|
||||
|
||||
/* Initialization code shared between primary and cloned accelerants */
|
||||
static status_t init_common(int the_fd)
|
||||
static status_t
|
||||
init_common(int the_fd)
|
||||
{
|
||||
status_t result;
|
||||
savage_get_private_data gpd;
|
||||
@ -132,64 +135,57 @@ static status_t init_common(int the_fd)
|
||||
/* set the magic number so the driver knows we're for real */
|
||||
gpd.magic = SAVAGE_PRIVATE_DATA_MAGIC;
|
||||
/* contact driver and get a pointer to the registers and shared data */
|
||||
result = ioctl(fd, SAVAGE_GET_PRIVATE_DATA, &gpd, sizeof(gpd));
|
||||
if (result != B_OK) goto error0;
|
||||
if (ioctl(fd, SAVAGE_GET_PRIVATE_DATA, &gpd, sizeof(gpd)) != 0)
|
||||
return errno;
|
||||
|
||||
/* clone the shared area for our use */
|
||||
shared_info_area = clone_area (
|
||||
"SAVAGE shared info", (void **)&si, B_ANY_ADDRESS,
|
||||
B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area);
|
||||
shared_info_area = clone_area("SAVAGE shared info", (void **)&si,
|
||||
B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area);
|
||||
if (shared_info_area < 0)
|
||||
{
|
||||
result = shared_info_area;
|
||||
goto error0;
|
||||
}
|
||||
return shared_info_area;
|
||||
|
||||
/* clone the memory mapped registers for our use */
|
||||
regs_area = clone_area (
|
||||
"SAVAGE regs area", (void **)®s, B_ANY_ADDRESS,
|
||||
regs_area = clone_area("SAVAGE regs area", (void **)®s, B_ANY_ADDRESS,
|
||||
B_READ_AREA | B_WRITE_AREA, si->regs_area);
|
||||
if (regs_area < 0)
|
||||
{
|
||||
if (regs_area < 0) {
|
||||
result = regs_area;
|
||||
goto error1;
|
||||
}
|
||||
regs = __get_area_address (regs_area);
|
||||
regs = get_area_address(regs_area);
|
||||
|
||||
dpf ("PCI VENDOR_ID = 0x%4X, DEVICE_ID = 0x%4X\n",
|
||||
read16 ((byte_t*)regs + 0x8000),
|
||||
read16 ((byte_t*)regs + 0x8002));
|
||||
dpf("PCI VENDOR_ID = 0x%4X, DEVICE_ID = 0x%4X\n",
|
||||
read16((byte_t*)regs + 0x8000),
|
||||
read16((byte_t*)regs + 0x8002));
|
||||
|
||||
/* clone the framebuffer buffer for our use */
|
||||
fb_area = clone_area (
|
||||
"SAVAGE fb area", (void **)&framebuffer, B_ANY_ADDRESS,
|
||||
B_READ_AREA | B_WRITE_AREA, si->fb_area);
|
||||
if (fb_area < 0)
|
||||
{
|
||||
fb_area = clone_area("SAVAGE fb area", (void **)&framebuffer,
|
||||
B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, si->fb_area);
|
||||
if (fb_area < 0) {
|
||||
result = regs_area;
|
||||
goto error2;
|
||||
}
|
||||
framebuffer = __get_area_address (fb_area);
|
||||
framebuffer = get_area_address(fb_area);
|
||||
|
||||
s3drv_init ((byte_t*)regs);
|
||||
s3drv_init((byte_t*)regs);
|
||||
dpf ("s3drv_init called\n");
|
||||
s3accel_init (s3drv_get_context ());
|
||||
s3accel_init(s3drv_get_context());
|
||||
dpf ("s3accel_init called\n");
|
||||
s3drv_unlock_regs ();
|
||||
s3drv_unlock_regs();
|
||||
|
||||
/* all done */
|
||||
goto error0;
|
||||
return B_OK;
|
||||
|
||||
error2:
|
||||
delete_area(regs_area);
|
||||
error1:
|
||||
delete_area(shared_info_area);
|
||||
error0:
|
||||
dpf ("init_common done\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Clean up code shared between primary and cloned accelrants */
|
||||
static void uninit_common(void)
|
||||
|
||||
/*! Clean up code shared between primary and cloned accelerants */
|
||||
static void
|
||||
uninit_common(void)
|
||||
{
|
||||
/* release framebuffer area */
|
||||
delete_area (fb_area);
|
||||
@ -204,14 +200,15 @@ static void uninit_common(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Initialize the accelerant. the_fd is the file handle of the device (in
|
||||
/dev/graphics) that has been opened by the app_server (or some test harness).
|
||||
We need to determine if the kernel driver and the accelerant are compatible.
|
||||
If they are, get the accelerant ready to handle other hook functions and
|
||||
report success or failure.
|
||||
/*!
|
||||
Initialize the accelerant. the_fd is the file handle of the device (in
|
||||
/dev/graphics) that has been opened by the app_server (or some test harness).
|
||||
We need to determine if the kernel driver and the accelerant are compatible.
|
||||
If they are, get the accelerant ready to handle other hook functions and
|
||||
report success or failure.
|
||||
*/
|
||||
status_t INIT_ACCELERANT(int the_fd)
|
||||
status_t
|
||||
INIT_ACCELERANT(int the_fd)
|
||||
{
|
||||
status_t result;
|
||||
/* note that we're the primary accelerant (accelerantIsClone is global) */
|
||||
@ -219,9 +216,8 @@ status_t INIT_ACCELERANT(int the_fd)
|
||||
|
||||
/* do the initialization common to both the primary and the clones */
|
||||
result = init_common(the_fd);
|
||||
|
||||
/* bail out if the common initialization failed */
|
||||
if (result != B_OK) goto error0;
|
||||
if (result != B_OK)
|
||||
goto error0;
|
||||
|
||||
/*
|
||||
If there is a possiblity that the kernel driver will recognize a card that
|
||||
@ -269,7 +265,8 @@ status_t INIT_ACCELERANT(int the_fd)
|
||||
Everybody else get's a read-only clone.
|
||||
*/
|
||||
result = create_mode_list();
|
||||
if (result != B_OK) goto error2;
|
||||
if (result != B_OK)
|
||||
goto error2;
|
||||
|
||||
/*
|
||||
Initialize the frame buffer and cursor pointers. Most newer video cards
|
||||
@ -343,11 +340,13 @@ error0:
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Return the number of bytes required to hold the information required
|
||||
to clone the device.
|
||||
|
||||
/*!
|
||||
Return the number of bytes required to hold the information required
|
||||
to clone the device.
|
||||
*/
|
||||
ssize_t ACCELERANT_CLONE_INFO_SIZE(void)
|
||||
ssize_t
|
||||
ACCELERANT_CLONE_INFO_SIZE(void)
|
||||
{
|
||||
/*
|
||||
Since we're passing the name of the device as the only required
|
||||
@ -357,11 +356,12 @@ ssize_t ACCELERANT_CLONE_INFO_SIZE(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Return the info required to clone the device. void *data points to
|
||||
a buffer at least ACCELERANT_CLONE_INFO_SIZE() bytes in length.
|
||||
/*!
|
||||
Return the info required to clone the device. void *data points to
|
||||
a buffer at least ACCELERANT_CLONE_INFO_SIZE() bytes in length.
|
||||
*/
|
||||
void GET_ACCELERANT_CLONE_INFO(void *data)
|
||||
void
|
||||
GET_ACCELERANT_CLONE_INFO(void *data)
|
||||
{
|
||||
savage_device_name dn;
|
||||
status_t result;
|
||||
@ -373,48 +373,41 @@ void GET_ACCELERANT_CLONE_INFO(void *data)
|
||||
result = ioctl(fd, SAVAGE_DEVICE_NAME, &dn, sizeof(dn));
|
||||
}
|
||||
|
||||
/*
|
||||
Initialize a copy of the accelerant as a clone. void *data points to
|
||||
a copy of the data returned by GET_ACCELERANT_CLONE_INFO().
|
||||
|
||||
/*!
|
||||
Initialize a copy of the accelerant as a clone. void *data points to
|
||||
a copy of the data returned by GET_ACCELERANT_CLONE_INFO().
|
||||
*/
|
||||
status_t CLONE_ACCELERANT(void *data)
|
||||
status_t
|
||||
CLONE_ACCELERANT(void *data)
|
||||
{
|
||||
status_t result;
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
/* the data is the device name */
|
||||
strcpy(path, "/dev");
|
||||
strcpy(path, "/dev/");
|
||||
strcat(path, (const char *)data);
|
||||
/* open the device, the permissions aren't important */
|
||||
fd = open(path, B_READ_WRITE);
|
||||
if (fd < 0)
|
||||
{
|
||||
result = fd;
|
||||
goto error0;
|
||||
}
|
||||
return errno;
|
||||
|
||||
/* note that we're a clone accelerant */
|
||||
accelerantIsClone = 1;
|
||||
|
||||
/* call the shared initialization code */
|
||||
result = init_common(fd);
|
||||
|
||||
/* bail out if the common initialization failed */
|
||||
if (result != B_OK) goto error1;
|
||||
if (result != B_OK)
|
||||
goto error1;
|
||||
|
||||
/* get shared area for display modes */
|
||||
result = my_mode_list_area = clone_area(
|
||||
"SAVAGE cloned display_modes",
|
||||
(void **)&my_mode_list,
|
||||
B_ANY_ADDRESS,
|
||||
B_READ_AREA,
|
||||
si->mode_area
|
||||
);
|
||||
if (result < B_OK) goto error2;
|
||||
result = my_mode_list_area = clone_area("SAVAGE cloned display_modes",
|
||||
(void **)&my_mode_list, B_ANY_ADDRESS, B_READ_AREA, si->mode_area);
|
||||
if (result < B_OK)
|
||||
goto error2;
|
||||
|
||||
/* all done */
|
||||
result = B_OK;
|
||||
goto error0;
|
||||
return B_OK;
|
||||
|
||||
error2:
|
||||
/* free up the areas we cloned */
|
||||
@ -422,11 +415,12 @@ error2:
|
||||
error1:
|
||||
/* close the device we opened */
|
||||
close(fd);
|
||||
error0:
|
||||
return result;
|
||||
}
|
||||
|
||||
void UNINIT_ACCELERANT(void)
|
||||
|
||||
void
|
||||
UNINIT_ACCELERANT(void)
|
||||
{
|
||||
/* free our mode list area */
|
||||
delete_area(my_mode_list_area);
|
||||
@ -435,10 +429,13 @@ void UNINIT_ACCELERANT(void)
|
||||
/* release our cloned data */
|
||||
uninit_common();
|
||||
/* close the file handle ONLY if we're the clone */
|
||||
if (accelerantIsClone) close(fd);
|
||||
if (accelerantIsClone)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi)
|
||||
|
||||
status_t
|
||||
GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi)
|
||||
{
|
||||
status_t retval;
|
||||
static const char * names1[] =
|
||||
@ -450,17 +447,13 @@ status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi)
|
||||
{ "ProSavage PN133", "ProSavage KN133", "ProSavage P4M266", "ProSavage8 KM266" };
|
||||
|
||||
adi->version = 0x10000;
|
||||
if (si->device_id == PCI_PID_SAVAGE2000)
|
||||
{
|
||||
if (si->device_id == PCI_PID_SAVAGE2000) {
|
||||
strcpy (adi->name, "Savage2000");
|
||||
strcpy (adi->chipset, "Savage2000");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
const char ** names = NULL;
|
||||
int offset = 0;
|
||||
switch (si->device_id & 0xFFF0)
|
||||
{
|
||||
switch (si->device_id & 0xFFF0) {
|
||||
case 0x8a20:
|
||||
names = names1;
|
||||
offset = si->device_id - PCI_PID_SAVAGE3D;
|
||||
@ -474,13 +467,10 @@ status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi)
|
||||
offset = si->device_id - PCI_PID_PN133;
|
||||
break;
|
||||
}
|
||||
if (names != NULL)
|
||||
{
|
||||
if (names != NULL) {
|
||||
strcpy (adi->name, names[offset]);
|
||||
strcpy (adi->chipset, names[offset]);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
strcpy (adi->name, "not supported");
|
||||
strcpy (adi->chipset, "Savage");
|
||||
}
|
||||
|
@ -48,38 +48,34 @@ static const display_mode mode_list[] = {
|
||||
/* create a mask of one "bits" bits wide */
|
||||
#define MASKFROMWIDTH(bits) ((1 << bits) - 1)
|
||||
|
||||
/*
|
||||
Validate a target display mode is both
|
||||
a) a valid display mode for this device and
|
||||
b) falls between the contraints imposed by "low" and "high"
|
||||
/*!
|
||||
Validate a target display mode is both
|
||||
a) a valid display mode for this device and
|
||||
b) falls between the contraints imposed by "low" and "high"
|
||||
|
||||
If the mode is not (or cannot) be made valid for this device, return B_ERROR.
|
||||
If a valid mode can be constructed, but it does not fall within the limits,
|
||||
If the mode is not (or cannot) be made valid for this device, return B_ERROR.
|
||||
If a valid mode can be constructed, but it does not fall within the limits,
|
||||
return B_BAD_VALUE.
|
||||
If the mode is both valid AND falls within the limits, return B_OK.
|
||||
If the mode is both valid AND falls within the limits, return B_OK.
|
||||
*/
|
||||
status_t PROPOSE_DISPLAY_MODE (
|
||||
display_mode *target, const display_mode *low, const display_mode *high)
|
||||
status_t
|
||||
PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low,
|
||||
const display_mode *high)
|
||||
{
|
||||
const uint16 h_display_bits = MASKFROMWIDTH(8);
|
||||
//const uint16 h_display_bits = MASKFROMWIDTH(8);
|
||||
const uint16 h_sync_bits = MASKFROMWIDTH(5);
|
||||
const uint16 h_total_bits = MASKFROMWIDTH(9);
|
||||
const uint16 v_display_bits = MASKFROMWIDTH(11);
|
||||
const uint16 v_sync_bits = MASKFROMWIDTH(5);
|
||||
const uint16 v_total_bits = MASKFROMWIDTH(11);
|
||||
//const uint16 v_total_bits = MASKFROMWIDTH(11);
|
||||
|
||||
status_t
|
||||
result = B_OK;
|
||||
uint32
|
||||
row_bytes,
|
||||
limit_clock;
|
||||
double
|
||||
target_refresh = ((double)target->timing.pixel_clock * 1000.0)
|
||||
status_t result = B_OK;
|
||||
uint32 row_bytes, limit_clock;
|
||||
double target_refresh = ((double)target->timing.pixel_clock * 1000.0)
|
||||
/ ((double)target->timing.h_total
|
||||
* (double)target->timing.v_total);
|
||||
bool
|
||||
want_same_width = target->timing.h_display == target->virtual_width,
|
||||
want_same_height = target->timing.v_display == target->virtual_height;
|
||||
bool want_same_width = target->timing.h_display == target->virtual_width;
|
||||
bool want_same_height = target->timing.v_display == target->virtual_height;
|
||||
|
||||
/*
|
||||
NOTE:
|
||||
@ -109,15 +105,21 @@ status_t PROPOSE_DISPLAY_MODE (
|
||||
uint16 h_total = target->timing.h_total >> 3;
|
||||
|
||||
/* ensure reasonable minium display and sequential order of parms */
|
||||
if (h_display < (320 >> 3)) h_display = 320 >> 3;
|
||||
if (h_display > (2048 >> 3)) h_display = 2048 >> 3;
|
||||
if (h_sync_start < (h_display + 2)) h_sync_start = h_display + 2;
|
||||
if (h_display < (320 >> 3))
|
||||
h_display = 320 >> 3;
|
||||
if (h_display > (2048 >> 3))
|
||||
h_display = 2048 >> 3;
|
||||
if (h_sync_start < (h_display + 2))
|
||||
h_sync_start = h_display + 2;
|
||||
if (h_sync_end < (h_sync_start + 3))
|
||||
h_sync_end = h_sync_start + 3; /*(0x001f >> 2);*/
|
||||
if (h_total < (h_sync_end + 1)) h_total = h_sync_end + 1;
|
||||
if (h_total < (h_sync_end + 1))
|
||||
h_total = h_sync_end + 1;
|
||||
|
||||
/* adjust for register limitations: */
|
||||
/* h_total is 9 bits */
|
||||
if (h_total > h_total_bits) h_total = h_total_bits;
|
||||
if (h_total > h_total_bits)
|
||||
h_total = h_total_bits;
|
||||
/* h_display is 8 bits - handled above */
|
||||
/* h_sync_start is 9 bits */
|
||||
/* h_sync_width is 5 bits */
|
||||
@ -132,17 +134,15 @@ status_t PROPOSE_DISPLAY_MODE (
|
||||
}
|
||||
|
||||
/* did we fall out of one of the limits? */
|
||||
if (
|
||||
(target->timing.h_display < low->timing.h_display) ||
|
||||
(target->timing.h_display > high->timing.h_display) ||
|
||||
(target->timing.h_sync_start < low->timing.h_sync_start) ||
|
||||
(target->timing.h_sync_start > high->timing.h_sync_start) ||
|
||||
(target->timing.h_sync_end < low->timing.h_sync_end) ||
|
||||
(target->timing.h_sync_end > high->timing.h_sync_end) ||
|
||||
(target->timing.h_total < low->timing.h_total) ||
|
||||
(target->timing.h_total > high->timing.h_total)
|
||||
) result = B_BAD_VALUE;
|
||||
|
||||
if (target->timing.h_display < low->timing.h_display
|
||||
|| target->timing.h_display > high->timing.h_display
|
||||
|| target->timing.h_sync_start < low->timing.h_sync_start
|
||||
|| target->timing.h_sync_start > high->timing.h_sync_start
|
||||
|| target->timing.h_sync_end < low->timing.h_sync_end
|
||||
|| target->timing.h_sync_end > high->timing.h_sync_end
|
||||
|| target->timing.h_total < low->timing.h_total
|
||||
|| target->timing.h_total > high->timing.h_total)
|
||||
result = B_BAD_VALUE;
|
||||
|
||||
/* validate vertical timings */
|
||||
{
|
||||
@ -156,14 +156,21 @@ status_t PROPOSE_DISPLAY_MODE (
|
||||
/* v_total is 11 bits */
|
||||
/* v_sync_start is 11 bits */
|
||||
/* v_sync_width is 5 bits */
|
||||
if (v_display < 200) v_display = 200;
|
||||
if (v_display > (v_display_bits - 5)) v_display = (v_display_bits - 5); /* leave room for the sync pulse */
|
||||
if (v_sync_start < (v_display + 1)) v_sync_start = v_display + 1;
|
||||
if (v_sync_end < v_sync_start) v_sync_end = v_sync_start + 3;
|
||||
if (v_total < (v_sync_end + 1)) v_total = v_sync_end + 1;
|
||||
if (v_display < 200)
|
||||
v_display = 200;
|
||||
if (v_display > (v_display_bits - 5))
|
||||
v_display = (v_display_bits - 5); /* leave room for the sync pulse */
|
||||
if (v_sync_start < (v_display + 1))
|
||||
v_sync_start = v_display + 1;
|
||||
if (v_sync_end < v_sync_start)
|
||||
v_sync_end = v_sync_start + 3;
|
||||
if (v_total < (v_sync_end + 1))
|
||||
v_total = v_sync_end + 1;
|
||||
|
||||
/* adjust for register limitations */
|
||||
if ((v_sync_end - v_sync_start) > v_sync_bits)
|
||||
v_sync_end = v_sync_start + v_sync_bits;
|
||||
|
||||
target->timing.v_display = v_display;
|
||||
target->timing.v_sync_start = v_sync_start;
|
||||
target->timing.v_sync_end = v_sync_end;
|
||||
@ -171,16 +178,15 @@ status_t PROPOSE_DISPLAY_MODE (
|
||||
}
|
||||
|
||||
/* did we fall out of one of the limits? */
|
||||
if (
|
||||
(target->timing.v_display < low->timing.v_display) ||
|
||||
(target->timing.v_display > high->timing.v_display) ||
|
||||
(target->timing.v_sync_start < low->timing.v_sync_start) ||
|
||||
(target->timing.v_sync_start > high->timing.h_sync_start) ||
|
||||
(target->timing.v_sync_end < low->timing.v_sync_end) ||
|
||||
(target->timing.v_sync_end > high->timing.v_sync_end) ||
|
||||
(target->timing.v_total < low->timing.v_total) ||
|
||||
(target->timing.v_total > high->timing.v_total)
|
||||
) result = B_BAD_VALUE;
|
||||
if (target->timing.v_display < low->timing.v_display
|
||||
|| target->timing.v_display > high->timing.v_display
|
||||
|| target->timing.v_sync_start < low->timing.v_sync_start
|
||||
|| target->timing.v_sync_start > high->timing.h_sync_start
|
||||
|| target->timing.v_sync_end < low->timing.v_sync_end
|
||||
|| target->timing.v_sync_end > high->timing.v_sync_end
|
||||
|| target->timing.v_total < low->timing.v_total
|
||||
|| target->timing.v_total > high->timing.v_total)
|
||||
result = B_BAD_VALUE;
|
||||
|
||||
/* adjust pixel clock for DAC limits and target refresh rate */
|
||||
/*
|
||||
@ -200,8 +206,7 @@ status_t PROPOSE_DISPLAY_MODE (
|
||||
This is also a convienient place to determine the number of bytes
|
||||
per pixel for a later display pitch calculation.
|
||||
*/
|
||||
switch (target->space & 0x0fff)
|
||||
{
|
||||
switch (target->space & 0x0fff) {
|
||||
case B_CMAP8:
|
||||
limit_clock = si->pix_clk_max8;
|
||||
row_bytes = 1;
|
||||
@ -228,25 +233,23 @@ status_t PROPOSE_DISPLAY_MODE (
|
||||
but I'm lazy */
|
||||
|
||||
/* note if we fell outside the limits */
|
||||
if (
|
||||
(target->timing.pixel_clock < low->timing.pixel_clock) ||
|
||||
(target->timing.pixel_clock > high->timing.pixel_clock)
|
||||
) result = B_BAD_VALUE;
|
||||
if (target->timing.pixel_clock < low->timing.pixel_clock
|
||||
|| target->timing.pixel_clock > high->timing.pixel_clock)
|
||||
result = B_BAD_VALUE;
|
||||
|
||||
/* validate display vs. virtual */
|
||||
if ((target->timing.h_display > target->virtual_width) || want_same_width)
|
||||
if (target->timing.h_display > target->virtual_width || want_same_width)
|
||||
target->virtual_width = target->timing.h_display;
|
||||
if ((target->timing.v_display > target->virtual_height) || want_same_height)
|
||||
if (target->timing.v_display > target->virtual_height || want_same_height)
|
||||
target->virtual_height = target->timing.v_display;
|
||||
if (target->virtual_width > 2048)
|
||||
target->virtual_width = 2048;
|
||||
|
||||
/* adjust virtual width for engine limitations */
|
||||
target->virtual_width = (target->virtual_width + 7) & ~7;
|
||||
if (
|
||||
(target->virtual_width < low->virtual_width) ||
|
||||
(target->virtual_width > high->virtual_width)
|
||||
) result = B_BAD_VALUE;
|
||||
if (target->virtual_width < low->virtual_width
|
||||
|| target->virtual_width > high->virtual_width)
|
||||
result = B_BAD_VALUE;
|
||||
|
||||
/* calculate rowbytes after we've nailed the virtual width */
|
||||
row_bytes *= target->virtual_width;
|
||||
@ -258,13 +261,12 @@ status_t PROPOSE_DISPLAY_MODE (
|
||||
if (target->virtual_height > 2048)
|
||||
target->virtual_height = 2048;
|
||||
|
||||
if (target->virtual_height < target->timing.v_display)
|
||||
if (target->virtual_height < target->timing.v_display) {
|
||||
/* not enough frame buffer memory for the mode */
|
||||
return B_ERROR;
|
||||
else if (
|
||||
(target->virtual_height < low->virtual_height) ||
|
||||
(target->virtual_height > high->virtual_height)
|
||||
) result = B_BAD_VALUE;
|
||||
} else if (target->virtual_height < low->virtual_height
|
||||
|| target->virtual_height > high->virtual_height)
|
||||
result = B_BAD_VALUE;
|
||||
|
||||
/*
|
||||
Bit Flag Encoding
|
||||
@ -277,26 +279,29 @@ status_t PROPOSE_DISPLAY_MODE (
|
||||
0 1 Feature MAY be enabled, prefered enabled
|
||||
1 0 Feature MAY be enabled, prefered disabled
|
||||
1 1 Feature MUST be enabled
|
||||
|
||||
*/
|
||||
/* MORE WORK REQUIRED HERE. Current drivers mostly ignore the flags */
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/*!
|
||||
Return the number of modes this device will return from GET_MODE_LIST().
|
||||
*/
|
||||
uint32 ACCELERANT_MODE_COUNT(void)
|
||||
uint32
|
||||
ACCELERANT_MODE_COUNT(void)
|
||||
{
|
||||
/* return the number of 'built-in' display modes */
|
||||
return si->mode_count;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/*!
|
||||
Copy the list of guaranteed supported video modes to the location
|
||||
provided.
|
||||
*/
|
||||
status_t GET_MODE_LIST(display_mode *dm)
|
||||
status_t
|
||||
GET_MODE_LIST(display_mode *dm)
|
||||
{
|
||||
/* copy them to the buffer pointed at by *dm */
|
||||
memcpy(dm, my_mode_list, si->mode_count * sizeof(display_mode));
|
||||
@ -304,21 +309,16 @@ status_t GET_MODE_LIST(display_mode *dm)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*!
|
||||
Create a list of display_modes to pass back to the caller.
|
||||
*/
|
||||
status_t create_mode_list(void)
|
||||
status_t
|
||||
create_mode_list(void)
|
||||
{
|
||||
size_t max_size;
|
||||
uint32
|
||||
i, j,
|
||||
pix_clk_range;
|
||||
const display_mode
|
||||
*src;
|
||||
display_mode
|
||||
*dst,
|
||||
low,
|
||||
high;
|
||||
uint32 i, j, pix_clk_range;
|
||||
const display_mode *src;
|
||||
display_mode *dst, low, high;
|
||||
|
||||
/*
|
||||
We prefer frame buffers to have the same endianness as the host
|
||||
@ -339,36 +339,38 @@ status_t create_mode_list(void)
|
||||
/* figure out how big the list could be, and adjust up to nearest
|
||||
multiple of B_PAGE_SIZE */
|
||||
max_size = (((MODE_COUNT * sizeof (spaces) / sizeof (color_space))
|
||||
* sizeof(display_mode))
|
||||
+ (B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1);
|
||||
* sizeof(display_mode)) + (B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1);
|
||||
|
||||
/* create an area to hold the info */
|
||||
si->mode_area = my_mode_list_area =
|
||||
create_area (
|
||||
"SAVAGE accelerant mode info", (void **)&my_mode_list,
|
||||
create_area("SAVAGE accelerant mode info", (void **)&my_mode_list,
|
||||
B_ANY_ADDRESS, max_size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||
if (my_mode_list_area < B_OK) return my_mode_list_area;
|
||||
if (my_mode_list_area < B_OK)
|
||||
return my_mode_list_area;
|
||||
|
||||
/* walk through our predefined list and see which modes fit this device */
|
||||
src = mode_list;
|
||||
dst = my_mode_list;
|
||||
si->mode_count = 0;
|
||||
for (i = 0; i < MODE_COUNT; i++)
|
||||
{
|
||||
for (i = 0; i < MODE_COUNT; i++) {
|
||||
/* set ranges for acceptable values */
|
||||
low = high = *src;
|
||||
|
||||
/* range is 6.25% of default clock: arbitrarily picked */
|
||||
pix_clk_range = low.timing.pixel_clock >> 5;
|
||||
low.timing.pixel_clock -= pix_clk_range;
|
||||
high.timing.pixel_clock += pix_clk_range;
|
||||
/* some cards need wider virtual widths for certain modes */
|
||||
high.virtual_width = 2048;
|
||||
|
||||
/* do it once for each depth we want to support */
|
||||
for (j = 0; j < (sizeof(spaces) / sizeof(color_space)); j++) {
|
||||
/* set target values */
|
||||
*dst = *src;
|
||||
/* poke the specific space */
|
||||
dst->space = low.space = high.space = spaces[j];
|
||||
if (spaces[j] != B_CMAP8) dst->flags &= ~B_8_BIT_DAC;
|
||||
if (spaces[j] != B_CMAP8)
|
||||
dst->flags &= ~B_8_BIT_DAC;
|
||||
/* ask for a compatible mode */
|
||||
if (1 || PROPOSE_DISPLAY_MODE(dst, &low, &high) != B_ERROR) {
|
||||
/* count it, and move on to next mode */
|
||||
|
@ -2,12 +2,13 @@
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#if !defined(GENERIC_H)
|
||||
#ifndef GENERIC_H
|
||||
#define GENERIC_H
|
||||
|
||||
|
||||
#include <Accelerant.h>
|
||||
|
||||
|
||||
status_t INIT_ACCELERANT(int fd);
|
||||
ssize_t ACCELERANT_CLONE_INFO_SIZE(void);
|
||||
void GET_ACCELERANT_CLONE_INFO(void *data);
|
||||
@ -49,100 +50,3 @@ void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count);
|
||||
void FILL_SPAN(engine_token *et, uint32 color, uint16 *list, uint32 count);
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
typedef enum
|
||||
{
|
||||
B_NO_COLOR_SPACE = 0x0000, /* byte in memory order, high bit first */
|
||||
|
||||
/* linear color space (little endian is the default) */
|
||||
B_RGB32 = 0x0008, /* B[7:0] G[7:0] R[7:0] -[7:0] */
|
||||
B_RGBA32 = 0x2008, /* B[7:0] G[7:0] R[7:0] A[7:0] */
|
||||
B_RGB24 = 0x0003, /* B[7:0] G[7:0] R[7:0] */
|
||||
B_RGB16 = 0x0005, /* G[2:0],B[4:0] R[4:0],G[5:3] */
|
||||
B_RGB15 = 0x0010, /* G[2:0],B[4:0] -[0],R[4:0],G[4:3] */
|
||||
B_RGBA15 = 0x2010, /* G[2:0],B[4:0] A[0],R[4:0],G[4:3] */
|
||||
B_CMAP8 = 0x0004, /* D[7:0] */
|
||||
B_GRAY8 = 0x0002, /* Y[7:0] */
|
||||
B_GRAY1 = 0x0001, /* Y0[0],Y1[0],Y2[0],Y3[0],Y4[0],Y5[0],Y6[0],Y7[0] */
|
||||
|
||||
/* big endian version, when the encoding is not endianess independant */
|
||||
B_RGB32_BIG = 0x1008, /* -[7:0] R[7:0] G[7:0] B[7:0] */
|
||||
B_RGBA32_BIG = 0x3008, /* A[7:0] R[7:0] G[7:0] B[7:0] */
|
||||
B_RGB24_BIG = 0x1003, /* R[7:0] G[7:0] B[7:0] */
|
||||
B_RGB16_BIG = 0x1005, /* R[4:0],G[5:3] G[2:0],B[4:0] */
|
||||
B_RGB15_BIG = 0x1010, /* -[0],R[4:0],G[4:3] G[2:0],B[4:0] */
|
||||
B_RGBA15_BIG = 0x3010, /* A[0],R[4:0],G[4:3] G[2:0],B[4:0] */
|
||||
|
||||
/* little-endian declarations, for completness */
|
||||
B_RGB32_LITTLE = B_RGB32,
|
||||
B_RGBA32_LITTLE = B_RGBA32,
|
||||
B_RGB24_LITTLE = B_RGB24,
|
||||
B_RGB16_LITTLE = B_RGB16,
|
||||
B_RGB15_LITTLE = B_RGB15,
|
||||
B_RGBA15_LITTLE = B_RGBA15,
|
||||
|
||||
/* non linear color space -- note that these are here for exchange purposes; */
|
||||
/* a BBitmap or BView may not necessarily support all these color spaces. */
|
||||
|
||||
/* Loss/Saturation points are Y 16-235 (absoulte); Cb/Cr 16-240 (center 128) */
|
||||
|
||||
B_YCbCr422 = 0x4000, /* Y0[7:0] Cb0[7:0] Y1[7:0] Cr0[7:0] Y2[7:0]... */
|
||||
/* Cb2[7:0] Y3[7:0] Cr2[7:0] */
|
||||
B_YCbCr411 = 0x4001, /* Cb0[7:0] Y0[7:0] Cr0[7:0] Y1[7:0] Cb4[7:0]...*/
|
||||
/* Y2[7:0] Cr4[7:0] Y3[7:0] Y4[7:0] Y5[7:0]... */
|
||||
/* Y6[7:0] Y7[7:0] */
|
||||
B_YCbCr444 = 0x4003, /* Y0[7:0] Cb0[7:0] Cr0[7:0] */
|
||||
B_YCbCr420 = 0x4004, /* Non-interlaced only, Cb0 Y0 Y1 Cb2 Y2 Y3 on even scan lines ... */
|
||||
/* Cr0 Y0 Y1 Cr2 Y2 Y3 on odd scan lines */
|
||||
|
||||
/* Extrema points are Y 0 - 207 (absolute) U -91 - 91 (offset 128) V -127 - 127 (offset 128) */
|
||||
/* note that YUV byte order is different from YCbCr */
|
||||
/* USE YCbCr, not YUV, when that's what you mean! */
|
||||
B_YUV422 = 0x4020, /* U0[7:0] Y0[7:0] V0[7:0] Y1[7:0] ... */
|
||||
/* U2[7:0] Y2[7:0] V2[7:0] Y3[7:0] */
|
||||
B_YUV411 = 0x4021, /* U0[7:0] Y0[7:0] Y1[7:0] V0[7:0] Y2[7:0] Y3[7:0] */
|
||||
/* U4[7:0] Y4[7:0] Y5[7:0] V4[7:0] Y6[7:0] Y7[7:0] */
|
||||
B_YUV444 = 0x4023, /* U0[7:0] Y0[7:0] V0[7:0] U1[7:0] Y1[7:0] V1[7:0] */
|
||||
B_YUV420 = 0x4024, /* Non-interlaced only, U0 Y0 Y1 U2 Y2 Y3 on even scan lines ... */
|
||||
/* V0 Y0 Y1 V2 Y2 Y3 on odd scan lines */
|
||||
B_YUV9 = 0x402C, /* planar? 410? */
|
||||
B_YUV12 = 0x402D, /* planar? 420? */
|
||||
|
||||
B_UVL24 = 0x4030, /* U0[7:0] V0[7:0] L0[7:0] ... */
|
||||
B_UVL32 = 0x4031, /* U0[7:0] V0[7:0] L0[7:0] X0[7:0]... */
|
||||
B_UVLA32 = 0x6031, /* U0[7:0] V0[7:0] L0[7:0] A0[7:0]... */
|
||||
|
||||
B_LAB24 = 0x4032, /* L0[7:0] a0[7:0] b0[7:0] ... (a is not alpha!) */
|
||||
B_LAB32 = 0x4033, /* L0[7:0] a0[7:0] b0[7:0] X0[7:0] ... (b is not alpha!) */
|
||||
B_LABA32 = 0x6033, /* L0[7:0] a0[7:0] b0[7:0] A0[7:0] ... (A is alpha) */
|
||||
|
||||
/* red is at hue = 0 */
|
||||
|
||||
B_HSI24 = 0x4040, /* H[7:0] S[7:0] I[7:0] */
|
||||
B_HSI32 = 0x4041, /* H[7:0] S[7:0] I[7:0] X[7:0] */
|
||||
B_HSIA32 = 0x6041, /* H[7:0] S[7:0] I[7:0] A[7:0] */
|
||||
|
||||
B_HSV24 = 0x4042, /* H[7:0] S[7:0] V[7:0] */
|
||||
B_HSV32 = 0x4043, /* H[7:0] S[7:0] V[7:0] X[7:0] */
|
||||
B_HSVA32 = 0x6043, /* H[7:0] S[7:0] V[7:0] A[7:0] */
|
||||
|
||||
B_HLS24 = 0x4044, /* H[7:0] L[7:0] S[7:0] */
|
||||
B_HLS32 = 0x4045, /* H[7:0] L[7:0] S[7:0] X[7:0] */
|
||||
B_HLSA32 = 0x6045, /* H[7:0] L[7:0] S[7:0] A[7:0] */
|
||||
|
||||
B_CMY24 = 0xC001, /* C[7:0] M[7:0] Y[7:0] No gray removal done */
|
||||
B_CMY32 = 0xC002, /* C[7:0] M[7:0] Y[7:0] X[7:0] No gray removal done */
|
||||
B_CMYA32 = 0xE002, /* C[7:0] M[7:0] Y[7:0] A[7:0] No gray removal done */
|
||||
B_CMYK32 = 0xC003, /* C[7:0] M[7:0] Y[7:0] K[7:0] */
|
||||
|
||||
/* compatibility declarations */
|
||||
B_MONOCHROME_1_BIT = B_GRAY1,
|
||||
B_GRAYSCALE_8_BIT = B_GRAY8,
|
||||
B_COLOR_8_BIT = B_CMAP8,
|
||||
B_RGB_32_BIT = B_RGB32,
|
||||
B_RGB_16_BIT = B_RGB15,
|
||||
B_BIG_RGB_32_BIT = B_RGB32_BIG,
|
||||
B_BIG_RGB_16_BIT = B_RGB15_BIG
|
||||
} color_space;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user