* Radeons. */
/* Parse a PCI ID and fill an r300_capabilities struct with information. */
-void r300_parse_chipset(struct r300_capabilities* caps)
+void r300_parse_chipset(uint32_t pci_id, struct r300_capabilities* caps)
{
- switch (caps->pci_id) {
+ switch (pci_id) {
#define CHIPSET(pci_id, name, chipfamily) \
case pci_id: \
caps->family = CHIP_FAMILY_##chipfamily; \
default:
fprintf(stderr, "r300: Warning: Unknown chipset 0x%x\nAborting...",
- caps->pci_id);
+ pci_id);
abort();
}
/* Structure containing all the possible information about a specific Radeon
* in the R3xx, R4xx, and R5xx families. */
struct r300_capabilities {
- /* PCI ID */
- uint32_t pci_id;
/* Chipset family */
int family;
/* The number of vertex floating-point units */
unsigned num_vert_fpus;
- /* The number of fragment pipes */
- unsigned num_frag_pipes;
- /* The number of z pipes */
- unsigned num_z_pipes;
/* The number of texture units. */
unsigned num_tex_units;
/* Whether or not TCL is physically present */
CHIP_FAMILY_RV570
};
-void r300_parse_chipset(struct r300_capabilities* caps);
+void r300_parse_chipset(uint32_t pci_id, struct r300_capabilities* caps);
#endif /* R300_CHIPSET_H */
boolean is_rv350 = r300->screen->caps.is_rv350;
boolean is_r500 = r300->screen->caps.is_r500;
boolean has_tcl = r300->screen->caps.has_tcl;
- boolean drm_2_6_0 = r300->rws->get_value(r300->rws, RADEON_VID_DRM_2_6_0);
+ boolean drm_2_6_0 = r300->screen->info.drm_minor >= 6;
/* Create the actual atom list.
*
if (r300->screen->caps.is_r500 ||
(r300->screen->caps.is_rv350 &&
- r300->rws->get_value(r300->rws, RADEON_VID_DRM_2_6_0))) {
+ r300->screen->info.drm_minor >= 6)) {
OUT_CB_REG(R300_GB_Z_PEQ_CONFIG, 0);
}
END_CB;
"r300: DRM version: %d.%d.%d, Name: %s, ID: 0x%04x, GB: %d, Z: %d\n"
"r300: GART size: %d MB, VRAM size: %d MB\n"
"r300: AA compression RAM: %s, Z compression RAM: %s, HiZ RAM: %s\n",
- rws->get_value(rws, RADEON_VID_DRM_MAJOR),
- rws->get_value(rws, RADEON_VID_DRM_MINOR),
- rws->get_value(rws, RADEON_VID_DRM_PATCHLEVEL),
+ r300->screen->info.drm_major,
+ r300->screen->info.drm_minor,
+ r300->screen->info.drm_patchlevel,
screen->get_name(screen),
- rws->get_value(rws, RADEON_VID_PCI_ID),
- rws->get_value(rws, RADEON_VID_R300_GB_PIPES),
- rws->get_value(rws, RADEON_VID_R300_Z_PIPES),
- rws->get_value(rws, RADEON_VID_GART_SIZE) >> 20,
- rws->get_value(rws, RADEON_VID_VRAM_SIZE) >> 20,
+ r300->screen->info.pci_id,
+ r300->screen->info.r300_num_gb_pipes,
+ r300->screen->info.r300_num_z_pipes,
+ r300->screen->info.gart_size >> 20,
+ r300->screen->info.vram_size >> 20,
"YES", /* XXX really? */
r300->screen->caps.zmask_ram ? "YES" : "NO",
r300->screen->caps.hiz_ram ? "YES" : "NO");
struct r300_query *query)
{
struct r300_capabilities* caps = &r300->screen->caps;
+ uint32_t gb_pipes = r300->screen->info.r300_num_gb_pipes;
CS_LOCALS(r300);
- assert(caps->num_frag_pipes);
+ assert(gb_pipes);
- BEGIN_CS(6 * caps->num_frag_pipes + 2);
+ BEGIN_CS(6 * gb_pipes + 2);
/* I'm not so sure I like this switch, but it's hard to be elegant
* when there's so many special cases...
*
* 4-byte offset for each pipe. RV380 and older are special; they have
* only two pipes, and the second pipe's enable is on bit 3, not bit 1,
* so there's a chipset cap for that. */
- switch (caps->num_frag_pipes) {
+ switch (gb_pipes) {
case 4:
/* pipe 3 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 3);
break;
default:
fprintf(stderr, "r300: Implementation error: Chipset reports %d"
- " pixel pipes!\n", caps->num_frag_pipes);
+ " pixel pipes!\n", gb_pipes);
abort();
}
return;
if (caps->family == CHIP_FAMILY_RV530) {
- if (caps->num_z_pipes == 2)
+ if (r300->screen->info.r300_num_z_pipes == 2)
rv530_emit_query_end_double_z(r300, query);
else
rv530_emit_query_end_single_z(r300, query);
q->buffer_size = 4096;
if (r300screen->caps.family == CHIP_FAMILY_RV530)
- q->num_pipes = r300screen->caps.num_z_pipes;
+ q->num_pipes = r300screen->info.r300_num_z_pipes;
else
- q->num_pipes = r300screen->caps.num_frag_pipes;
+ q->num_pipes = r300screen->info.r300_num_gb_pipes;
insert_at_tail(&r300->query_list, q);
unsigned sample_count,
unsigned usage)
{
- struct radeon_winsys *rws = r300_screen(screen)->rws;
uint32_t retval = 0;
- boolean drm_2_8_0 = rws->get_value(rws, RADEON_VID_DRM_2_8_0);
+ boolean drm_2_8_0 = r300_screen(screen)->info.drm_minor >= 8;
boolean is_r500 = r300_screen(screen)->caps.is_r500;
boolean is_r400 = r300_screen(screen)->caps.is_r400;
boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM ||
return NULL;
}
- r300screen->caps.pci_id = rws->get_value(rws, RADEON_VID_PCI_ID);
- r300screen->caps.num_frag_pipes = rws->get_value(rws, RADEON_VID_R300_GB_PIPES);
- r300screen->caps.num_z_pipes = rws->get_value(rws, RADEON_VID_R300_Z_PIPES);
+ rws->query_info(rws, &r300screen->info);
r300_init_debug(r300screen);
- r300_parse_chipset(&r300screen->caps);
+ r300_parse_chipset(r300screen->info.pci_id, &r300screen->caps);
if (SCREEN_DBG_ON(r300screen, DBG_NO_ZMASK))
r300screen->caps.zmask_ram = 0;
if (SCREEN_DBG_ON(r300screen, DBG_NO_HIZ))
r300screen->caps.hiz_ram = 0;
- if (!rws->get_value(rws, RADEON_VID_DRM_2_8_0))
+ if (r300screen->info.drm_minor < 8)
r300screen->caps.has_us_format = FALSE;
pipe_mutex_init(r300screen->num_contexts_mutex);
#ifndef R300_SCREEN_H
#define R300_SCREEN_H
-#include "pipe/p_screen.h"
-
#include "r300_chipset.h"
-
+#include "../../winsys/radeon/drm/radeon_winsys.h"
+#include "pipe/p_screen.h"
#include "util/u_slab.h"
-
#include <stdio.h>
-struct radeon_winsys;
-
struct r300_screen {
/* Parent class */
struct pipe_screen screen;
struct radeon_winsys *rws;
- /* Chipset capabilities */
+ /* Chipset info and capabilities. */
+ struct radeon_info info;
struct r300_capabilities caps;
/* Memory pools. */
unsigned i, pipes;
if (screen->caps.family == CHIP_FAMILY_RV530) {
- pipes = screen->caps.num_z_pipes;
+ pipes = screen->info.r300_num_z_pipes;
} else {
- pipes = screen->caps.num_frag_pipes;
+ pipes = screen->info.r300_num_gb_pipes;
}
for (i = 0; i <= tex->b.b.b.last_level; i++) {
{
struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
- return cs->csc->used_gart < cs->ws->gart_size * 0.8 &&
- cs->csc->used_vram < cs->ws->vram_size * 0.8;
+ return cs->csc->used_gart < cs->ws->info.gart_size * 0.8 &&
+ cs->csc->used_vram < cs->ws->info.vram_size * 0.8;
}
static void radeon_drm_cs_write_reloc(struct radeon_winsys_cs *rcs,
return FALSE;
}
+static boolean radeon_get_drm_value(int fd, unsigned request,
+ const char *name, uint32_t *out)
+{
+ struct drm_radeon_info info = {0};
+ int retval;
+
+ info.value = (unsigned long)out;
+ info.request = request;
+
+ retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
+ if (retval) {
+ fprintf(stderr, "%s: Failed to get %s, error number %d\n",
+ __func__, name, retval);
+ return FALSE;
+ }
+ return TRUE;
+}
+
/* Helper function to do the ioctls needed for setup and init. */
-static void do_ioctls(struct radeon_drm_winsys *winsys)
+static boolean do_winsys_init(struct radeon_drm_winsys *ws)
{
struct drm_radeon_gem_info gem_info = {0};
- struct drm_radeon_info info = {0};
- int target = 0;
int retval;
drmVersionPtr version;
- info.value = (unsigned long)⌖
-
/* We do things in a specific order here.
*
* DRM version first. We need to be sure we're running on a KMS chipset.
* for all Radeons. If this fails, we probably got handed an FD for some
* non-Radeon card.
*
+ * The GEM info is actually bogus on the kernel side, as well as our side
+ * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because
+ * we don't actually use the info for anything yet.
+ *
* The GB and Z pipe requests should always succeed, but they might not
* return sensical values for all chipsets, but that's alright because
* the pipe drivers already know that.
- *
- * The GEM info is actually bogus on the kernel side, as well as our side
- * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because
- * we don't actually use the info for anything yet. */
+ */
- version = drmGetVersion(winsys->fd);
+ /* Get DRM version. */
+ version = drmGetVersion(ws->fd);
if (version->version_major != 2 ||
version->version_minor < 3) {
fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
- "only compatible with 2.3.x (kernel 2.6.34) and later.\n",
+ "only compatible with 2.3.x (kernel 2.6.34) or later.\n",
__FUNCTION__,
version->version_major,
version->version_minor,
version->version_patchlevel);
drmFreeVersion(version);
- exit(1);
+ return FALSE;
}
- winsys->drm_major = version->version_major;
- winsys->drm_minor = version->version_minor;
- winsys->drm_patchlevel = version->version_patchlevel;
+ ws->info.drm_major = version->version_major;
+ ws->info.drm_minor = version->version_minor;
+ ws->info.drm_patchlevel = version->version_patchlevel;
+ drmFreeVersion(version);
- info.request = RADEON_INFO_DEVICE_ID;
- retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info));
- if (retval) {
- fprintf(stderr, "%s: Failed to get PCI ID, "
- "error number %d\n", __FUNCTION__, retval);
- exit(1);
- }
- winsys->pci_id = target;
+ /* Get PCI ID. */
+ if (!radeon_get_drm_value(ws->fd, RADEON_INFO_DEVICE_ID, "PCI ID",
+ &ws->info.pci_id))
+ return FALSE;
- info.request = RADEON_INFO_NUM_GB_PIPES;
- retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info));
- if (retval) {
- fprintf(stderr, "%s: Failed to get GB pipe count, "
- "error number %d\n", __FUNCTION__, retval);
- exit(1);
- }
- winsys->gb_pipes = target;
+ /* Check PCI ID. */
+ switch (ws->info.pci_id) {
+#define CHIPSET(pci_id, name, family) case pci_id:
+#include "pci_ids/r300_pci_ids.h"
+#undef CHIPSET
+ break;
- info.request = RADEON_INFO_NUM_Z_PIPES;
- retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_INFO, &info, sizeof(info));
- if (retval) {
- fprintf(stderr, "%s: Failed to get Z pipe count, "
- "error number %d\n", __FUNCTION__, retval);
- exit(1);
+ default:
+ fprintf(stderr, "radeon: Invalid PCI ID.\n");
+ return FALSE;
}
- winsys->z_pipes = target;
- retval = drmCommandWriteRead(winsys->fd, DRM_RADEON_GEM_INFO,
+ /* Get GEM info. */
+ retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO,
&gem_info, sizeof(gem_info));
if (retval) {
fprintf(stderr, "%s: Failed to get MM info, error number %d\n",
__FUNCTION__, retval);
- exit(1);
+ return FALSE;
}
- winsys->gart_size = gem_info.gart_size;
- winsys->vram_size = gem_info.vram_size;
+ ws->info.gart_size = gem_info.gart_size;
+ ws->info.vram_size = gem_info.vram_size;
- drmFreeVersion(version);
+ ws->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+
+ /* Generation-specific queries. */
+ if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_GB_PIPES,
+ "GB pipe count",
+ &ws->info.r300_num_gb_pipes))
+ return FALSE;
- winsys->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+ if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_Z_PIPES,
+ "Z pipe count",
+ &ws->info.r300_num_z_pipes))
+ return FALSE;
+
+ return TRUE;
}
static void radeon_winsys_destroy(struct radeon_winsys *rws)
FREE(rws);
}
-static uint32_t radeon_get_value(struct radeon_winsys *rws,
- enum radeon_value_id id)
+static void radeon_query_info(struct radeon_winsys *rws,
+ struct radeon_info *info)
{
- struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *)rws;
-
- switch(id) {
- case RADEON_VID_PCI_ID:
- return ws->pci_id;
- case RADEON_VID_R300_GB_PIPES:
- return ws->gb_pipes;
- case RADEON_VID_R300_Z_PIPES:
- return ws->z_pipes;
- case RADEON_VID_GART_SIZE:
- return ws->gart_size;
- case RADEON_VID_VRAM_SIZE:
- return ws->vram_size;
- case RADEON_VID_DRM_MAJOR:
- return ws->drm_major;
- case RADEON_VID_DRM_MINOR:
- return ws->drm_minor;
- case RADEON_VID_DRM_PATCHLEVEL:
- return ws->drm_patchlevel;
- case RADEON_VID_DRM_2_6_0:
- return ws->drm_major*100 + ws->drm_minor >= 206;
- case RADEON_VID_DRM_2_8_0:
- return ws->drm_major*100 + ws->drm_minor >= 208;
- }
- return 0;
+ *info = ((struct radeon_drm_winsys *)rws)->info;
}
static boolean radeon_cs_request_feature(struct radeon_winsys_cs *rcs,
}
ws->fd = fd;
- do_ioctls(ws);
- switch (ws->pci_id) {
-#define CHIPSET(pci_id, name, family) case pci_id:
-#include "pci_ids/r300_pci_ids.h"
-#undef CHIPSET
- break;
- default:
- goto fail;
- }
+ if (!do_winsys_init(ws))
+ goto fail;
/* Create managers. */
ws->kman = radeon_bomgr_create(ws);
/* Set functions. */
ws->base.destroy = radeon_winsys_destroy;
- ws->base.get_value = radeon_get_value;
+ ws->base.query_info = radeon_query_info;
ws->base.cs_request_feature = radeon_cs_request_feature;
radeon_bomgr_init_functions(ws);
#define RADEON_DRM_WINSYS_H
#include "radeon_winsys.h"
-
#include "os/os_thread.h"
struct radeon_drm_winsys {
int fd; /* DRM file descriptor */
int num_cs; /* The number of command streams created. */
+ struct radeon_info info;
+
struct pb_manager *kman;
struct pb_manager *cman;
- uint32_t pci_id; /* PCI ID */
- uint32_t gb_pipes; /* GB pipe count */
- uint32_t z_pipes; /* Z pipe count (rv530 only) */
- uint32_t gart_size; /* GART size. */
- uint32_t vram_size; /* VRAM size. */
uint32_t num_cpus; /* Number of CPUs. */
- unsigned drm_major;
- unsigned drm_minor;
- unsigned drm_patchlevel;
-
struct radeon_drm_cs *hyperz_owner;
pipe_mutex hyperz_owner_mutex;
struct radeon_drm_cs *cmask_owner;
/* The public winsys interface header for the radeon driver. */
+/* R300 features in DRM.
+ *
+ * 2.6.0:
+ * - Hyper-Z
+ * - GB_Z_PEQ_CONFIG on rv350->r4xx
+ * - R500 FG_ALPHA_VALUE
+ *
+ * 2.8.0:
+ * - R500 US_FORMAT regs
+ * - R500 ARGB2101010 colorbuffer
+ * - CMask and AA regs
+ * - R16F/RG16F
+ */
+
#include "pipebuffer/pb_bufmgr.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
uint32_t *buf; /* The command buffer. */
};
-enum radeon_value_id {
- RADEON_VID_PCI_ID,
- RADEON_VID_R300_GB_PIPES,
- RADEON_VID_R300_Z_PIPES,
- RADEON_VID_GART_SIZE,
- RADEON_VID_VRAM_SIZE,
- RADEON_VID_DRM_MAJOR,
- RADEON_VID_DRM_MINOR,
- RADEON_VID_DRM_PATCHLEVEL,
-
- /* These should probably go away: */
-
- /* R300 features:
- * - Hyper-Z
- * - GB_Z_PEQ_CONFIG on rv350->r4xx
- * - R500 FG_ALPHA_VALUE
- *
- * R600 features:
- * - TBD
- */
- RADEON_VID_DRM_2_6_0,
+struct radeon_info {
+ uint32_t pci_id;
+ uint32_t gart_size;
+ uint32_t vram_size;
- /* R300 features:
- * - R500 US_FORMAT regs
- * - R500 ARGB2101010 colorbuffer
- * - CMask and AA regs
- * - R16F/RG16F
- *
- * R600 features:
- * - TBD
- */
- RADEON_VID_DRM_2_8_0,
+ uint32_t drm_major; /* version */
+ uint32_t drm_minor;
+ uint32_t drm_patchlevel;
+
+ uint32_t r300_num_gb_pipes;
+ uint32_t r300_num_z_pipes;
};
enum radeon_feature_id {
void (*destroy)(struct radeon_winsys *ws);
/**
- * Query a system value from a winsys.
+ * Query an info structure from winsys.
*
* \param ws The winsys this function is called from.
- * \param vid One of the RADEON_VID_* enums.
+ * \param info Return structure
*/
- uint32_t (*get_value)(struct radeon_winsys *ws,
- enum radeon_value_id vid);
+ void (*query_info)(struct radeon_winsys *ws,
+ struct radeon_info *info);
/**************************************************************************
* Buffer management. Buffer attributes are mostly fixed over its lifetime.