* 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:
Axel Dörfler 2006-09-29 14:12:22 +00:00
parent b9ecaef57a
commit b83fe28463
4 changed files with 401 additions and 498 deletions

View File

@ -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

View File

@ -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);
return ai.address;
area_info 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,81 +119,73 @@ 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;
status_t result;
savage_get_private_data gpd;
/* memorize the file descriptor */
fd = the_fd;
dpf ("init_common begin\n");
/* 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;
/* memorize the file descriptor */
fd = the_fd;
dpf ("init_common begin\n");
/* 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 */
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);
if (shared_info_area < 0)
{
result = shared_info_area;
goto error0;
}
/* clone the memory mapped registers for our use */
regs_area = clone_area (
"SAVAGE regs area", (void **)&regs, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, si->regs_area);
if (regs_area < 0)
{
result = regs_area;
goto error1;
}
regs = __get_area_address (regs_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)
return shared_info_area;
dpf ("PCI VENDOR_ID = 0x%4X, DEVICE_ID = 0x%4X\n",
read16 ((byte_t*)regs + 0x8000),
read16 ((byte_t*)regs + 0x8002));
/* clone the memory mapped registers for our use */
regs_area = clone_area("SAVAGE regs area", (void **)&regs, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, si->regs_area);
if (regs_area < 0) {
result = regs_area;
goto error1;
}
regs = get_area_address(regs_area);
/* 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)
{
result = regs_area;
goto error2;
}
framebuffer = __get_area_address (fb_area);
dpf("PCI VENDOR_ID = 0x%4X, DEVICE_ID = 0x%4X\n",
read16((byte_t*)regs + 0x8000),
read16((byte_t*)regs + 0x8002));
s3drv_init ((byte_t*)regs);
dpf ("s3drv_init called\n");
s3accel_init (s3drv_get_context ());
dpf ("s3accel_init called\n");
s3drv_unlock_regs ();
/* all done */
goto error0;
/* 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) {
result = regs_area;
goto error2;
}
framebuffer = get_area_address(fb_area);
s3drv_init((byte_t*)regs);
dpf ("s3drv_init called\n");
s3accel_init(s3drv_get_context());
dpf ("s3accel_init called\n");
s3drv_unlock_regs();
/* all done */
return B_OK;
error2:
delete_area(regs_area);
delete_area(regs_area);
error1:
delete_area(shared_info_area);
error0:
dpf ("init_common done\n");
return result;
delete_area(shared_info_area);
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
@ -268,8 +264,9 @@ status_t INIT_ACCELERANT(int the_fd)
initialized with this routine) will own the "one true copy" of the list.
Everybody else get's a read-only clone.
*/
result = create_mode_list();
if (result != B_OK) goto error2;
result = create_mode_list();
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,60 +373,54 @@ 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];
status_t result;
char path[MAXPATHLEN];
/* the data is the device name */
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;
}
/* the data is the device name */
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)
return errno;
/* note that we're a clone accelerant */
accelerantIsClone = 1;
/* note that we're a clone accelerant */
accelerantIsClone = 1;
/* call the shared initialization code */
result = init_common(fd);
/* call the shared initialization code */
result = init_common(fd);
if (result != B_OK)
goto error1;
/* bail out if the common initialization failed */
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;
/* 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;
/* all done */
result = B_OK;
goto error0;
/* all done */
return B_OK;
error2:
/* free up the areas we cloned */
uninit_common();
/* free up the areas we cloned */
uninit_common();
error1:
/* close the device we opened */
close(fd);
error0:
return result;
/* close the device we opened */
close(fd);
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,41 +447,34 @@ 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)
{
case 0x8a20:
names = names1;
offset = si->device_id - PCI_PID_SAVAGE3D;
break;
case 0x8c10:
names = names2;
offset = si->device_id - PCI_PID_SAVAGEMXMV;
break;
case 0x8d00:
names = names3;
offset = si->device_id - PCI_PID_PN133;
break;
switch (si->device_id & 0xFFF0) {
case 0x8a20:
names = names1;
offset = si->device_id - PCI_PID_SAVAGE3D;
break;
case 0x8c10:
names = names2;
offset = si->device_id - PCI_PID_SAVAGEMXMV;
break;
case 0x8d00:
names = names3;
offset = si->device_id - PCI_PID_PN133;
break;
}
if (names != NULL)
{
strcpy (adi->name, names[offset]);
strcpy (adi->chipset, names[offset]);
}
else
{
strcpy (adi->name, "not supported");
strcpy (adi->chipset, "Savage");
}
}
if (names != NULL) {
strcpy (adi->name, names[offset]);
strcpy (adi->chipset, names[offset]);
} else {
strcpy (adi->name, "not supported");
strcpy (adi->chipset, "Savage");
}
}
strcpy (adi->serial_no, "0");
adi->memory = si->mem_size;
adi->dac_speed = 250;

View File

@ -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,
return B_BAD_VALUE.
If the mode is both valid AND falls within the limits, return B_OK.
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.
*/
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_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 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);
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;
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;
bool want_same_height = target->timing.v_display == target->virtual_height;
/*
NOTE:
@ -101,86 +97,96 @@ status_t PROPOSE_DISPLAY_MODE (
*/
/* validate horizontal timings */
{
/* for most devices, horizontal parameters must be multiples of 8 */
uint16 h_display = target->timing.h_display >> 3;
uint16 h_sync_start = target->timing.h_sync_start >> 3;
uint16 h_sync_end = target->timing.h_sync_end >> 3;
uint16 h_total = target->timing.h_total >> 3;
{
/* for most devices, horizontal parameters must be multiples of 8 */
uint16 h_display = target->timing.h_display >> 3;
uint16 h_sync_start = target->timing.h_sync_start >> 3;
uint16 h_sync_end = target->timing.h_sync_end >> 3;
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_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;
/* adjust for register limitations: */
/* h_total is 9 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 */
if ((h_sync_end - h_sync_start) > h_sync_bits)
h_sync_end = h_sync_start + h_sync_bits;
/* 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_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;
/* shift back to the full width values */
target->timing.h_display = h_display << 3;
target->timing.h_sync_start = h_sync_start << 3;
target->timing.h_sync_end = h_sync_end << 3;
target->timing.h_total = h_total << 3;
}
/* adjust for register limitations: */
/* h_total is 9 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 */
if ((h_sync_end - h_sync_start) > h_sync_bits)
h_sync_end = h_sync_start + h_sync_bits;
/* shift back to the full width values */
target->timing.h_display = h_display << 3;
target->timing.h_sync_start = h_sync_start << 3;
target->timing.h_sync_end = h_sync_end << 3;
target->timing.h_total = h_total << 3;
}
/* 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 */
{
uint16 v_display = target->timing.v_display;
uint16 v_sync_start = target->timing.v_sync_start;
uint16 v_sync_end = target->timing.v_sync_end;
uint16 v_total = target->timing.v_total;
/* validate vertical timings */
{
uint16 v_display = target->timing.v_display;
uint16 v_sync_start = target->timing.v_sync_start;
uint16 v_sync_end = target->timing.v_sync_end;
uint16 v_total = target->timing.v_total;
/* ensure reasonable minium display and sequential order of parms */
/* v_display is 11 bits */
/* 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;
/* ensure reasonable minium display and sequential order of parms */
/* v_display is 11 bits */
/* 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;
/* 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;
target->timing.v_total = v_total;
}
/* 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;
target->timing.v_total = v_total;
}
/* 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 */
/*
@ -199,27 +205,26 @@ status_t PROPOSE_DISPLAY_MODE (
initialization code.
This is also a convienient place to determine the number of bytes
per pixel for a later display pitch calculation.
*/
switch (target->space & 0x0fff)
{
case B_CMAP8:
limit_clock = si->pix_clk_max8;
row_bytes = 1;
break;
//case B_RGB15:
case B_RGB16:
limit_clock = si->pix_clk_max16;
row_bytes = 2;
break;
case B_RGB32:
limit_clock = si->pix_clk_max32;
row_bytes = 4;
break;
default:
/* no amount of adjusting will fix not being able to support
the pixel format */
return B_ERROR;
}
*/
switch (target->space & 0x0fff) {
case B_CMAP8:
limit_clock = si->pix_clk_max8;
row_bytes = 1;
break;
//case B_RGB15:
case B_RGB16:
limit_clock = si->pix_clk_max16;
row_bytes = 2;
break;
case B_RGB32:
limit_clock = si->pix_clk_max32;
row_bytes = 4;
break;
default:
/* no amount of adjusting will fix not being able to support
the pixel format */
return B_ERROR;
}
/* make sure we don't generate more pixel bandwidth than the device
can handle */
if (target->timing.pixel_clock > limit_clock)
@ -228,97 +233,92 @@ 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)
target->virtual_width = target->timing.h_display;
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;
/* validate display vs. virtual */
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)
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;
/* 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;
/* calculate rowbytes after we've nailed the virtual width */
row_bytes *= target->virtual_width;
/* calculate rowbytes after we've nailed the virtual width */
row_bytes *= target->virtual_width;
/* memory requirement for frame buffer */
if ((row_bytes * target->virtual_height) > si->mem_size)
target->virtual_height = si->mem_size / row_bytes;
/* memory requirement for frame buffer */
if ((row_bytes * target->virtual_height) > si->mem_size)
target->virtual_height = si->mem_size / row_bytes;
if (target->virtual_height > 2048)
target->virtual_height = 2048;
if (target->virtual_height > 2048)
target->virtual_height = 2048;
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;
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;
/*
Bit Flag Encoding
The way the bit flags works is as follows:
/*
Bit Flag Encoding
low high meaning
--- ---- -------
0 0 Feature must NOT be enabled
0 1 Feature MAY be enabled, prefered enabled
1 0 Feature MAY be enabled, prefered disabled
1 1 Feature MUST be enabled
The way the bit flags works is as follows:
*/
low high meaning
--- ---- -------
0 0 Feature must NOT be enabled
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)
{
/* return the number of 'built-in' display modes */
return si->mode_count;
}
/*
Copy the list of guaranteed supported video modes to the location
provided.
/*!
Return the number of modes this device will return from GET_MODE_LIST().
*/
status_t GET_MODE_LIST(display_mode *dm)
uint32
ACCELERANT_MODE_COUNT(void)
{
/* copy them to the buffer pointed at by *dm */
memcpy(dm, my_mode_list, si->mode_count * sizeof(display_mode));
return B_OK;
/* 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)
{
/* copy them to the buffer pointed at by *dm */
memcpy(dm, my_mode_list, si->mode_count * sizeof(display_mode));
return B_OK;
}
/*!
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
@ -336,49 +336,51 @@ status_t create_mode_list(void)
{B_CMAP8, B_RGB16_BIG, B_RGB32_BIG};
#endif
/* 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);
/* create an area to hold the info */
si->mode_area = my_mode_list_area =
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;
/* 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);
/* 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++)
{
/* 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;
/* ask for a compatible mode */
if (1 || PROPOSE_DISPLAY_MODE(dst, &low, &high) != B_ERROR) {
/* count it, and move on to next mode */
dst++;
si->mode_count++;
}
/* create an area to hold the info */
si->mode_area = my_mode_list_area =
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;
/* 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++) {
/* 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;
/* ask for a compatible mode */
if (1 || PROPOSE_DISPLAY_MODE(dst, &low, &high) != B_ERROR) {
/* count it, and move on to next mode */
dst++;
si->mode_count++;
}
}
/* advance to next mode */
src++;
}
/* advance to next mode */
src++;
}
return B_OK;
return B_OK;
}

View File

@ -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