winsys/radeon: simplify how value queries work
authorMarek Olšák <maraeo@gmail.com>
Fri, 22 Jul 2011 16:58:30 +0000 (18:58 +0200)
committerMarek Olšák <maraeo@gmail.com>
Mon, 25 Jul 2011 21:10:39 +0000 (23:10 +0200)
This drops the get_value query and adds a function query_info, which returns
all the values in one nice structure.

12 files changed:
src/gallium/drivers/r300/r300_chipset.c
src/gallium/drivers/r300/r300_chipset.h
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_query.c
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r300/r300_screen.h
src/gallium/drivers/r300/r300_texture_desc.c
src/gallium/winsys/radeon/drm/radeon_drm_cs.c
src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
src/gallium/winsys/radeon/drm/radeon_winsys.h

index 571986c301170c35919a3e6ac21767c6bb3375b9..80148b80afb2b405aa1b05bc8e9274bae6cfd347 100644 (file)
@@ -31,9 +31,9 @@
  * 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; \
@@ -43,7 +43,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
 
     default:
         fprintf(stderr, "r300: Warning: Unknown chipset 0x%x\nAborting...",
-                caps->pci_id);
+                pci_id);
         abort();
     }
 
index 4df6b5b62922173b82dba12effb7bb42b1b27c4f..f96cdaf25807899b1f29b012d25b0220834d2e0b 100644 (file)
@@ -43,16 +43,10 @@ enum r300_zmask_compression {
 /* 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 */
@@ -121,6 +115,6 @@ enum {
     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 */
index d94ac74f0e5d512018b293228ce650d3a472d5d6..2b3329e9f860bbfa45d845877a55d3f8689c4294 100644 (file)
@@ -173,7 +173,7 @@ static boolean r300_setup_atoms(struct r300_context* r300)
     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.
      *
@@ -380,7 +380,7 @@ static void r300_init_states(struct pipe_context *pipe)
 
         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;
@@ -520,15 +520,15 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
                 "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");
index d214af4cd5b308bd69b92334eb083db7db98035a..502aed3a20cccbd39aee6b14435a34140b4e0b8d 100644 (file)
@@ -574,11 +574,12 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
                                            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...
      *
@@ -587,7 +588,7 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
      * 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);
@@ -613,7 +614,7 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
             break;
         default:
             fprintf(stderr, "r300: Implementation error: Chipset reports %d"
-                    " pixel pipes!\n", caps->num_frag_pipes);
+                    " pixel pipes!\n", gb_pipes);
             abort();
     }
 
@@ -663,7 +664,7 @@ void r300_emit_query_end(struct r300_context* r300)
         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);
index 782f041e926043cac9db24b4d439718513633f40..000114129bf31b857f1d239fd753c95b27946d30 100644 (file)
@@ -49,9 +49,9 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
     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);
 
index c8df45fb3e7a12984a0edd34b5b2ab9a070bb407..d9378308ad025204ceb0bf734cb5a627b7ad2871 100644 (file)
@@ -327,9 +327,8 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
                                         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 ||
@@ -497,19 +496,17 @@ struct pipe_screen* r300_screen_create(struct radeon_winsys *rws)
         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);
index e5c53bf3500f1bc040329b86de62d3348416fc9d..82b2068e7a08ea5b62d8498a4a22d5167dda5528 100644 (file)
 #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. */
index da5778be65e36d3936e837aa14d18f4bdc415684..fe4f8dd5679708ad313b89615bda01c3e78c9f2d 100644 (file)
@@ -360,9 +360,9 @@ static void r300_setup_hyperz_properties(struct r300_screen *screen,
         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++) {
index 0139de1973afc3eedc49f48af56665ccb54a84e3..f0f4a70be3f9d16d36d9eed602531ad7f56babd2 100644 (file)
@@ -308,8 +308,8 @@ static boolean radeon_drm_cs_validate(struct radeon_winsys_cs *rcs)
 {
     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,
index 0474b381ade6d9c0f1908c4fd34ff7e8cf4bdca8..473f388d1217f1aefefd7a9ad3d73c06841eab10 100644 (file)
@@ -103,17 +103,31 @@ static boolean radeon_set_fd_access(struct radeon_drm_cs *applier,
     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)&target;
-
     /* We do things in a specific order here.
      *
      * DRM version first. We need to be sure we're running on a KMS chipset.
@@ -123,71 +137,76 @@ static void do_ioctls(struct radeon_drm_winsys *winsys)
      * 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)
@@ -202,34 +221,10 @@ 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,
@@ -268,16 +263,9 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd)
     }
 
     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);
@@ -289,7 +277,7 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd)
 
     /* 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);
index d5186bc4d178d344646e2b995ec4b1d3c5cb8255..347e1f1d11a0616fc58a71f3d8ee9a65fca1e74d 100644 (file)
@@ -31,7 +31,6 @@
 #define RADEON_DRM_WINSYS_H
 
 #include "radeon_winsys.h"
-
 #include "os/os_thread.h"
 
 struct radeon_drm_winsys {
@@ -40,20 +39,13 @@ 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;
index 3a64e4abc357eecb39e5ace3c421c5de85b52822..915a9c5bad127b02ba1abb61f96e324c3300f9c1 100644 (file)
 
 /* 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"
@@ -55,38 +69,17 @@ struct radeon_winsys_cs {
     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 {
@@ -103,13 +96,13 @@ struct radeon_winsys {
     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.