summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-01-24 22:37:42 +0100
committerJerome Glisse <jglisse@redhat.com>2010-01-24 22:37:42 +0100
commit05590d95d51e29e58534028c323847c199efebe5 (patch)
treec7057a84afa4914d8b2e519fad885bc425404ff5
r600/r700: winsys standalone testing
This is a standalone KMS program for testing and building the r600 winsys API. It does run as root when no X is running, will only work on non RV6XX (well might work on those but haven't tested).
-rw-r--r--Makefile14
-rw-r--r--config.h6
-rw-r--r--list.h542
-rw-r--r--lwrapper.h73
-rw-r--r--mode.c153
-rw-r--r--r.cs388
-rw-r--r--r600_atom.c1347
-rw-r--r--r600_atom_api.h112
-rw-r--r--r600_winsys.h34
-rw-r--r--r600d.h167
-rw-r--r--r700_atom.c23
-rw-r--r--radeon.c144
-rw-r--r--radeon.h57
-rw-r--r--radeon_atom.c93
-rw-r--r--radeon_atom.h111
-rw-r--r--radeon_device.c204
-rw-r--r--radeon_device.h79
-rw-r--r--test.c156
-rw-r--r--triflat.cs830
19 files changed, 4533 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3c20326
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+OBJECTS = radeon.o mode.o test.o r700_atom.o radeon_device.o radeon_atom.o\
+ r600_atom.o
+CFLAGS = -g3 -O0 -std=gnu99 -I/usr/include/drm
+LDFLAGS = -ldrm -ldrm_radeon
+DEPS = radeon.h
+
+radeonkmstest: $(OBJECTS)
+ gcc -o radeonkmstest $(OBJECTS) $(LDFLAGS)
+
+.c.o: $(DEPS)
+ gcc $(CFLAGS) -c $<
+
+clean:
+ rm -f *.o
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..2fc56ef
--- /dev/null
+++ b/config.h
@@ -0,0 +1,6 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define _FILE_OFFSET_BITS 64
+
+#endif
diff --git a/list.h b/list.h
new file mode 100644
index 0000000..a19e709
--- /dev/null
+++ b/list.h
@@ -0,0 +1,542 @@
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+ list->next = list;
+ list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+#else
+extern void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next);
+#endif
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = (void*)0xDEADBEEF;
+ entry->prev = (void*)0xBEEFDEAD;
+}
+#else
+extern void list_del(struct list_head *entry);
+#endif
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old,
+ struct list_head *new)
+{
+ new->next = old->next;
+ new->next->prev = new;
+ new->prev = old->prev;
+ new->prev->next = new;
+}
+
+static inline void list_replace_init(struct list_head *old,
+ struct list_head *new)
+{
+ list_replace(old, new);
+ INIT_LIST_HEAD(old);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+ const struct list_head *head)
+{
+ return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+ return head->next == head;
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+ struct list_head *next = head->next;
+ return (next == head) && (next == head->prev);
+}
+
+/**
+ * list_is_singular - tests whether a list has just one entry.
+ * @head: the list to test.
+ */
+static inline int list_is_singular(const struct list_head *head)
+{
+ return !list_empty(head) && (head->next == head->prev);
+}
+
+static inline void __list_cut_position(struct list_head *list,
+ struct list_head *head, struct list_head *entry)
+{
+ struct list_head *new_first = entry->next;
+ list->next = head->next;
+ list->next->prev = list;
+ list->prev = entry;
+ entry->next = list;
+ head->next = new_first;
+ new_first->prev = head;
+}
+
+/**
+ * list_cut_position - cut a list into two
+ * @list: a new list to add all removed entries
+ * @head: a list with entries
+ * @entry: an entry within head, could be the head itself
+ * and if so we won't cut the list
+ *
+ * This helper moves the initial part of @head, up to and
+ * including @entry, from @head to @list. You should
+ * pass on @entry an element you know is on @head. @list
+ * should be an empty list or a list you do not care about
+ * losing its data.
+ *
+ */
+static inline void list_cut_position(struct list_head *list,
+ struct list_head *head, struct list_head *entry)
+{
+ if (list_empty(head))
+ return;
+ if (list_is_singular(head) &&
+ (head->next != entry && head != entry))
+ return;
+ if (entry == head)
+ INIT_LIST_HEAD(list);
+ else
+ __list_cut_position(list, head, entry);
+}
+
+static inline void __list_splice(const struct list_head *list,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+
+ first->prev = prev;
+ prev->next = first;
+
+ last->next = next;
+ next->prev = last;
+}
+
+/**
+ * list_splice - join two lists, this is designed for stacks
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(const struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head, head->next);
+}
+
+/**
+ * list_splice_tail - join two lists, each list being a queue
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice_tail(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head->prev, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head, head->next);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_splice_tail_init - join two lists and reinitialise the emptied list
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * Each of the lists is a queue.
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_tail_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head->prev, head);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; prefetch(pos->next), pos != (head); \
+ pos = pos->next)
+
+/**
+ * __list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
+ pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+ for (pos = (head)->prev, n = pos->prev; \
+ prefetch(pos->prev), pos != (head); \
+ pos = n, n = pos->prev)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member); \
+ prefetch(pos->member.prev), &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
+ * @pos: the type * to use as a start point
+ * @head: the head of the list
+ * @member: the name of the list_struct within the struct.
+ *
+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
+ */
+#define list_prepare_entry(pos, head, member) \
+ ((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue(pos, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue_reverse - iterate backwards from the given point
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Start to iterate over list of given type backwards, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_reverse(pos, head, member) \
+ for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
+ prefetch(pos->member.prev), &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current point
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, head, member) \
+ for (; prefetch(pos->member.next), &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_from
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member) \
+ for (n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member), \
+ n = list_entry(pos->member.prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+#endif
diff --git a/lwrapper.h b/lwrapper.h
new file mode 100644
index 0000000..93bf02b
--- /dev/null
+++ b/lwrapper.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef LWRAPPER_H
+#define LWRAPPER_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "xf86drm.h"
+#include "radeon_bo.h"
+#include "radeon_drm.h"
+
+typedef uint32_t u32;
+typedef uint64_t u64;
+#define GFP_KERNEL 0
+#define kmalloc(s, gfp) malloc(s)
+#define kfree(p) free(p)
+
+struct idr {
+ u32 cid;
+};
+
+struct mutex {
+ int lock;
+};
+
+#define mutex_init(ptr)
+#define mutex_lock(ptr)
+#define mutex_unlock(ptr)
+
+extern int idr_pre_get(struct idr *idp, int gfp_mask);
+extern int idr_get_new(struct idr *idp, void *ptr, int *id);
+extern void idr_destroy(struct idr *idp);
+extern void idr_init(struct idr *idp);
+
+#include "list.h"
+#define dev_err(d, p, args...) fprintf(stderr, p, args)
+
+struct kref {
+ int refcount;
+};
+
+void kref_set(struct kref *kref, int num);
+void kref_init(struct kref *kref);
+void kref_get(struct kref *kref);
+int kref_put(struct kref *kref, void (*release) (struct kref *kref));
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+#endif
diff --git a/mode.c b/mode.c
new file mode 100644
index 0000000..7043bc3
--- /dev/null
+++ b/mode.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright © 2009 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include "xf86drm.h"
+#include "radeon_drm.h"
+#include "radeon.h"
+#include "radeon_bo.h"
+
+const char *connector_status(drmModeConnector *connector)
+{
+ switch (connector->connection) {
+ case DRM_MODE_CONNECTED:
+ return "connected";
+ case DRM_MODE_DISCONNECTED:
+ return "disconnected";
+ }
+ return "unknown";
+}
+
+int radeon_mode_configure(struct radeon *radeon)
+{
+ struct radeon_mode *mode = &radeon->mode;
+ drmModeRes *resources;
+ drmModeConnector *connector;
+ drmModeEncoder *encoder;
+ u32 connector_id;
+ int r;
+
+ r = drmSetMaster(radeon->fd);
+ if (r) {
+ fprintf(stderr, "Failed to set master\n");
+ perror(NULL);
+ }
+ mode->bo = NULL;
+ mode->fb_id = 0;
+ resources = drmModeGetResources(radeon->fd);
+ if (resources == NULL) {
+ fprintf(stderr, "Failed to get resources from card\n");
+ return -EINVAL;
+ }
+ /* Iterates through connector an pick first one with a valid mode */
+ printf("%d connectors\n", resources->count_connectors);
+ for (int i = 0; i < resources->count_connectors; i++) {
+ connector = drmModeGetConnector(radeon->fd, resources->connectors[i]);
+ if (connector == NULL) {
+ fprintf(stderr, "Could not get connector %i\n",
+ resources->connectors[i]);
+ r = -EINVAL;
+ goto out;
+ }
+ printf("connector(%d) %s to encoder(%d)\n", connector->connector_id,
+ connector_status(connector), connector->encoder_id);
+ for (int j = 0; j < connector->count_modes; j++) {
+ if (connector->modes[j].type & DRM_MODE_TYPE_PREFERRED) {
+ memcpy(&mode->info, &connector->modes[j],
+ sizeof(drmModeModeInfo));
+ mode->connector_id = connector->connector_id;
+ mode->encoder_id = connector->encoder_id;
+ drmModeFreeConnector(connector);
+ goto setmode;
+ }
+ }
+ drmModeFreeConnector(connector);
+ }
+ fprintf(stderr, "No modes found !\n");
+ r = -EINVAL;
+ goto out;
+setmode:
+ /* Find crtc id */
+ encoder = drmModeGetEncoder(radeon->fd, mode->encoder_id);
+ if (encoder == NULL) {
+ fprintf(stderr, "Could not get encoder %i\n", mode->encoder_id);
+ r = -EINVAL;
+ goto out;
+ }
+ mode->crtc_id = resources->crtcs[ffs(encoder->possible_crtcs)-1];
+ drmModeFreeEncoder(encoder);
+ /* Allocate buffer */
+ mode->bpp = 4;
+ mode->height = mode->info.vdisplay;
+ mode->pitch = mode->info.hdisplay * mode->bpp;
+ mode->size = mode->pitch * mode->info.vdisplay;
+ mode->bo = radeon_bo_open(radeon->bom, 0, mode->size, 0,
+ RADEON_GEM_DOMAIN_VRAM, 0);
+ if (mode->bo == NULL) {
+ fprintf(stderr, "failed to create fb: %s\n", strerror(errno));
+ goto out;
+ }
+ r = drmModeAddFB(radeon->fd, mode->info.hdisplay, mode->info.vdisplay,
+ 32, 32, mode->pitch, mode->bo->handle, &mode->fb_id);
+ if (r) {
+ fprintf(stderr, "failed to add fb: %s 0x%08X\n", strerror(errno), mode->bo->handle);
+ goto out;
+ }
+ printf("Mode: %dx%d %dbpp on CRTC(%d) connector(%d)\n", mode->info.hdisplay,
+ mode->info.vdisplay, mode->bpp*8, mode->crtc_id,
+ mode->connector_id);
+ connector_id = mode->connector_id;
+ r = drmModeSetCrtc(radeon->fd, mode->crtc_id, mode->fb_id, 0, 0,
+ &connector_id, 1, &mode->info);
+ if (r) {
+ fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
+ goto out;
+ }
+ if (connector_id != mode->connector_id) {
+ fprintf(stderr, "Set mode on different connector %d, expected %d\n",
+ connector_id, mode->connector_id);
+ }
+out:
+ if (r && mode->fb_id) {
+ drmModeRmFB(radeon->fd, mode->fb_id);
+ mode->fb_id = 0;
+ }
+ if (r && mode->bo) {
+ mode->bo = radeon_bo_unref(mode->bo);
+ }
+ drmModeFreeResources(resources);
+ return r;
+}
+
+void radeon_mode_cleanup(struct radeon *radeon)
+{
+ if (radeon->mode.fb_id) {
+ drmModeRmFB(radeon->fd, radeon->mode.fb_id);
+ radeon->mode.fb_id = 0;
+ }
+ if (radeon->mode.bo) {
+ radeon_bo_unmap(radeon->mode.bo);
+ radeon->mode.bo = radeon_bo_unref(radeon->mode.bo);
+ }
+ drmDropMaster(radeon->fd);
+}
diff --git a/r.cs b/r.cs
new file mode 100644
index 0000000..4fd9c0d
--- /dev/null
+++ b/r.cs
@@ -0,0 +1,388 @@
+(3) PACKET3(0x28, 1, CONTEXT_CONTROL)
+(4) 0x80000000
+(5) 0x80000000
+(6) PACKET3(0x46, 0, EVENT_WRITE)
+(7) 0x00000016
+(8) PACKET3(0x68, 1, SET_CONFIG_REG)
+(9) 0x00000010 (index)
+(10) 0x00008040 = 0x00028000 (unknown)
+(11) PACKET3(0x68, 6, SET_CONFIG_REG)
+(12) 0x00000300 (index)
+(13) 0x00008C00 = 0x0000000D SQ_CONFIG
+(14) 0x00008C04 = 0x40240054 SQ_GPR_RESOURCE_MGMT_1
+(15) 0x00008C08 = 0x00000000 SQ_GPR_RESOURCE_MGMT_2
+(16) 0x00008C0C = 0x00003CBC SQ_THREAD_RESOURCE_MGMT
+(17) 0x00008C10 = 0x00800080 SQ_STACK_RESOURCE_MGMT_1
+(18) 0x00008C14 = 0x00000000 SQ_STACK_RESOURCE_MGMT_2
+(22) PACKET3(0x68, 1, SET_CONFIG_REG)
+(23) 0x000005C5 (index)
+(24) 0x00009714 = 0x00000000 (unknown)
+(25) PACKET3(0x68, 1, SET_CONFIG_REG)
+(26) 0x00000363 (index)
+(27) 0x00008D8C = 0x00004000 (unknown)
+(28) PACKET3(0x68, 1, SET_CONFIG_REG)
+(29) 0x0000060C (index)
+(30) 0x00009830 = 0x00000000 (unknown)
+(31) PACKET3(0x68, 1, SET_CONFIG_REG)
+(32) 0x0000060E (index)
+(33) 0x00009838 = 0x00420204 (unknown)
+(34) PACKET3(0x69, 9, SET_CONTEXT_REG)
+(35) 0x0000022A (index)
+(36) 0x000288A8 = 0x00000000 SQ_ESGS_RING_ITEMSIZE
+(37) 0x000288AC = 0x00000000 SQ_GSVS_RING_ITEMSIZE
+(38) 0x000288B0 = 0x00000000 SQ_ESTMP_RING_ITEMSIZE
+(39) 0x000288B4 = 0x00000000 SQ_GSTMP_RING_ITEMSIZE
+(40) 0x000288B8 = 0x00000000 SQ_VSTMP_RING_ITEMSIZE
+(41) 0x000288BC = 0x00000000 SQ_PSTMP_RING_ITEMSIZE
+(42) 0x000288C0 = 0x00000000 SQ_FBUF_RING_ITEMSIZE
+(43) 0x000288C4 = 0x00000000 SQ_REDUC_RING_ITEMSIZE
+(44) 0x000288C8 = 0x00000000 SQ_GS_VERT_ITEMSIZE
+(45) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(46) 0x0000000A (index)
+(47) 0x00028028 = 0x00000000 DB_STENCIL_CLEAR
+(48) 0x0002802C = 0x3F800000 DB_DEPTH_CLEAR
+(49) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(50) 0x00000200 (index)
+(51) 0x00028800 = 0x00700700 DB_DEPTH_CONTROL
+(52) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(53) 0x00000203 (index)
+(54) 0x0002880C = 0x00000210 DB_SHADER_CONTROL
+(55) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(56) 0x00000343 (index)
+(57) 0x00028D0C = 0x00000060 DB_RENDER_CONTROL
+(58) 0x00028D10 = 0x0000002A DB_RENDER_OVERRIDE
+(59) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(60) 0x00000351 (index)
+(61) 0x00028D44 = 0x0000AA00 (unknown)
+(62) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(63) 0x0000010C (index)
+(64) 0x00028430 = 0xFFFFFF00 DB_STENCILREFMASK
+(65) 0x00028434 = 0xFFFFFF00 DB_STENCILREFMASK_BF
+(66) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(67) 0x0000008C (index)
+(68) 0x00028230 = 0xAAAAAAAA (unknown)
+(109) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(110) 0x00000308 (index)
+(111) 0x00028C20 = 0x00000000 (unknown)
+(156) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(157) 0x000001E8 (index)
+(158) 0x000287A0 = 0x00000003 (unknown)
+(191) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(192) 0x000001E0 (index)
+(193) 0x00028780 = 0x00010001 CB_BLEND0_CONTROL
+(194) PACKET3(0x69, 4, SET_CONTEXT_REG)
+(195) 0x00000105 (index)
+(196) 0x00028414 = 0x00000000 CB_BLEND_RED
+(197) 0x00028418 = 0x00000000 CB_BLEND_GREEN
+(198) 0x0002841C = 0x00000000 CB_BLEND_BLUE
+(199) 0x00028420 = 0x00000000 CB_BLEND_ALPHA
+(200) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(201) 0x000000D4 (index)
+(202) 0x00028350 = 0x00000000 SX_MISC
+(203) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(204) 0x00000104 (index)
+(205) 0x00028410 = 0x00000000 SX_ALPHA_TEST_CONTROL
+(206) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(207) 0x0000010E (index)
+(208) 0x00028438 = 0x00000000 SX_ALPHA_REF
+(209) PACKET3(0x69, 4, SET_CONTEXT_REG)
+(210) 0x00000100 (index)
+(211) 0x00028400 = 0x00FFFFFF VGT_MAX_VTX_INDX
+(212) 0x00028404 = 0x00000000 VGT_MIN_VTX_INDX
+(213) 0x00028408 = 0x00000000 VGT_INDX_OFFSET
+(214) 0x0002840C = 0x00000000 VGT_MULTI_PRIM_IB_RESET_INDX
+(215) PACKET3(0x69, 13, SET_CONTEXT_REG)
+(216) 0x00000284 (index)
+(217) 0x00028A10 = 0x00000000 VGT_OUTPUT_PATH_CNTL
+(218) 0x00028A14 = 0x00000000 VGT_HOS_CNTL
+(219) 0x00028A18 = 0x00000000 VGT_HOS_MAX_TESS_LEVEL
+(220) 0x00028A1C = 0x00000000 VGT_HOS_MIN_TESS_LEVEL
+(221) 0x00028A20 = 0x00000000 VGT_HOS_REUSE_DEPTH
+(222) 0x00028A24 = 0x00000000 VGT_GROUP_PRIM_TYPE
+(223) 0x00028A28 = 0x00000000 VGT_GROUP_FIRST_DECR
+(224) 0x00028A2C = 0x00000000 VGT_GROUP_DECR
+(225) 0x00028A30 = 0x00000000 VGT_GROUP_VECT_0_CNTL
+(226) 0x00028A34 = 0x00000000 VGT_GROUP_VECT_1_CNTL
+(227) 0x00028A38 = 0x00000000 VGT_GROUP_VECT_0_FMT_CNTL
+(228) 0x00028A3C = 0x00000000 VGT_GROUP_VECT_1_FMT_CNTL
+(229) 0x00028A40 = 0x00000000 VGT_GS_MODE
+(230) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(231) 0x000002A1 (index)
+(232) 0x00028A84 = 0x00000000 VGT_PRIMITIVEID_EN
+(233) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(234) 0x000002A5 (index)
+(235) 0x00028A94 = 0x00000000 VGT_MULTI_PRIM_IB_RESET_EN
+(236) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(237) 0x000002A8 (index)
+(238) 0x00028AA0 = 0x00000000 VGT_INSTANCE_STEP_RATE_0
+(239) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(240) 0x000002A9 (index)
+(241) 0x00028AA4 = 0x00000000 VGT_INSTANCE_STEP_RATE_1
+(242) PACKET3(0x69, 3, SET_CONTEXT_REG)
+(243) 0x000002AC (index)
+(244) 0x00028AB0 = 0x00000000 VGT_STRMOUT_EN
+(245) 0x00028AB4 = 0x00000001 VGT_REUSE_OFF
+(246) 0x00028AB8 = 0x00000000 VGT_VTX_CNT_EN
+(247) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(248) 0x000002C8 (index)
+(249) 0x00028B20 = 0x00000000 VGT_STRMOUT_BUFFER_EN
+(250) PACKET3(0x69, 32, SET_CONTEXT_REG)
+(251) 0x000000E0 (index)
+(252) 0x00028380 = 0x00000000 SQ_VTX_SEMANTIC_0
+(253) 0x00028384 = 0x00000000 SQ_VTX_SEMANTIC_1
+(254) 0x00028388 = 0x00000000 SQ_VTX_SEMANTIC_2
+(255) 0x0002838C = 0x00000000 SQ_VTX_SEMANTIC_3
+(256) 0x00028390 = 0x00000000 SQ_VTX_SEMANTIC_4
+(257) 0x00028394 = 0x00000000 SQ_VTX_SEMANTIC_5
+(258) 0x00028398 = 0x00000000 SQ_VTX_SEMANTIC_6
+(259) 0x0002839C = 0x00000000 SQ_VTX_SEMANTIC_7
+(260) 0x000283A0 = 0x00000000 SQ_VTX_SEMANTIC_8
+(261) 0x000283A4 = 0x00000000 SQ_VTX_SEMANTIC_9
+(262) 0x000283A8 = 0x00000000 SQ_VTX_SEMANTIC_10
+(263) 0x000283AC = 0x00000000 SQ_VTX_SEMANTIC_11
+(264) 0x000283B0 = 0x00000000 SQ_VTX_SEMANTIC_12
+(265) 0x000283B4 = 0x00000000 SQ_VTX_SEMANTIC_13
+(266) 0x000283B8 = 0x00000000 SQ_VTX_SEMANTIC_14
+(267) 0x000283BC = 0x00000000 SQ_VTX_SEMANTIC_15
+(268) 0x000283C0 = 0x00000000 SQ_VTX_SEMANTIC_16
+(269) 0x000283C4 = 0x00000000 SQ_VTX_SEMANTIC_17
+(270) 0x000283C8 = 0x00000000 SQ_VTX_SEMANTIC_18
+(271) 0x000283CC = 0x00000000 SQ_VTX_SEMANTIC_19
+(272) 0x000283D0 = 0x00000000 SQ_VTX_SEMANTIC_20
+(273) 0x000283D4 = 0x00000000 SQ_VTX_SEMANTIC_21
+(274) 0x000283D8 = 0x00000000 SQ_VTX_SEMANTIC_22
+(275) 0x000283DC = 0x00000000 SQ_VTX_SEMANTIC_23
+(276) 0x000283E0 = 0x00000000 SQ_VTX_SEMANTIC_24
+(277) 0x000283E4 = 0x00000000 SQ_VTX_SEMANTIC_25
+(278) 0x000283E8 = 0x00000000 SQ_VTX_SEMANTIC_26
+(279) 0x000283EC = 0x00000000 SQ_VTX_SEMANTIC_27
+(280) 0x000283F0 = 0x00000000 SQ_VTX_SEMANTIC_28
+(281) 0x000283F4 = 0x00000000 SQ_VTX_SEMANTIC_29
+(282) 0x000283F8 = 0x00000000 SQ_VTX_SEMANTIC_30
+(283) 0x000283FC = 0x00000000 SQ_VTX_SEMANTIC_31
+(284) PACKET3(0x69, 10, SET_CONTEXT_REG)
+(285) 0x00000185 (index)
+(286) 0x00028614 = 0x03020100 SPI_VS_OUT_ID_0
+(287) 0x00028618 = 0x07060504 SPI_VS_OUT_ID_1
+(288) 0x0002861C = 0x0B0A0908 SPI_VS_OUT_ID_2
+(289) 0x00028620 = 0x0F0E0D0C SPI_VS_OUT_ID_3
+(290) 0x00028624 = 0x00000000 SPI_VS_OUT_ID_4
+(291) 0x00028628 = 0x00000000 SPI_VS_OUT_ID_5
+(292) 0x0002862C = 0x00000000 SPI_VS_OUT_ID_6
+(293) 0x00028630 = 0x00000000 SPI_VS_OUT_ID_7
+(294) 0x00028634 = 0x00000000 SPI_VS_OUT_ID_8
+(295) 0x00028638 = 0x00000000 SPI_VS_OUT_ID_9
+(296) PACKET3(0x69, 9, SET_CONTEXT_REG)
+(297) 0x000001B1 (index)
+(298) 0x000286C4 = 0x00000000 SPI_VS_OUT_CONFIG
+(299) 0x000286C8 = 0x00000001 (unknown)
+(300) 0x000286CC = 0x10000001 SPI_PS_IN_CONTROL_0
+(301) 0x000286D0 = 0x00000000 SPI_PS_IN_CONTROL_1
+(302) 0x000286D4 = 0x00000000 SPI_INTERP_CONTROL_0
+(303) 0x000286D8 = 0x00000000 SPI_INPUT_Z
+(304) 0x000286DC = 0x00000000 SPI_FOG_CNTL
+(305) 0x000286E0 = 0x00000000 SPI_FOG_FUNC_SCALE
+(306) 0x000286E4 = 0x00000000 SPI_FOG_FUNC_BIAS
+(307) PACKET3(0x69, 32, SET_CONTEXT_REG)
+(308) 0x00000191 (index)
+(309) 0x00028644 = 0x00000800 SPI_PS_INPUT_CNTL_0
+(310) 0x00028648 = 0x00000000 SPI_PS_INPUT_CNTL_1
+(311) 0x0002864C = 0x00000000 SPI_PS_INPUT_CNTL_2
+(312) 0x00028650 = 0x00000000 SPI_PS_INPUT_CNTL_3
+(313) 0x00028654 = 0x00000000 SPI_PS_INPUT_CNTL_4
+(314) 0x00028658 = 0x00000000 SPI_PS_INPUT_CNTL_5
+(315) 0x0002865C = 0x00000000 SPI_PS_INPUT_CNTL_6
+(316) 0x00028660 = 0x00000000 SPI_PS_INPUT_CNTL_7
+(317) 0x00028664 = 0x00000000 SPI_PS_INPUT_CNTL_8
+(318) 0x00028668 = 0x00000000 SPI_PS_INPUT_CNTL_9
+(319) 0x0002866C = 0x00000000 SPI_PS_INPUT_CNTL_10
+(320) 0x00028670 = 0x00000000 SPI_PS_INPUT_CNTL_11
+(321) 0x00028674 = 0x00000000 SPI_PS_INPUT_CNTL_12
+(322) 0x00028678 = 0x00000000 SPI_PS_INPUT_CNTL_13
+(323) 0x0002867C = 0x00000000 SPI_PS_INPUT_CNTL_14
+(324) 0x00028680 = 0x00000000 SPI_PS_INPUT_CNTL_15
+(325) 0x00028684 = 0x00000000 SPI_PS_INPUT_CNTL_16
+(326) 0x00028688 = 0x00000000 SPI_PS_INPUT_CNTL_17
+(327) 0x0002868C = 0x00000000 SPI_PS_INPUT_CNTL_18
+(328) 0x00028690 = 0x00000000 SPI_PS_INPUT_CNTL_19
+(329) 0x00028694 = 0x00000000 SPI_PS_INPUT_CNTL_20
+(330) 0x00028698 = 0x00000000 SPI_PS_INPUT_CNTL_21
+(331) 0x0002869C = 0x00000000 SPI_PS_INPUT_CNTL_22
+(332) 0x000286A0 = 0x00000000 SPI_PS_INPUT_CNTL_23
+(333) 0x000286A4 = 0x00000000 SPI_PS_INPUT_CNTL_24
+(334) 0x000286A8 = 0x00000000 SPI_PS_INPUT_CNTL_25
+(335) 0x000286AC = 0x00000000 SPI_PS_INPUT_CNTL_26
+(336) 0x000286B0 = 0x00000000 SPI_PS_INPUT_CNTL_27
+(337) 0x000286B4 = 0x00000000 SPI_PS_INPUT_CNTL_28
+(338) 0x000286B8 = 0x00000000 SPI_PS_INPUT_CNTL_29
+(339) 0x000286BC = 0x00000000 SPI_PS_INPUT_CNTL_30
+(340) 0x000286C0 = 0x00000000 SPI_PS_INPUT_CNTL_31
+(341) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(342) 0x00000094 (index)
+(343) 0x00028250 = 0x80000000 (unknown)
+(344) 0x00028254 = 0x00FA00FA (unknown)
+(345) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(346) 0x000000B4 (index)
+(347) 0x000282D0 = 0x00000000 PA_SC_VPORT_ZMIN_0
+(348) 0x000282D4 = 0x3F800000 PA_SC_VPORT_ZMAX_0
+(349) PACKET3(0x69, 6, SET_CONTEXT_REG)
+(350) 0x0000010F (index)
+(351) 0x0002843C = 0x42FA0000 PA_CL_VPORT_XSCALE_0
+(352) 0x00028440 = 0x42FA0000 PA_CL_VPORT_XOFFSET_0
+(353) 0x00028444 = 0xC2FA0000 PA_CL_VPORT_YSCALE_0
+(354) 0x00028448 = 0x42FA0000 PA_CL_VPORT_YOFFSET_0
+(355) 0x0002844C = 0x3F000000 PA_CL_VPORT_ZSCALE_0
+(356) 0x00028450 = 0x3F000000 PA_CL_VPORT_ZOFFSET_0
+(357) PACKET3(0x43, 3, SURFACE_SYNC)
+(358) 0x08000000
+(359) 0x00000001
+(360) 0x00000000
+(361) 0x0000000A
+(362) PACKET3(0x10, 0, NOP)
+(363) 0x00000004
+(364) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(365) 0x00000225 (index)
+(366) 0x00028894 = 0x00000000 SQ_PGM_START_FS
+(367) PACKET3(0x10, 0, NOP)
+(368) 0x00000004
+(369) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(370) 0x00000229 (index)
+(371) 0x000288A4 = 0x00000000 SQ_PGM_RESOURCES_FS
+(372) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(373) 0x00000237 (index)
+(374) 0x000288DC = 0x00000000 SQ_PGM_CF_OFFSET_FS
+(375) PACKET3(0x43, 3, SURFACE_SYNC)
+(376) 0x08000000
+(377) 0x00000001
+(378) 0x00000000
+(379) 0x0000000A
+(380) PACKET3(0x10, 0, NOP)
+(381) 0x00000004
+(382) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(383) 0x00000216 (index)
+(384) 0x00028858 = 0x00000000 SQ_PGM_START_VS
+(385) PACKET3(0x10, 0, NOP)
+(386) 0x00000004
+(387) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(388) 0x0000021A (index)
+(389) 0x00028868 = 0x00000006 SQ_PGM_RESOURCES_VS
+(390) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(391) 0x00000234 (index)
+(392) 0x000288D0 = 0x00000000 SQ_PGM_CF_OFFSET_VS
+(393) PACKET3(0x6C, 1, SET_LOOP_CONST)
+(394) 0x00000020
+(395) 0x0100000F
+(396) PACKET3(0x43, 3, SURFACE_SYNC)
+(397) 0x08000000
+(398) 0x00000001
+(399) 0x00000000
+(400) 0x0000000A
+(401) PACKET3(0x10, 0, NOP)
+(402) 0x00000008
+(403) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(404) 0x00000210 (index)
+(405) 0x00028840 = 0x00000000 SQ_PGM_START_PS
+(406) PACKET3(0x10, 0, NOP)
+(407) 0x00000008
+(408) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(409) 0x00000214 (index)
+(410) 0x00028850 = 0x00000003 SQ_PGM_RESOURCES_PS
+(411) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(412) 0x00000215 (index)
+(413) 0x00028854 = 0x00000002 SQ_PGM_EXPORTS_PS
+(414) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(415) 0x00000233 (index)
+(416) 0x000288CC = 0x00000000 SQ_PGM_CF_OFFSET_PS
+(417) PACKET3(0x6C, 1, SET_LOOP_CONST)
+(418) 0x00000000
+(419) 0x01000FFF
+(420) PACKET3(0x6A, 16, SET_ALU_CONST)
+(421) 0x00000400
+(422) 0x3C03126F
+(423) 0x00000000
+(424) 0x00000000
+(425) 0xBF800000
+(426) 0x00000000
+(427) 0x3C03126F
+(428) 0x00000000
+(429) 0xBF800000
+(430) 0x00000000
+(431) 0x00000000
+(432) 0xBF800000
+(433) 0x00000000
+(434) 0x00000000
+(435) 0x00000000
+(436) 0x00000000
+(437) 0x3F800000
+(438) PACKET3(0x6F, 1, SET_CTL_CONST)
+(439) 0x00000000
+(440) 0x00000000
+(441) PACKET3(0x6F, 1, SET_CTL_CONST)
+(442) 0x00000001
+(443) 0x00000000
+(444) PACKET3(0x43, 3, SURFACE_SYNC)
+(445) 0x01000000
+(446) 0x00000001
+(447) 0x00000000
+(448) 0x0000000A
+(449) PACKET3(0x10, 0, NOP)
+(450) 0x0000000C
+(451) PACKET3(0x6D, 7, SET_RESOURCE)
+(452) 0x00000460
+(453) 0x00000000
+(454) 0x0000006F
+(455) 0x03001C00
+(456) 0x00000001
+(457) 0x00000000
+(458) 0x00000000
+(459) 0xC0000000
+(460) PACKET3(0x10, 0, NOP)
+(461) 0x0000000C
+(462) PACKET3(0x43, 3, SURFACE_SYNC)
+(463) 0x01000000
+(464) 0x00000001
+(465) 0x00000000
+(466) 0x0000000A
+(467) PACKET3(0x10, 0, NOP)
+(468) 0x0000000C
+(469) PACKET3(0x6D, 7, SET_RESOURCE)
+(470) 0x00000475
+(471) 0x0000000C
+(472) 0x0000006F
+(473) 0x02301C00
+(474) 0x00000001
+(475) 0x00000000
+(476) 0x00000000
+(477) 0xC0000000
+(478) PACKET3(0x10, 0, NOP)
+(479) 0x0000000C
+(480) PACKET3(0x68, 1, SET_CONFIG_REG)
+(481) 0x00000256 (index)
+(482) 0x00008958 = 0x00000005 VGT_PRIMITIVE_TYPE
+(483) PACKET3(0x2A, 0, INDEX_TYPE)
+(484) 0x00000000
+(485) PACKET3(0x2F, 0, NUM_INSTANCES)
+(486) 0x00000001
+(487) PACKET3(0x2D, 1, DRAW_INDEX_AUTO)
+(488) 0x00000004
+(489) 0x00000002
+(490) PACKET3(0x46, 0, EVENT_WRITE)
+(491) 0x00000016
+(492) PACKET3(0x68, 1, SET_CONFIG_REG)
+(493) 0x00000010 (index)
+(494) 0x00008040 = 0x00028000 (unknown)
+(495) PACKET3(0x43, 3, SURFACE_SYNC)
+(496) 0x02000040
+(497) 0x000003F0
+(498) 0x00000000
+(499) 0x0000000A
+(500) PACKET3(0x10, 0, NOP)
+(501) 0x00000000
+(502) PACKET3(0x28, 1, CONTEXT_CONTROL)
+(503) 0x80000000
+(504) 0x80000000
+(505) PACKET3(0x46, 0, EVENT_WRITE)
+(506) 0x00000016
+(507) PACKET3(0x68, 1, SET_CONFIG_REG)
+(508) 0x00000010 (index)
+(509) 0x00008040 = 0x00028000 (unknown)
diff --git a/r600_atom.c b/r600_atom.c
new file mode 100644
index 0000000..6610e45
--- /dev/null
+++ b/r600_atom.c
@@ -0,0 +1,1347 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "radeon.h"
+#include "radeon_device.h"
+#include "r600d.h"
+
+/*
+ * helpers functions
+ */
+static int r600_atom_process_default(struct radeon_device *rdev,
+ struct radeon_atom *atom,
+ u32 last_id,
+ void *data)
+{
+ struct r600_batch *batch = data;
+
+ if (atom->id != last_id) {
+ batch->npkts += atom->npkts;
+ }
+ return 0;
+}
+
+/*
+ * r600_cb
+ */
+struct r600_cb {
+ struct radeon_atom atom;
+ u32 pkts[900];
+ u32 placements[2];
+ struct radeon_bo *bo;
+ struct radeon_bo *vsshader1;
+ struct radeon_bo *vsshader2;
+ struct radeon_bo *psshader1;
+ struct radeon_bo *vbo1;
+ struct radeon_bo *vbo2;
+ struct r600_atoms *atoms;
+};
+
+static void r600_cb_release(struct kref *kref)
+{
+ struct radeon_atom *atom = container_of(kref, struct radeon_atom, kref);
+ struct r600_cb *cb = container_of(atom, struct r600_cb, atom);
+
+ mutex_lock(&cb->atoms->mutex);
+ list_del_init(&cb->atom.list);
+ mutex_unlock(&cb->atoms->mutex);
+ if (cb->bo)
+ radeon_bo_unref(cb->bo);
+ if (cb->vsshader1)
+ radeon_bo_unref(cb->vsshader1);
+ if (cb->vsshader2)
+ radeon_bo_unref(cb->vsshader2);
+ if (cb->psshader1)
+ radeon_bo_unref(cb->psshader1);
+ if (cb->vbo1)
+ radeon_bo_unref(cb->vbo1);
+ if (cb->vbo2)
+ radeon_bo_unref(cb->vbo2);
+ kfree(cb);
+}
+
+static int r600_cb_emit(struct radeon_device *rdev,
+ struct radeon_atom *atom,
+ void *data,
+ struct radeon_ib *ib)
+{
+ struct r600_cb *cb = (struct r600_cb *)atom;
+ int r;
+
+ cb->pkts[16] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]);
+ cb->pkts[21] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]);
+ cb->pkts[26] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]);
+ cb->pkts[271] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[276] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[289] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[294] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[310] = radeon_ib_reloc(ib, cb->psshader1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[315] = radeon_ib_reloc(ib, cb->psshader1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[358] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[369] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[376] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[387] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[409] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]);
+ r = radeon_ib_copy(ib, cb->pkts, atom->npkts);
+ return r;
+}
+
+static int r600_cb_process(struct radeon_device *rdev,
+ struct radeon_atom *atom,
+ u32 last_id,
+ void *data)
+{
+ struct r600_batch *batch = data;
+ struct r600_cb *cb = (struct r600_cb *)atom;
+ int r;
+
+ if (atom->id != last_id) {
+ batch->npkts += atom->npkts;
+ }
+ /* FIXME: proper flags */
+ r = radeon_atom_flush_add(&batch->post_flushes, cb->bo, 0);
+ if (r < 0)
+ return r;
+ return 0;
+}
+
+/* FIXME delete */
+void r600_tflat(struct radeon_atom *atom);
+int r600_tflat_init(struct radeon *radeon, struct r600_cb *cb);
+
+static int r600_cb_create(struct radeon_device *rdev,
+ struct drm_radeon_atom *patom,
+ struct radeon_atom **atom)
+{
+ struct drm_r600_cb pcb;
+ struct r600_cb *cb;
+ struct r700_asic *cfg = &rdev->asic.r700;
+ u32 bpe, tmp;
+ int r;
+
+ cb = kmalloc(sizeof(*cb), GFP_KERNEL);
+ if (cb == NULL)
+ return -ENOMEM;
+ /* make sure structure properly initialized */
+ memset(cb, 0, sizeof(*cb));
+ INIT_LIST_HEAD(&cb->atom.list);
+ kref_init(&cb->atom.kref);
+ cb->atom.release = &r600_cb_release;
+ cb->atom.emit = &r600_cb_emit;
+ cb->atom.process = &r600_cb_process;
+ cb->atom.pkts = cb->pkts;
+ cb->placements[0] = pcb.placements[0];
+ cb->placements[1] = pcb.placements[1];
+ cb->atom.nflushes = 1;
+ /* KERNEL use get user data */
+ memcpy(&pcb, (void*)(unsigned long)patom->data, sizeof(struct drm_r600_cb));
+ /* take a references on the bo */
+ cb->bo = pcb.bo;
+ radeon_bo_ref(cb->bo);
+ r = r600_tflat_init(rdev->radeon, cb);
+ if (r)
+ goto out_err;
+ /* check cb configuration */
+ switch (G_0280A0_FORMAT(pcb.color_info)) {
+ case V_0280A0_COLOR_8:
+ case V_0280A0_COLOR_4_4:
+ case V_0280A0_COLOR_3_3_2:
+ bpe = 1;
+ break;
+ case V_0280A0_COLOR_16:
+ case V_0280A0_COLOR_16_FLOAT:
+ case V_0280A0_COLOR_8_8:
+ case V_0280A0_COLOR_5_6_5:
+ case V_0280A0_COLOR_6_5_5:
+ case V_0280A0_COLOR_1_5_5_5:
+ case V_0280A0_COLOR_4_4_4_4:
+ case V_0280A0_COLOR_5_5_5_1:
+ bpe = 2;
+ break;
+ case V_0280A0_COLOR_32:
+ case V_0280A0_COLOR_32_FLOAT:
+ case V_0280A0_COLOR_16_16:
+ case V_0280A0_COLOR_16_16_FLOAT:
+ case V_0280A0_COLOR_8_24:
+ case V_0280A0_COLOR_8_24_FLOAT:
+ case V_0280A0_COLOR_24_8:
+ case V_0280A0_COLOR_24_8_FLOAT:
+ case V_0280A0_COLOR_10_11_11:
+ case V_0280A0_COLOR_10_11_11_FLOAT:
+ case V_0280A0_COLOR_11_11_10:
+ case V_0280A0_COLOR_11_11_10_FLOAT:
+ case V_0280A0_COLOR_2_10_10_10:
+ case V_0280A0_COLOR_8_8_8_8:
+ case V_0280A0_COLOR_10_10_10_2:
+ case V_0280A0_COLOR_X24_8_32_FLOAT:
+ bpe = 4;
+ break;
+ case V_0280A0_COLOR_32_32:
+ case V_0280A0_COLOR_32_32_FLOAT:
+ case V_0280A0_COLOR_16_16_16_16:
+ case V_0280A0_COLOR_16_16_16_16_FLOAT:
+ bpe = 8;
+ break;
+ case V_0280A0_COLOR_32_32_32_32:
+ case V_0280A0_COLOR_32_32_32_32_FLOAT:
+ bpe = 16;
+ break;
+ case V_0280A0_COLOR_INVALID:
+ default:
+ dev_err(rdev->dev, "%s cb invalid format %d\n", __func__,
+ S_0280A0_FORMAT(pcb.color_info));
+ r = -EINVAL;
+ goto out_err;
+ }
+ switch (G_0280A0_ARRAY_MODE(pcb.color_info)) {
+ case V_0280A0_ARRAY_LINEAR_GENERAL:
+ case V_0280A0_ARRAY_LINEAR_ALIGNED:
+ if ((pcb.pitch) & 0x3f) {
+ dev_err(rdev->dev, "%s:%d cb pitch (%d) invalid\n",
+ __func__, __LINE__, pcb.pitch);
+ r = -EINVAL;
+ goto out_err;
+ }
+ if ((pcb.pitch * bpe) & (cfg->group_bytes - 1)) {
+ dev_err(rdev->dev, "%s:%d cb pitch (%d) invalid\n",
+ __func__, __LINE__, pcb.pitch);
+ r = -EINVAL;
+ goto out_err;
+ }
+ break;
+ case V_0280A0_ARRAY_1D_TILED_THIN1:
+ if ((pcb.pitch) & 0x7) {
+ dev_err(rdev->dev, "%s:%d cb pitch (%d) invalid\n",
+ __func__, __LINE__, pcb.pitch);
+ r = -EINVAL;
+ goto out_err;
+ }
+ if ((pcb.pitch * 8 * bpe * pcb.nsamples) & (cfg->group_bytes - 1)) {
+ dev_err(rdev->dev, "%s:%d cb pitch (%d) invalid\n",
+ __func__, __LINE__, pcb.pitch);
+ r = -EINVAL;
+ goto out_err;
+ }
+ if (pcb.height & 0x7) {
+ dev_err(rdev->dev, "%s:%d cb height (%d) invalid\n",
+ __func__, __LINE__, pcb.height);
+ r = -EINVAL;
+ goto out_err;
+ }
+ break;
+ case V_0280A0_ARRAY_2D_TILED_THIN1:
+ if ((pcb.pitch) & ((8 * cfg->nbanks) - 1)) {
+ dev_err(rdev->dev, "%s:%d cb pitch (%d) invalid\n",
+ __func__, __LINE__, pcb.pitch);
+ r = -EINVAL;
+ goto out_err;
+ }
+ tmp = pcb.pitch * 8 * bpe * pcb.nsamples;
+ tmp = tmp / cfg->nbanks;
+ if (tmp & (cfg->group_bytes - 1)) {
+ dev_err(rdev->dev, "%s:%d cb pitch (%d) invalid\n",
+ __func__, __LINE__, pcb.pitch);
+ r = -EINVAL;
+ goto out_err;
+ }
+ if (pcb.height & ((8 * cfg->npipes) - 1)) {
+ dev_err(rdev->dev, "%s:%d cb height (%d) invalid\n",
+ __func__, __LINE__, pcb.height);
+ r = -EINVAL;
+ goto out_err;
+ }
+ break;
+ default:
+ dev_err(rdev->dev, "%s invalid tiling %d\n", __func__,
+ G_0280A0_ARRAY_MODE(pcb.color_info));
+ r = -EINVAL;
+ goto out_err;
+ }
+ /* cb require a buffer of at list pcb.size */
+ if (radeon_bo_size(pcb.bo) < pcb.pitch * pcb.height * bpe) {
+ dev_err(rdev->dev, "%s bo too small (%d) need (%d) %d %d %d\n",
+ __func__, radeon_bo_size(pcb.bo),
+ pcb.pitch * pcb.height * bpe, pcb.pitch, pcb.height, bpe);
+ return -EINVAL;
+ }
+ /* CB_COLOR0_INFO */
+ cb->pkts[cb->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ cb->pkts[cb->atom.npkts++] = 0x00000028;
+ cb->pkts[cb->atom.npkts++] = pcb.color_info;
+ /* CB_COLOR0_SIZE */
+ cb->pkts[cb->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ cb->pkts[cb->atom.npkts++] = 0x00000018;
+ cb->pkts[cb->atom.npkts++] =
+ S_028060_PITCH_TILE_MAX((pcb.pitch >> 3) - 1) |
+ S_028060_SLICE_TILE_MAX(((pcb.pitch * pcb.height) >> 6) - 1);
+ /* CB_COLOR0_VIEW */
+ cb->pkts[cb->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ cb->pkts[cb->atom.npkts++] = 0x00000020;
+ cb->pkts[cb->atom.npkts++] = 0x00000000;
+ /* CB_COLOR0_MASK */
+ cb->pkts[cb->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ cb->pkts[cb->atom.npkts++] = 0x00000040;
+ cb->pkts[cb->atom.npkts++] = 0x00000000;
+ /* CB_COLOR0_TILE */
+ cb->pkts[cb->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ cb->pkts[cb->atom.npkts++] = 0x00000030;
+ cb->pkts[cb->atom.npkts++] = 0x00000000;
+ cb->pkts[cb->atom.npkts++] = PKT3(PKT3_NOP, 0);
+fprintf(stderr, "cb->pkts[%d] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]);\n", cb->atom.npkts);
+ cb->pkts[cb->atom.npkts++] = 0x00000000;
+ /* CB_COLOR0_FRAG */
+ cb->pkts[cb->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ cb->pkts[cb->atom.npkts++] = 0x00000038;
+ cb->pkts[cb->atom.npkts++] = 0x00000000;
+ cb->pkts[cb->atom.npkts++] = PKT3(PKT3_NOP, 0);
+fprintf(stderr, "cb->pkts[%d] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]);\n", cb->atom.npkts);
+ cb->pkts[cb->atom.npkts++] = 0x00000000;
+ /* CB_COLOR0_BASE */
+ cb->pkts[cb->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ cb->pkts[cb->atom.npkts++] = 0x00000010;
+ cb->pkts[cb->atom.npkts++] = 0x00000000;
+ cb->pkts[cb->atom.npkts++] = PKT3(PKT3_NOP, 0);
+fprintf(stderr, "cb->pkts[%d] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]);\n", cb->atom.npkts);
+ cb->pkts[cb->atom.npkts++] = 0x00000000;
+ r600_tflat(&cb->atom);
+ *atom = &cb->atom;
+ return 0;
+out_err:
+ radeon_atom_put(&cb->atom);
+ *atom = NULL;
+ return r;
+}
+
+/*
+ * r600_cb_cntl
+ */
+struct r600_cb_cntl {
+ struct radeon_atom atom;
+ u32 pkts[16];
+ struct r600_atoms *atoms;
+};
+
+static void r600_cb_cntl_release(struct kref *kref)
+{
+ struct radeon_atom *atom = container_of(kref, struct radeon_atom, kref);
+ struct r600_cb_cntl *cb_cntl = container_of(atom, struct r600_cb_cntl, atom);
+
+ mutex_lock(&cb_cntl->atoms->mutex);
+ list_del_init(&cb_cntl->atom.list);
+ mutex_unlock(&cb_cntl->atoms->mutex);
+ kfree(cb_cntl);
+}
+
+static int r600_cb_cntl_create(struct radeon_device *rdev,
+ struct drm_radeon_atom *patom,
+ struct radeon_atom **atom)
+{
+ struct drm_r600_cb_cntl pcb_cntl;
+ struct r600_cb_cntl *cb_cntl;
+ int r;
+
+ cb_cntl = kmalloc(sizeof(*cb_cntl), GFP_KERNEL);
+ if (cb_cntl == NULL)
+ return -ENOMEM;
+ /* make sure structure properly initialized */
+ memset(cb_cntl, 0, sizeof(*cb_cntl));
+ INIT_LIST_HEAD(&cb_cntl->atom.list);
+ kref_init(&cb_cntl->atom.kref);
+ cb_cntl->atom.release = &r600_cb_cntl_release;
+ cb_cntl->atom.emit = &radeon_atom_emit_default;
+ cb_cntl->atom.process = &r600_atom_process_default;
+ cb_cntl->atom.pkts = cb_cntl->pkts;
+ /* KERNEL use get user data */
+ memcpy(&pcb_cntl, (void*)(unsigned long)patom->data, sizeof(struct drm_r600_cb_cntl));
+ /* CB_TARGET_MASK */
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 2);
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = 0x0000008E;
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = pcb_cntl.cb_target_mask;
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = pcb_cntl.cb_shader_mask;
+ /* CB_CLRCMP_CONTROL */
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 4);
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = 0x0000030C;
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = pcb_cntl.cb_clrcmp_control;
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = pcb_cntl.cb_clrcmp_src;
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = pcb_cntl.cb_clrcmp_dst;
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = pcb_cntl.cb_clrcmp_msk;
+ /* CB_COLOR_CONTROL */
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = 0x00000202;
+ cb_cntl->pkts[cb_cntl->atom.npkts++] = pcb_cntl.cb_color_control;
+ *atom = &cb_cntl->atom;
+fprintf(stderr, "%s %d pkts\n", __func__, (*atom)->npkts);
+ return 0;
+out_err:
+ radeon_atom_put(&cb_cntl->atom);
+ *atom = NULL;
+ return r;
+}
+
+/*
+ * r600_tp
+ */
+struct r600_tp {
+ struct radeon_atom atom;
+ u32 pkts[4];
+ struct r600_atoms *atoms;
+};
+
+static void r600_tp_release(struct kref *kref)
+{
+ struct radeon_atom *atom = container_of(kref, struct radeon_atom, kref);
+ struct r600_tp *tp = container_of(atom, struct r600_tp, atom);
+
+ mutex_lock(&tp->atoms->mutex);
+ list_del_init(&tp->atom.list);
+ mutex_unlock(&tp->atoms->mutex);
+ kfree(tp);
+}
+
+static int r600_tp_create(struct radeon_device *rdev,
+ struct drm_radeon_atom *patom,
+ struct radeon_atom **atom)
+{
+ struct drm_r600_tp ptp;
+ struct r600_tp *tp;
+ int r;
+
+ tp = kmalloc(sizeof(*tp), GFP_KERNEL);
+ if (tp == NULL)
+ return -ENOMEM;
+ /* make sure structure properly initialized */
+ memset(tp, 0, sizeof(*tp));
+ INIT_LIST_HEAD(&tp->atom.list);
+ kref_init(&tp->atom.kref);
+ tp->atom.release = &r600_tp_release;
+ tp->atom.emit = &radeon_atom_emit_default;
+ tp->atom.process = &r600_atom_process_default;
+ tp->atom.pkts = tp->pkts;
+ /* KERNEL use get user data */
+ memcpy(&ptp, (void*)(unsigned long)patom->data, sizeof(struct drm_r600_tp));
+ /* TA_CNTL_AUX */
+ tp->pkts[tp->atom.npkts++] = PKT3(PKT3_SET_CONFIG_REG, 1);
+ tp->pkts[tp->atom.npkts++] = 0x00000542;
+ tp->pkts[tp->atom.npkts++] = ptp.ta_cntl_aux;
+ *atom = &tp->atom;
+fprintf(stderr, "%s %d pkts\n", __func__, (*atom)->npkts);
+ return 0;
+out_err:
+ radeon_atom_put(&tp->atom);
+ *atom = NULL;
+ return r;
+}
+
+/*
+ * r600_pa
+ */
+struct r600_pa {
+ struct radeon_atom atom;
+ u32 pkts[128];
+ struct r600_atoms *atoms;
+};
+
+static void r600_pa_release(struct kref *kref)
+{
+ struct radeon_atom *atom = container_of(kref, struct radeon_atom, kref);
+ struct r600_pa *pa = container_of(atom, struct r600_pa, atom);
+
+ mutex_lock(&pa->atoms->mutex);
+ list_del_init(&pa->atom.list);
+ mutex_unlock(&pa->atoms->mutex);
+ kfree(pa);
+}
+
+static int r600_pa_create(struct radeon_device *rdev,
+ struct drm_radeon_atom *patom,
+ struct radeon_atom **atom)
+{
+ struct drm_r600_pa ppa;
+ struct r600_pa *pa;
+ int r;
+
+ pa = kmalloc(sizeof(*pa), GFP_KERNEL);
+ if (pa == NULL)
+ return -ENOMEM;
+ /* make sure structure properly initialized */
+ memset(pa, 0, sizeof(*pa));
+ INIT_LIST_HEAD(&pa->atom.list);
+ kref_init(&pa->atom.kref);
+ pa->atom.release = &r600_pa_release;
+ pa->atom.emit = &radeon_atom_emit_default;
+ pa->atom.process = &r600_atom_process_default;
+ pa->atom.pkts = pa->pkts;
+ /* KERNEL use get user data */
+ memcpy(&ppa, (void*)(unsigned long)patom->data, sizeof(struct drm_r600_pa));
+ /* PA_SC_MPASS_PS_CNTL */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ pa->pkts[pa->atom.npkts++] = 0x00000292;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_mpass_ps_cntl;
+ /* PA_SC_MODE_CNTL */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ pa->pkts[pa->atom.npkts++] = 0x00000293;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_mode_cntl;
+ /* PA_SC_LINE_CNTL */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ pa->pkts[pa->atom.npkts++] = 0x00000300;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_line_cntl;
+ /* PA_SC_SCREEN_SCISSOR_TL */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 2);
+ pa->pkts[pa->atom.npkts++] = 0x0000000C;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_screen_scissor_tl;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_screen_scissor_br;
+ /* PA_SC_WINDOW_OFFSET */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 12);
+ pa->pkts[pa->atom.npkts++] = 0x00000080;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_window_offset;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_window_scissor_tl;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_window_scissor_br;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_cliprect_rule;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_cliprect_0_tl;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_cliprect_0_br;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_cliprect_1_tl;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_cliprect_1_br;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_cliprect_2_tl;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_cliprect_2_br;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_cliprect_3_tl;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_cliprect_3_br;
+ /* PA_SC_GENERIC_SCISSOR_TL */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 2);
+ pa->pkts[pa->atom.npkts++] = 0x00000090;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_generic_scissor_tl;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_generic_scissor_br;
+ /* PA_SC_AA_CONFIG */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ pa->pkts[pa->atom.npkts++] = 0x00000301;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_aa_config;
+ /* PA_SC_AA_SAMPLE_LOCS_MCTX */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ pa->pkts[pa->atom.npkts++] = 0x00000307;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_aa_sample_locs_mctx;
+ /* PA_SC_AA_MASK */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ pa->pkts[pa->atom.npkts++] = 0x00000312;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_aa_mask;
+ /* PA_CL_CLIP_CNTL */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ pa->pkts[pa->atom.npkts++] = 0x00000204;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_cl_clip_cntl;
+ /* PA_CL_VTE_CNTL */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ pa->pkts[pa->atom.npkts++] = 0x00000206;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_cl_vte_cntl;
+ /* PA_CL_VS_OUT_CNTL */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ pa->pkts[pa->atom.npkts++] = 0x00000207;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_cl_vs_out_cntl;
+ /* PA_CL_NANINF_CNTL */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ pa->pkts[pa->atom.npkts++] = 0x00000208;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_cl_naninf_cntl;
+ /* PA_CL_GB_VERT_CLIP_ADJ */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 4);
+ pa->pkts[pa->atom.npkts++] = 0x00000303;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_cl_gb_vert_clip_adj;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_cl_gb_vert_disc_adj;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_cl_gb_horz_clip_adj;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_cl_gb_horz_disc_adj;
+ /* PA_SU_SC_MODE_CNTL */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1);
+ pa->pkts[pa->atom.npkts++] = 0x00000205;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_su_sc_mode_cntl;
+ /* PA_SU_POINT_SIZE */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 4);
+ pa->pkts[pa->atom.npkts++] = 0x00000280;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_su_point_size;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_su_point_minmax;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_su_line_cntl;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_sc_line_stipple;
+ /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 2);
+ pa->pkts[pa->atom.npkts++] = 0x0000037E;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_su_poly_offset_db_fmt_cntl;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_su_poly_offset_clamp;
+ /* PA_SU_POLY_OFFSET_FRONT_SCALE */
+ pa->pkts[pa->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 4);
+ pa->pkts[pa->atom.npkts++] = 0x00000380;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_su_poly_offset_front_scale;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_su_poly_offset_front_offset;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_su_poly_offset_back_scale;
+ pa->pkts[pa->atom.npkts++] = ppa.pa_su_poly_offset_back_offset;
+ *atom = &pa->atom;
+fprintf(stderr, "%s %d pkts\n", __func__, (*atom)->npkts);
+ return 0;
+out_err:
+ radeon_atom_put(&pa->atom);
+ *atom = NULL;
+ return r;
+}
+
+/*
+ * r600 atom core functions
+ */
+int r600_atom_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct drm_radeon_atom *patom)
+{
+ struct radeon_atom *atom;
+ int r;
+
+ patom->id = 0;
+ mutex_lock(&atoms->mutex);
+ switch (patom->type) {
+ case R600_ATOM_CB:
+ r = r600_cb_create(rdev, patom, &atom);
+ if (r)
+ return r;
+ atom->type = patom->type;
+ list_add_tail(&atom->list, &atoms->cb_atoms);
+ break;
+ case R600_ATOM_CB_CNTL:
+ r = r600_cb_cntl_create(rdev, patom, &atom);
+ if (r)
+ return r;
+ atom->type = patom->type;
+ list_add_tail(&atom->list, &atoms->cb_cntl_atoms);
+ break;
+ case R600_ATOM_PA:
+ r = r600_pa_create(rdev, patom, &atom);
+ if (r)
+ return r;
+ atom->type = patom->type;
+ list_add_tail(&atom->list, &atoms->pa_atoms);
+ break;
+ case R600_ATOM_TP:
+ r = r600_tp_create(rdev, patom, &atom);
+ if (r)
+ return r;
+ atom->type = patom->type;
+ list_add_tail(&atom->list, &atoms->tp_atoms);
+ break;
+ default:
+ dev_err(rdev->dev, "unknown R600 atom type 0x%08X\n", patom->type);
+ return -EINVAL;
+ }
+ r = radeon_atom_newid(rdev, &atoms->idr, atom);
+ if (r) {
+ radeon_atom_put(atom);
+ return r;
+ }
+ patom->id = atom->id;
+ mutex_unlock(&atoms->mutex);
+ return 0;
+}
+
+/*
+ * r600_batch
+ */
+static int r600_batch_alloc(struct r600_batch **batch)
+{
+ struct r600_batch *rbatch;
+
+ *batch = NULL;
+ rbatch = kmalloc(sizeof(*rbatch), GFP_KERNEL);
+ if (rbatch == NULL)
+ return -ENOMEM;
+ INIT_LIST_HEAD(&rbatch->list);
+ INIT_LIST_HEAD(&rbatch->pre_flushes);
+ INIT_LIST_HEAD(&rbatch->post_flushes);
+ rbatch->npkts = 0;
+ *batch = rbatch;
+ return 0;
+}
+
+/*
+ * r600_batches
+ */
+static void r600_batches_clear_locked(struct radeon_device *rdev, struct r600_batches *batches)
+{
+ struct r600_batch *batch, *n;
+ int i;
+
+ list_for_each_entry_safe(batch, n, &batches->batches, list) {
+ for (i = 0; i < R600_BATCH_NATOMS; i++) {
+ radeon_atom_put(batch->atoms[i]);
+ }
+ list_del(&batch->list);
+ kfree(batch);
+ }
+ INIT_LIST_HEAD(&batches->batches);
+ batches->npkts = 0;
+}
+
+static int r600_batches_flush_locked(struct radeon_device *rdev, struct r600_batches *batches)
+{
+ struct r600_batch *batch;
+ int r, i;
+
+ list_for_each_entry(batch, &batches->batches, list) {
+ for (i = 3; i < R600_BATCH_NATOMS; i++) {
+ r = batch->atoms[i]->emit(rdev, batch->atoms[i], batch, batches->ib);
+ if (r)
+ goto out_err;
+ }
+ }
+ r = radeon_ib_schedule(rdev, batches->ib);
+out_err:
+ r600_batches_clear_locked(rdev, batches);
+ /* FIXME helper function */
+ batches->ib->cpkts = 0;
+ batches->ib->nrelocs = 0;
+ return r;
+}
+
+int r600_batches_queue(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct drm_r600_batch *batch)
+{
+ struct r600_batch *rbatch;
+ struct r600_batches *batches = &atoms->batches;
+ int r, i;
+
+ r = r600_batch_alloc(&rbatch);
+ if (r)
+ return r;
+ mutex_lock(&atoms->mutex);
+ i = 0;
+ r = radeon_atom_find_locked(&atoms->cb_cntl_atoms, batch->cb_cntl_id,
+ R600_ATOM_CB_CNTL, &rbatch->atoms[i++]);
+ if (r)
+ goto out_err;
+ r = radeon_atom_find_locked(&atoms->pa_atoms, batch->pa_id,
+ R600_ATOM_PA, &rbatch->atoms[i++]);
+ if (r)
+ goto out_err;
+ r = radeon_atom_find_locked(&atoms->tp_atoms, batch->tp_id,
+ R600_ATOM_TP, &rbatch->atoms[i++]);
+ if (r)
+ goto out_err;
+ r = radeon_atom_find_locked(&atoms->cb_atoms, batch->cb_id,
+ R600_ATOM_CB, &rbatch->atoms[i++]);
+ if (r)
+ goto out_err;
+reprocess:
+ for (i = 0; i < R600_BATCH_NATOMS; i++) {
+ r = rbatch->atoms[i]->process(rdev, rbatch->atoms[i], batches->last_id[i], rbatch);
+ if (r)
+ goto out_err;
+ }
+ /* if batch is bigger than ib size it's an invalid one, this should
+ * not happen
+ */
+ if (rbatch->npkts > batches->ib->length_dw) {
+ dev_err(rdev->dev, "single batch to big (%d) to fit into ib (%d)\n",
+ rbatch->npkts, batches->ib->length_dw);
+ goto out_err;
+ }
+ /* flush or not ? */
+ if (batches->npkts + rbatch->npkts > batches->ib->length_dw) {
+ r = r600_batches_flush_locked(rdev, batches);
+ if (r)
+ goto out_err;
+ goto reprocess;
+ }
+ /* batch is queued */
+ for (i = 0; i < R600_BATCH_NATOMS; i++) {
+ batches->last_id[i] = rbatch->atoms[i]->id;
+ }
+ batches->npkts += rbatch->npkts;
+ list_add_tail(&rbatch->list, &batches->batches);
+ mutex_unlock(&atoms->mutex);
+ return 0;
+out_err:
+ for (i = 0; i < R600_BATCH_NATOMS; i++) {
+ if (rbatch->atoms[i])
+ radeon_atom_put(rbatch->atoms[i]);
+ }
+ mutex_unlock(&rdev->asic.r700.atom.mutex);
+ /* FIXME: release kref on atoms */
+ kfree(rbatch);
+ return r;
+}
+
+static int r600_batches_init(struct radeon_device *rdev, struct r600_batches *batches)
+{
+ int r;
+
+ memset(batches, 0 , sizeof(struct r600_batches));
+ INIT_LIST_HEAD(&batches->batches);
+ r = radeon_ib_get(rdev, &batches->ib);
+ return r;
+}
+
+static void r600_batches_cleanup_locked(struct radeon_device *rdev, struct r600_batches *batches)
+{
+ r600_batches_clear_locked(rdev, batches);
+ radeon_ib_free(batches->ib);
+ batches->ib = NULL;
+}
+
+int r600_batches_flush(struct radeon_device *rdev, struct r600_atoms *atoms)
+{
+ int r;
+
+ mutex_lock(&atoms->mutex);
+ r = r600_batches_flush_locked(rdev, &atoms->batches);
+ mutex_unlock(&atoms->mutex);
+ return r;
+}
+
+int r600_atoms_init(struct radeon_device *rdev, struct r600_atoms *atoms)
+{
+ mutex_init(&atoms->mutex);
+ INIT_LIST_HEAD(&atoms->cb_atoms);
+ INIT_LIST_HEAD(&atoms->pa_atoms);
+ INIT_LIST_HEAD(&atoms->sq_atoms);
+ INIT_LIST_HEAD(&atoms->tp_atoms);
+ INIT_LIST_HEAD(&atoms->vgt_atoms);
+ INIT_LIST_HEAD(&atoms->cb_cntl_atoms);
+ idr_init(&atoms->idr);
+ return r600_batches_init(rdev, &atoms->batches);
+}
+
+void r600_atoms_release(struct radeon_device *rdev, struct r600_atoms *atoms)
+{
+ mutex_lock(&atoms->mutex);
+ r600_batches_cleanup_locked(rdev, &atoms->batches);
+ idr_destroy(&atoms->idr);
+ mutex_unlock(&atoms->mutex);
+}
+
+
+
+
+
+#define WPKT(a) (atom->pkts[atom->npkts++] = (a))
+#define WPKT_RELOC(s)\
+ do {\
+ WPKT(PKT3(PKT3_NOP, 0));\
+ if (!strcmp("bo", s)) {\
+ fprintf(stderr, "cb->pkts[%d] = radeon_ib_reloc(ib, cb->"s", cb->placements[0] | cb->placements[1]);\n", atom->npkts);\
+ } else {\
+ fprintf(stderr, "cb->pkts[%d] = radeon_ib_reloc(ib, cb->"s", RADEON_GEM_DOMAIN_GTT);\n", atom->npkts);\
+ }\
+ WPKT(0x00000000);\
+ } while (0)
+void r600_tflat(struct radeon_atom *atom)
+{
+ WPKT(PKT3(PKT3_CONTEXT_CONTROL, 1));
+ WPKT(0x80000000);
+ WPKT(0x80000000);
+ WPKT(PKT3(PKT3_EVENT_WRITE, 0));
+ WPKT(0x00000016);
+ WPKT(PKT3(PKT3_SET_CONFIG_REG, 1));
+ WPKT(0x00000010);
+ WPKT(0x00028000);
+ WPKT(PKT3(PKT3_SET_CONFIG_REG, 6));
+ WPKT(0x00000300);
+ WPKT(0x0000000D);
+ WPKT(0x40240054);
+ WPKT(0x00000000);
+ WPKT(0x00003CBC);
+ WPKT(0x00800080);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONFIG_REG, 1));
+ WPKT(0x000005C5);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONFIG_REG, 1));
+ WPKT(0x00000363);
+ WPKT(0x00004000);
+ WPKT(PKT3(PKT3_SET_CONFIG_REG, 1));
+ WPKT(0x0000060C);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONFIG_REG, 1));
+ WPKT(0x0000060E);
+ WPKT(0x00420204);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 9));
+ WPKT(0x0000022A);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 2));
+ WPKT(0x0000000A);
+ WPKT(0x00000000);
+ WPKT(0x3F800000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000200);
+ WPKT(0x00700700);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000203);
+ WPKT(0x00000210);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 2));
+ WPKT(0x00000343);
+ WPKT(0x00000060);
+ WPKT(0x0000002A);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000351);
+ WPKT(0x0000AA00);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 2));
+ WPKT(0x0000010C);
+ WPKT(0xFFFFFF00);
+ WPKT(0xFFFFFF00);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x0000008C);
+ WPKT(0xAAAAAAAA);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000307);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000308);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x000001E8);
+ WPKT(0x00000003);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x000001E0);
+ WPKT(0x00010001);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 4));
+ WPKT(0x00000105);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x000000D4);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000104);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x0000010E);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 4));
+ WPKT(0x00000100);
+ WPKT(0x00FFFFFF);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 13));
+ WPKT(0x00000284);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x000002A1);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x000002A5);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x000002A8);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x000002A9);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 3));
+ WPKT(0x000002AC);
+ WPKT(0x00000000);
+ WPKT(0x00000001);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x000002C8);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 32));
+ WPKT(0x000000E0);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 10));
+ WPKT(0x00000185);
+ WPKT(0x03020100);
+ WPKT(0x07060504);
+ WPKT(0x0B0A0908);
+ WPKT(0x0F0E0D0C);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 9));
+ WPKT(0x000001B1);
+ WPKT(0x00000000);
+ WPKT(0x00000001);
+ WPKT(0x10000001);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 32));
+ WPKT(0x00000191);
+ WPKT(0x00000800);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 2));
+ WPKT(0x00000094);
+ WPKT(0x80000000);
+ WPKT(0x00FA00FA);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 2));
+ WPKT(0x000000B4);
+ WPKT(0x00000000);
+ WPKT(0x3F800000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 6));
+ WPKT(0x0000010F);
+ WPKT(0x42FA0000);
+ WPKT(0x42FA0000);
+ WPKT(0xC2FA0000);
+ WPKT(0x42FA0000);
+ WPKT(0x3F000000);
+ WPKT(0x3F000000);
+ WPKT(PKT3(PKT3_SURFACE_SYNC, 3));
+ WPKT(0x08000000);
+ WPKT(0x00000001);
+ WPKT(0x00000000);
+ WPKT(0x0000000A);
+ WPKT_RELOC("vsshader1");
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000225);
+ WPKT(0x00000000);
+ WPKT_RELOC("vsshader1");
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000229);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000237);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SURFACE_SYNC, 3));
+ WPKT(0x08000000);
+ WPKT(0x00000001);
+ WPKT(0x00000000);
+ WPKT(0x0000000A);
+ WPKT_RELOC("vsshader1");
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000216);
+ WPKT(0x00000000);
+ WPKT_RELOC("vsshader1");
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x0000021A);
+ WPKT(0x00000006);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000234);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_LOOP_CONST, 1));
+ WPKT(0x00000020);
+ WPKT(0x0100000F);
+ WPKT(PKT3(PKT3_SURFACE_SYNC, 3));
+ WPKT(0x08000000);
+ WPKT(0x00000001);
+ WPKT(0x00000000);
+ WPKT(0x0000000A);
+ WPKT_RELOC("psshader1");
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000210);
+ WPKT(0x00000000);
+ WPKT_RELOC("psshader1");
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000214);
+ WPKT(0x00000003);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000215);
+ WPKT(0x00000002);
+ WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1));
+ WPKT(0x00000233);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_LOOP_CONST, 1));
+ WPKT(0x00000000);
+ WPKT(0x01000FFF);
+ WPKT(PKT3(PKT3_SET_ALU_CONST, 16));
+ WPKT(0x00000400);
+ WPKT(0x3C03126F);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0xBF800000);
+ WPKT(0x00000000);
+ WPKT(0x3C03126F);
+ WPKT(0x00000000);
+ WPKT(0xBF800000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0xBF800000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0x3F800000);
+ WPKT(PKT3(PKT3_SET_CTL_CONST, 1));
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SET_CTL_CONST, 1));
+ WPKT(0x00000001);
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_SURFACE_SYNC, 3));
+ WPKT(0x01000000);
+ WPKT(0x00000001);
+ WPKT(0x00000000);
+ WPKT(0x0000000A);
+ WPKT_RELOC("vbo1");
+ WPKT(PKT3(PKT3_SET_RESOURCE, 7));
+ WPKT(0x00000460);
+ WPKT(0x00000000);
+ WPKT(0x0000006F);
+ WPKT(0x03001C00);
+ WPKT(0x00000001);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0xC0000000);
+ WPKT_RELOC("vbo1");
+ WPKT(PKT3(PKT3_SURFACE_SYNC, 3));
+ WPKT(0x01000000);
+ WPKT(0x00000001);
+ WPKT(0x00000000);
+ WPKT(0x0000000A);
+ WPKT_RELOC("vbo1");
+ WPKT(PKT3(PKT3_SET_RESOURCE, 7));
+ WPKT(0x00000475);
+ WPKT(0x0000000C);
+ WPKT(0x0000006F);
+ WPKT(0x02301C00);
+ WPKT(0x00000001);
+ WPKT(0x00000000);
+ WPKT(0x00000000);
+ WPKT(0xC0000000);
+ WPKT_RELOC("vbo1");
+ WPKT(PKT3(PKT3_SET_CONFIG_REG, 1));
+ WPKT(0x00000256);
+ WPKT(0x00000005);
+ WPKT(PKT3(PKT3_INDEX_TYPE, 0));
+ WPKT(0x00000000);
+ WPKT(PKT3(PKT3_NUM_INSTANCES, 0));
+ WPKT(0x00000001);
+ WPKT(PKT3(PKT3_DRAW_INDEX_AUTO, 1));
+ WPKT(0x00000004);
+ WPKT(0x00000002);
+ WPKT(PKT3(PKT3_EVENT_WRITE, 0));
+ WPKT(0x00000016);
+ WPKT(PKT3(PKT3_SET_CONFIG_REG, 1));
+ WPKT(0x00000010);
+ WPKT(0x00028000);
+ WPKT(PKT3(PKT3_SURFACE_SYNC, 3));
+ WPKT(0x02000040);
+ WPKT(0x000003F0);
+ WPKT(0x00000000);
+ WPKT(0x0000000A);
+ WPKT_RELOC("bo");
+ WPKT(PKT3(PKT3_CONTEXT_CONTROL, 1));
+ WPKT(0x80000000);
+ WPKT(0x80000000);
+ WPKT(PKT3(PKT3_EVENT_WRITE, 0));
+ WPKT(0x00000016);
+ WPKT(PKT3(PKT3_SET_CONFIG_REG, 1));
+ WPKT(0x00000010);
+ WPKT(0x00028000);
+}
+
+static u32 rvsshader1[64] = {
+ 0x0000001C, 0x81000400, 0x00000005, 0x80000000, 0x00000007,
+ 0xA04C0000, 0xC001A03C, 0x94000688, 0xC0024000, 0x94200688,
+ 0x900000F8, 0x00A80C90, 0x00000000, 0x00000000, 0x00200001,
+ 0x006C2810, 0x00A00401, 0x206C2800, 0x01200801, 0x406C2800,
+ 0x81A00C01, 0x606C2800, 0x00202001, 0x006C2800, 0x00A02401,
+ 0x206C2810, 0x01202801, 0x406C2800, 0x81A02C01, 0x606C2800,
+ 0x00204001, 0x006C2800, 0x00A04401, 0x206C2800, 0x01204801,
+ 0x406C2810, 0x81A04C01, 0x606C2800, 0x00206001, 0x006C2800,
+ 0x00A06401, 0x206C2800, 0x01206801, 0x406C2800, 0x81A06C01,
+ 0x606C2810, 0x00000002, 0x00940C90, 0x00000402, 0x20940C90,
+ 0x00000802, 0x40940C90, 0x80000C02, 0x60940C90, 0x00000000,
+ 0x00000000, 0x7C000000, 0x1C351001, 0x00080000, 0x0BEADEAF,
+ 0x7C000300, 0x18ED1002, 0x00080000, 0x0BEADEAF,
+};
+
+static u32 rpsshader1[20] = {
+ 0x00000003, 0x80000000, 0x00000005, 0xA00C0000,
+ 0xC0008000, 0x94200688, 0x900000F8, 0x00480C90,
+ 0x00000000, 0x00000000, 0x00000000, 0x00340C90,
+ 0x00000400, 0x20340C90, 0x00000800, 0x40340C90,
+ 0x80000C00, 0x60340C90, 0x00000000, 0x00000000,
+};
+
+static u32 rvsshader2[64] = {
+ 0x0000001C, 0x81000400, 0x00000005, 0x80000000, 0x00000007,
+ 0xA04C0000, 0xC001A03C, 0x94000688, 0xC0024000, 0x94200688,
+ 0x900000F8, 0x00A80C90, 0x00000000, 0x00000000, 0x00200001,
+ 0x006C2810, 0x00A00401, 0x206C2800, 0x01200801, 0x406C2800,
+ 0x81A00C01, 0x606C2800, 0x00202001, 0x006C2800, 0x00A02401,
+ 0x206C2810, 0x01202801, 0x406C2800, 0x81A02C01, 0x606C2800,
+ 0x00204001, 0x006C2800, 0x00A04401, 0x206C2800, 0x01204801,
+ 0x406C2810, 0x81A04C01, 0x606C2800, 0x00206001, 0x006C2800,
+ 0x00A06401, 0x206C2800, 0x01206801, 0x406C2800, 0x81A06C01,
+ 0x606C2810, 0x00000002, 0x00940C90, 0x00000402, 0x20940C90,
+ 0x00000802, 0x40940C90, 0x80000C02, 0x60940C90, 0x00000000,
+ 0x00000000, 0x7C000000, 0x1C351001, 0x00080000, 0x0BEADEAF,
+ 0x7C000300, 0x1C351002, 0x00080000, 0x0BEADEAF,
+};
+
+static float rvbo1[32] = {
+ 0.000000, 0.000000, -1.000000, 0.500000,
+ 0.500000, 0.500000, 0.000000, 250.000000,
+ 0.000000, -1.000000, 0.500000, 0.500000,
+ 0.500000, 0.000000, 250.000000, 250.000000,
+ -1.000000, 0.500000, 0.500000, 0.500000,
+ 0.000000, 0.000000, 250.000000, -1.000000,
+ 0.500000, 0.500000, 0.500000, 0.000000,
+ 0.000000, 0.000000, 0.000000, 0.000000,
+};
+
+static float rvbo2[25] = {
+ 0.900000, -0.900000, -30.000000,
+ 0.900000, 0.900000, -30.000000,
+ -0.900000, 0.000000, -30.000000,
+ 0.000000, 0.000000, 0.000000,
+ 0.000000, 0.000000, 0.000000, 0.000000,
+ 0.000000, 0.000000, 1.000000,
+ 1.000000, 0.000000, 0.000000,
+ 0.000000, 1.000000, 0.000000,
+};
+
+int r600_tflat_init(struct radeon *radeon, struct r600_cb *cb)
+{
+ int r = 0;
+
+ cb->vsshader1 = radeon_bo_open(radeon->bom, 0, 4096, 0,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ if (cb->vsshader1 == NULL) {
+ fprintf(stderr, "Failed to create vsshader1 bo\n");
+ r = -ENOMEM;
+ goto out_err;
+ }
+ cb->vsshader2 = radeon_bo_open(radeon->bom, 0, 4096, 0,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ if (cb->vsshader2 == NULL) {
+ fprintf(stderr, "Failed to create vsshader2 bo\n");
+ r = -ENOMEM;
+ goto out_err;
+ }
+ cb->psshader1 = radeon_bo_open(radeon->bom, 0, 4096, 0,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ if (cb->psshader1 == NULL) {
+ fprintf(stderr, "Failed to create psshader1 bo\n");
+ r = -ENOMEM;
+ goto out_err;
+ }
+ cb->vbo1 = radeon_bo_open(radeon->bom, 0, 4096, 0,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ if (cb->vbo1 == NULL) {
+ fprintf(stderr, "Failed to create vbo1 bo\n");
+ r = -ENOMEM;
+ goto out_err;
+ }
+ cb->vbo2 = radeon_bo_open(radeon->bom, 0, 4096, 0,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ if (cb->vbo2 == NULL) {
+ fprintf(stderr, "Failed to create vbo2 bo\n");
+ r = -ENOMEM;
+ goto out_err;
+ }
+ memset_bo(cb->vsshader1, 0);
+ memset_bo(cb->vsshader2, 0);
+ memset_bo(cb->psshader1, 0);
+ memset_bo(cb->vbo1, 0);
+ memset_bo(cb->vbo2, 0);
+ memcpy_bo(cb->vsshader1, rvsshader1, 64);
+ memcpy_bo(cb->vsshader2, rvsshader2, 64);
+ memcpy_bo(cb->psshader1, rpsshader1, 20);
+ memcpy_bo(cb->vbo1, (u32*)rvbo1, 32);
+ memcpy_bo(cb->vbo2, (u32*)rvbo2, 25);
+ return 0;
+out_err:
+ if (cb->vsshader1)
+ radeon_bo_unref(cb->vsshader1);
+ if (cb->vsshader2)
+ radeon_bo_unref(cb->vsshader2);
+ if (cb->psshader1)
+ radeon_bo_unref(cb->psshader1);
+ if (cb->vbo1)
+ radeon_bo_unref(cb->vbo1);
+ if (cb->vbo2)
+ radeon_bo_unref(cb->vbo2);
+ return r;
+}
diff --git a/r600_atom_api.h b/r600_atom_api.h
new file mode 100644
index 0000000..5a309f8
--- /dev/null
+++ b/r600_atom_api.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef R600_ATOM_API_H
+#define R600_ATOM_API_H
+
+struct radeon_device;
+
+/* public API */
+struct drm_radeon_atom {
+ u32 type;
+ u32 id;
+ u64 data;
+};
+
+/* R700 public API */
+#define R600_ATOM_CB 1
+#define R600_ATOM_TP 2
+#define R600_ATOM_PA 3
+#define R600_ATOM_CB_CNTL 4
+
+struct drm_r600_cb {
+ u32 pitch;
+ u32 height;
+ u32 color_info;
+ u32 nsamples;
+ u32 placements[2];
+ struct radeon_bo *bo;
+};
+
+struct drm_r600_cb_cntl {
+ u32 cb_target_mask;
+ u32 cb_shader_mask;
+ u32 cb_clrcmp_control;
+ u32 cb_clrcmp_src;
+ u32 cb_clrcmp_dst;
+ u32 cb_clrcmp_msk;
+ u32 cb_color_control;
+};
+
+/* tp - texture pipe */
+struct drm_r600_tp {
+ u32 ta_cntl_aux;
+};
+
+/* pa - primitive assembly */
+struct drm_r600_pa {
+ u32 pa_sc_mpass_ps_cntl;
+ u32 pa_sc_mode_cntl;
+ u32 pa_sc_line_cntl;
+ u32 pa_sc_screen_scissor_tl;
+ u32 pa_sc_screen_scissor_br;
+ u32 pa_sc_window_offset;
+ u32 pa_sc_window_scissor_tl;
+ u32 pa_sc_window_scissor_br;
+ u32 pa_sc_cliprect_rule;
+ u32 pa_sc_cliprect_0_tl;
+ u32 pa_sc_cliprect_0_br;
+ u32 pa_sc_cliprect_1_tl;
+ u32 pa_sc_cliprect_1_br;
+ u32 pa_sc_cliprect_2_tl;
+ u32 pa_sc_cliprect_2_br;
+ u32 pa_sc_cliprect_3_tl;
+ u32 pa_sc_cliprect_3_br;
+ u32 pa_sc_generic_scissor_tl;
+ u32 pa_sc_generic_scissor_br;
+ u32 pa_sc_aa_config;
+ u32 pa_sc_aa_sample_locs_mctx;
+ u32 pa_sc_aa_mask;
+ u32 pa_cl_clip_cntl;
+ u32 pa_cl_vte_cntl;
+ u32 pa_cl_vs_out_cntl;
+ u32 pa_cl_naninf_cntl;
+ u32 pa_cl_gb_vert_clip_adj;
+ u32 pa_cl_gb_vert_disc_adj;
+ u32 pa_cl_gb_horz_clip_adj;
+ u32 pa_cl_gb_horz_disc_adj;
+ u32 pa_su_sc_mode_cntl;
+ u32 pa_su_point_size;
+ u32 pa_su_point_minmax;
+ u32 pa_su_line_cntl;
+ u32 pa_sc_line_stipple;
+ u32 pa_su_poly_offset_db_fmt_cntl;
+ u32 pa_su_poly_offset_clamp;
+ u32 pa_su_poly_offset_front_scale;
+ u32 pa_su_poly_offset_front_offset;
+ u32 pa_su_poly_offset_back_scale;
+ u32 pa_su_poly_offset_back_offset;
+};
+
+struct drm_r600_batch {
+ u32 cb_id;
+ u32 cb_cntl_id;
+ u32 pa_id;
+ u32 tp_id;
+};
+
+
+#endif
diff --git a/r600_winsys.h b/r600_winsys.h
new file mode 100644
index 0000000..708b46f
--- /dev/null
+++ b/r600_winsys.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef R600_WINSYS_H
+#define R600_WINSYS_H
+
+#include "r600_atom_api.h"
+
+/* opaque structure */
+struct radeon_device *rdev;
+
+/* atom */
+extern int radeon_atom_create(struct radeon_device*, struct drm_radeon_atom*);
+extern int radeon_batches_queue(struct radeon_device *rdev, void *batch);
+extern int radeon_batches_flush(struct radeon_device *rdev);
+
+/* core functions */
+extern int radeon_device_init(struct radeon_device **rdev, struct radeon *radeon);
+extern void radeon_device_release(struct radeon_device *rdev);
+
+#endif
diff --git a/r600d.h b/r600d.h
new file mode 100644
index 0000000..cbae883
--- /dev/null
+++ b/r600d.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef R600D_H
+#define R600D_H
+
+#define PKT3_NOP 0x10
+#define PKT3_INDIRECT_BUFFER_END 0x17
+#define PKT3_SET_PREDICATION 0x20
+#define PKT3_REG_RMW 0x21
+#define PKT3_COND_EXEC 0x22
+#define PKT3_PRED_EXEC 0x23
+#define PKT3_START_3D_CMDBUF 0x24
+#define PKT3_DRAW_INDEX_2 0x27
+#define PKT3_CONTEXT_CONTROL 0x28
+#define PKT3_DRAW_INDEX_IMMD_BE 0x29
+#define PKT3_INDEX_TYPE 0x2A
+#define PKT3_DRAW_INDEX 0x2B
+#define PKT3_DRAW_INDEX_AUTO 0x2D
+#define PKT3_DRAW_INDEX_IMMD 0x2E
+#define PKT3_NUM_INSTANCES 0x2F
+#define PKT3_STRMOUT_BUFFER_UPDATE 0x34
+#define PKT3_INDIRECT_BUFFER_MP 0x38
+#define PKT3_MEM_SEMAPHORE 0x39
+#define PKT3_MPEG_INDEX 0x3A
+#define PKT3_WAIT_REG_MEM 0x3C
+#define PKT3_MEM_WRITE 0x3D
+#define PKT3_INDIRECT_BUFFER 0x32
+#define PKT3_CP_INTERRUPT 0x40
+#define PKT3_SURFACE_SYNC 0x43
+#define PKT3_ME_INITIALIZE 0x44
+#define PKT3_COND_WRITE 0x45
+#define PKT3_EVENT_WRITE 0x46
+#define PKT3_EVENT_WRITE_EOP 0x47
+#define PKT3_ONE_REG_WRITE 0x57
+#define PKT3_SET_CONFIG_REG 0x68
+#define PKT3_SET_CONTEXT_REG 0x69
+#define PKT3_SET_ALU_CONST 0x6A
+#define PKT3_SET_BOOL_CONST 0x6B
+#define PKT3_SET_LOOP_CONST 0x6C
+#define PKT3_SET_RESOURCE 0x6D
+#define PKT3_SET_SAMPLER 0x6E
+#define PKT3_SET_CTL_CONST 0x6F
+#define PKT3_SURFACE_BASE_UPDATE 0x73
+
+#define PKT_TYPE_S(x) (((x) & 0x3) << 30)
+#define PKT_TYPE_G(x) (((x) >> 30) & 0x3)
+#define PKT_TYPE_C 0x3FFFFFFF
+#define PKT_COUNT_S(x) (((x) & 0x3FFF) << 16)
+#define PKT_COUNT_G(x) (((x) >> 16) & 0x3FFF)
+#define PKT_COUNT_C 0xC000FFFF
+#define PKT0_BASE_INDEX_S(x) (((x) & 0xFFFF) << 0)
+#define PKT0_BASE_INDEX_G(x) (((x) >> 0) & 0xFFFF)
+#define PKT0_BASE_INDEX_C 0xFFFF0000
+#define PKT3_IT_OPCODE_S(x) (((x) & 0xFF) << 8)
+#define PKT3_IT_OPCODE_G(x) (((x) >> 8) & 0xFF)
+#define PKT3_IT_OPCODE_C 0xFFFF00FF
+#define PKT0(index, count) (PKT_TYPE_S(0) | PKT0_BASE_INDEX_S(index) | PKT_COUNT_S(count))
+#define PKT3(op, count) (PKT_TYPE_S(3) | PKT3_IT_OPCODE_S(op) | PKT_COUNT_S(count))
+
+/* Registers */
+#define R_0280A0_CB_COLOR0_INFO 0x0280A0
+#define S_0280A0_ENDIAN(x) (((x) & 0x3) << 0)
+#define G_0280A0_ENDIAN(x) (((x) >> 0) & 0x3)
+#define C_0280A0_ENDIAN 0xFFFFFFFC
+#define S_0280A0_FORMAT(x) (((x) & 0x3F) << 2)
+#define G_0280A0_FORMAT(x) (((x) >> 2) & 0x3F)
+#define C_0280A0_FORMAT 0xFFFFFF03
+#define V_0280A0_COLOR_INVALID 0x00000000
+#define V_0280A0_COLOR_8 0x00000001
+#define V_0280A0_COLOR_4_4 0x00000002
+#define V_0280A0_COLOR_3_3_2 0x00000003
+#define V_0280A0_COLOR_16 0x00000005
+#define V_0280A0_COLOR_16_FLOAT 0x00000006
+#define V_0280A0_COLOR_8_8 0x00000007
+#define V_0280A0_COLOR_5_6_5 0x00000008
+#define V_0280A0_COLOR_6_5_5 0x00000009
+#define V_0280A0_COLOR_1_5_5_5 0x0000000A
+#define V_0280A0_COLOR_4_4_4_4 0x0000000B
+#define V_0280A0_COLOR_5_5_5_1 0x0000000C
+#define V_0280A0_COLOR_32 0x0000000D
+#define V_0280A0_COLOR_32_FLOAT 0x0000000E
+#define V_0280A0_COLOR_16_16 0x0000000F
+#define V_0280A0_COLOR_16_16_FLOAT 0x00000010
+#define V_0280A0_COLOR_8_24 0x00000011
+#define V_0280A0_COLOR_8_24_FLOAT 0x00000012
+#define V_0280A0_COLOR_24_8 0x00000013
+#define V_0280A0_COLOR_24_8_FLOAT 0x00000014
+#define V_0280A0_COLOR_10_11_11 0x00000015
+#define V_0280A0_COLOR_10_11_11_FLOAT 0x00000016
+#define V_0280A0_COLOR_11_11_10 0x00000017
+#define V_0280A0_COLOR_11_11_10_FLOAT 0x00000018
+#define V_0280A0_COLOR_2_10_10_10 0x00000019
+#define V_0280A0_COLOR_8_8_8_8 0x0000001A
+#define V_0280A0_COLOR_10_10_10_2 0x0000001B
+#define V_0280A0_COLOR_X24_8_32_FLOAT 0x0000001C
+#define V_0280A0_COLOR_32_32 0x0000001D
+#define V_0280A0_COLOR_32_32_FLOAT 0x0000001E
+#define V_0280A0_COLOR_16_16_16_16 0x0000001F
+#define V_0280A0_COLOR_16_16_16_16_FLOAT 0x00000020
+#define V_0280A0_COLOR_32_32_32_32 0x00000022
+#define V_0280A0_COLOR_32_32_32_32_FLOAT 0x00000023
+#define S_0280A0_ARRAY_MODE(x) (((x) & 0xF) << 8)
+#define G_0280A0_ARRAY_MODE(x) (((x) >> 8) & 0xF)
+#define C_0280A0_ARRAY_MODE 0xFFFFF0FF
+#define V_0280A0_ARRAY_LINEAR_GENERAL 0x00000000
+#define V_0280A0_ARRAY_LINEAR_ALIGNED 0x00000001
+#define V_0280A0_ARRAY_1D_TILED_THIN1 0x00000002
+#define V_0280A0_ARRAY_2D_TILED_THIN1 0x00000004
+#define S_0280A0_NUMBER_TYPE(x) (((x) & 0x7) << 12)
+#define G_0280A0_NUMBER_TYPE(x) (((x) >> 12) & 0x7)
+#define C_0280A0_NUMBER_TYPE 0xFFFF8FFF
+#define S_0280A0_READ_SIZE(x) (((x) & 0x1) << 15)
+#define G_0280A0_READ_SIZE(x) (((x) >> 15) & 0x1)
+#define C_0280A0_READ_SIZE 0xFFFF7FFF
+#define S_0280A0_COMP_SWAP(x) (((x) & 0x3) << 16)
+#define G_0280A0_COMP_SWAP(x) (((x) >> 16) & 0x3)
+#define C_0280A0_COMP_SWAP 0xFFFCFFFF
+#define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18)
+#define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3)
+#define C_0280A0_TILE_MODE 0xFFF3FFFF
+#define S_0280A0_BLEND_CLAMP(x) (((x) & 0x1) << 20)
+#define G_0280A0_BLEND_CLAMP(x) (((x) >> 20) & 0x1)
+#define C_0280A0_BLEND_CLAMP 0xFFEFFFFF
+#define S_0280A0_CLEAR_COLOR(x) (((x) & 0x1) << 21)
+#define G_0280A0_CLEAR_COLOR(x) (((x) >> 21) & 0x1)
+#define C_0280A0_CLEAR_COLOR 0xFFDFFFFF
+#define S_0280A0_BLEND_BYPASS(x) (((x) & 0x1) << 22)
+#define G_0280A0_BLEND_BYPASS(x) (((x) >> 22) & 0x1)
+#define C_0280A0_BLEND_BYPASS 0xFFBFFFFF
+#define S_0280A0_BLEND_FLOAT32(x) (((x) & 0x1) << 23)
+#define G_0280A0_BLEND_FLOAT32(x) (((x) >> 23) & 0x1)
+#define C_0280A0_BLEND_FLOAT32 0xFF7FFFFF
+#define S_0280A0_SIMPLE_FLOAT(x) (((x) & 0x1) << 24)
+#define G_0280A0_SIMPLE_FLOAT(x) (((x) >> 24) & 0x1)
+#define C_0280A0_SIMPLE_FLOAT 0xFEFFFFFF
+#define S_0280A0_ROUND_MODE(x) (((x) & 0x1) << 25)
+#define G_0280A0_ROUND_MODE(x) (((x) >> 25) & 0x1)
+#define C_0280A0_ROUND_MODE 0xFDFFFFFF
+#define S_0280A0_TILE_COMPACT(x) (((x) & 0x1) << 26)
+#define G_0280A0_TILE_COMPACT(x) (((x) >> 26) & 0x1)
+#define C_0280A0_TILE_COMPACT 0xFBFFFFFF
+#define S_0280A0_SOURCE_FORMAT(x) (((x) & 0x1) << 27)
+#define G_0280A0_SOURCE_FORMAT(x) (((x) >> 27) & 0x1)
+#define C_0280A0_SOURCE_FORMAT 0xF7FFFFFF
+#define R_028060_CB_COLOR0_SIZE 0x028060
+#define S_028060_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028060_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028060_PITCH_TILE_MAX 0xFFFFFC00
+#define S_028060_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10)
+#define G_028060_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF)
+#define C_028060_SLICE_TILE_MAX 0xC00003FF
+
+#endif
diff --git a/r700_atom.c b/r700_atom.c
new file mode 100644
index 0000000..dde5f93
--- /dev/null
+++ b/r700_atom.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "radeon_device.h"
+
+/* TODO
+ * convert to radeon_atom_init
+ *RENDERING SHOULD WORK & num of bo in gem info should show that we did cleanup
+ * add more state ...
+ */
diff --git a/radeon.c b/radeon.c
new file mode 100644
index 0000000..5d6c90e
--- /dev/null
+++ b/radeon.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2009 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include "xf86drm.h"
+#include "radeon_bo_gem.h"
+#include "radeon_cs_gem.h"
+#include "radeon.h"
+
+int radeon_init(struct radeon *radeon)
+{
+ int r;
+
+ memset(radeon, 0, sizeof(*radeon));
+ radeon->fd = drmOpen("radeon", NULL);
+ if (radeon->fd < 0) {
+ fprintf(stderr, "Failed to open the card fd (%d)\n", radeon->fd);
+ return radeon->fd;
+ }
+ radeon->csm = radeon_cs_manager_gem_ctor(radeon->fd);
+ if (radeon->csm == NULL) {
+ fprintf(stderr, "Failed to create CS manager\n");
+ return -1;
+ }
+ radeon->bom = radeon_bo_manager_gem_ctor(radeon->fd);
+ if (radeon->bom == NULL) {
+ fprintf(stderr, "Failed to create BO manager\n");
+ return -1;
+ }
+ r = radeon_mode_configure(radeon);
+ if (r) {
+ return r;
+ }
+ return 0;
+}
+
+void radeon_fini(struct radeon *radeon)
+{
+ radeon_mode_cleanup(radeon);
+ radeon_bo_manager_gem_dtor(radeon->bom);
+ radeon_cs_manager_gem_dtor(radeon->csm);
+ drmClose(radeon->fd);
+}
+
+void memset_bo(struct radeon_bo *bo, u32 value)
+{
+ u32 *ptr;
+ int r;
+
+ r = radeon_bo_map(bo, 1);
+ if (r) {
+ fprintf(stderr, "Failed to map buffer\n");
+ perror(NULL);
+ return;
+ }
+ ptr = (u32*)bo->ptr;
+ for (r = 0; r < (bo->size / 4); r++)
+ ptr[r] = value;
+ radeon_bo_unmap(bo);
+}
+
+void memcpy_bo(struct radeon_bo *bo, u32 *src, u32 size)
+{
+ u32 *ptr;
+ int r;
+
+ r = radeon_bo_map(bo, 1);
+ if (r) {
+ fprintf(stderr, "Failed to map buffer\n");
+ perror(NULL);
+ return;
+ }
+ ptr = (u32*)bo->ptr;
+ for (r = 0; r < size; r++)
+ ptr[r] = src[r];
+ radeon_bo_unmap(bo);
+}
+
+int memcmp_bo(struct radeon_bo *s1, struct radeon_bo *s2, u32 size)
+{
+ u32 *s1ptr;
+ u32 *s2ptr;
+ int r;
+
+ r = radeon_bo_map(s1, 1);
+ if (r) {
+ fprintf(stderr, "Failed to map buffer\n");
+ perror(NULL);
+ return -1;
+ }
+ r = radeon_bo_map(s2, 1);
+ if (r) {
+ fprintf(stderr, "Failed to map buffer\n");
+ perror(NULL);
+ return -1;
+ }
+ s1ptr = (u32*)s1->ptr;
+ s2ptr = (u32*)s2->ptr;
+ for (r = 0; r < (size / 4); r++)
+ if (s1ptr[r] != s2ptr[r])
+ return -1;
+ radeon_bo_unmap(s2);
+ radeon_bo_unmap(s1);
+ return 0;
+}
+
+void memsetrandom_bo(struct radeon_bo *bo)
+{
+ u32 *ptr;
+ int r;
+ double tmp;
+
+ r = radeon_bo_map(bo, 1);
+ if (r) {
+ fprintf(stderr, "Failed to map buffer\n");
+ perror(NULL);
+ return;
+ }
+ ptr = (u32*)bo->ptr;
+ for (r = 0; r < (bo->size / 4); r++) {
+ tmp = ((double)rand()) / ((double)RAND_MAX);
+ ptr[r] = (u32)(tmp * 0xFFFFFF);
+ }
+ radeon_bo_unmap(bo);
+}
diff --git a/radeon.h b/radeon.h
new file mode 100644
index 0000000..942a625
--- /dev/null
+++ b/radeon.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2009 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef RADEON_H
+#define RADEON_H
+
+#include <stdint.h>
+#include "xf86drm.h"
+#include "xf86drmMode.h"
+#include "radeon_bo.h"
+#include "radeon_cs.h"
+#include "lwrapper.h"
+#include <errno.h>
+
+struct radeon_mode {
+ drmModeModeInfo info;
+ u32 pitch;
+ u32 height;
+ u32 bpp;
+ u32 size;
+ u32 encoder_id;
+ u32 connector_id;
+ u32 crtc_id;
+ u32 fb_id;
+ struct radeon_bo *bo;
+};
+
+struct radeon {
+ struct radeon_mode mode;
+ struct radeon_bo_manager *bom;
+ struct radeon_cs_manager *csm;
+ int fd;
+};
+
+extern int radeon_init(struct radeon *radeon);
+extern void radeon_fini(struct radeon *radeon);
+extern int radeon_mode_configure(struct radeon *radeon);
+extern void radeon_mode_cleanup(struct radeon *radeon);
+extern void memset_bo(struct radeon_bo *bo, u32 value);
+extern int memcmp_bo(struct radeon_bo *s1, struct radeon_bo *s2, u32 size);
+extern void memsetrandom_bo(struct radeon_bo *bo);
+extern void memcpy_bo(struct radeon_bo *bo, u32 *src, u32 size);
+
+#endif
diff --git a/radeon_atom.c b/radeon_atom.c
new file mode 100644
index 0000000..57b6d15
--- /dev/null
+++ b/radeon_atom.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "radeon_device.h"
+
+int radeon_atom_newid(struct radeon_device *rdev, struct idr *idp, struct radeon_atom *atom)
+{
+ int r;
+
+ r = idr_pre_get(idp, GFP_KERNEL);
+ if (r)
+ return r;
+ return idr_get_new(idp, atom, &atom->id);
+}
+
+int radeon_atom_find_locked(struct list_head *atoms, u32 id,
+ u32 type, struct radeon_atom **atom)
+{
+ struct radeon_atom *i;
+
+ *atom = NULL;
+ list_for_each_entry(i, atoms, list) {
+ if (i->id == id)
+ break;
+ }
+ if (i == (struct radeon_atom*)atoms)
+ return -EINVAL;
+ if (i->type != type) {
+ dev_err(rdev->dev, "atom(0x%08X, 0x%08X) not of type 0x%08X\n",
+ i->id, i->type, type);
+ return -EINVAL;
+ }
+ *atom = i;
+ kref_get(&i->kref);
+ return 0;
+}
+
+int radeon_atom_flush_add(struct list_head *flushes, struct radeon_bo *bo, u32 flags)
+{
+ struct radeon_atom_flush *i;
+
+ list_for_each_entry(i, flushes, list) {
+ if (i->bo->handle == bo->handle) {
+ i->flags |= flags;
+ return 0;
+ }
+ }
+ i = kmalloc(sizeof(*i), GFP_KERNEL);
+ if (i == NULL)
+ return -ENOMEM;
+ i->bo = bo;
+ i->flags = flags;
+ list_add_tail(&i->list, flushes);
+ return 1;
+}
+
+int radeon_atom_emit_default(struct radeon_device *rdev,
+ struct radeon_atom *atom,
+ void *data,
+ struct radeon_ib *ib)
+{
+ return radeon_ib_copy(ib, atom->pkts, atom->npkts);
+}
+
+int radeon_atom_create(struct radeon_device *rdev, struct drm_radeon_atom *patom)
+{
+ struct r600_atoms *atoms = &rdev->asic.r700.atoms;
+
+ return r600_atom_create(rdev, atoms, patom);
+}
+
+int radeon_batches_queue(struct radeon_device *rdev, void *batch)
+{
+ return r600_batches_queue(rdev, &rdev->asic.r700.atoms, batch);
+}
+
+int radeon_batches_flush(struct radeon_device *rdev)
+{
+ return r600_batches_flush(rdev, &rdev->asic.r700.atoms);
+}
diff --git a/radeon_atom.h b/radeon_atom.h
new file mode 100644
index 0000000..27b2f5e
--- /dev/null
+++ b/radeon_atom.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef RADEON_ATOM_H
+#define RADEON_ATOM_H
+
+#include "r600_winsys.h"
+
+struct radeon_device;
+struct radeon_ib;
+struct radeon_atom;
+
+struct radeon_atom_flush {
+ struct list_head list;
+ u32 flags;
+ struct radeon_bo *bo;
+};
+
+typedef int (*radeon_atom_emit_t)(struct radeon_device*,
+ struct radeon_atom*,
+ void *data,
+ struct radeon_ib*);
+typedef int (*radeon_atom_process_t)(struct radeon_device*,
+ struct radeon_atom*,
+ u32 last_id,
+ void*);
+typedef void (*radeon_atom_release_t)(struct kref *kref);
+
+struct radeon_atom {
+ struct list_head list;
+ struct kref kref;
+ u32 type;
+ u32 id;
+ u32 nflushes;
+ u32 npkts;
+ u32 *pkts;
+ radeon_atom_emit_t emit;
+ radeon_atom_process_t process;
+ radeon_atom_release_t release;
+};
+
+/* R600 */
+#define R600_BATCH_NATOMS 4
+struct r600_batch {
+ struct list_head list;
+ struct list_head pre_flushes;
+ struct list_head post_flushes;
+ struct radeon_atom *atoms[R600_BATCH_NATOMS];
+ u32 npkts;
+};
+
+struct r600_batches {
+ struct radeon_ib *ib;
+ u32 npkts;
+ struct list_head batches;
+ u32 last_id[R600_BATCH_NATOMS];
+};
+
+struct r600_atoms {
+ struct list_head cb_atoms;
+ struct list_head pa_atoms;
+ struct list_head sq_atoms;
+ struct list_head tp_atoms;
+ struct list_head vgt_atoms;
+ struct list_head cb_cntl_atoms;
+ struct idr idr;
+ struct mutex mutex;
+ struct r600_batches batches;
+};
+
+extern int radeon_atom_flush_add(struct list_head *flushes, struct radeon_bo *bo, u32 flags);
+extern int radeon_atom_find_locked(struct list_head *atoms, u32 id,
+ u32 type, struct radeon_atom **atom);
+extern int radeon_atom_newid(struct radeon_device *rdev,
+ struct idr *idp,
+ struct radeon_atom *atom);
+extern int radeon_atom_emit_default(struct radeon_device *rdev,
+ struct radeon_atom *atom,
+ void *data,
+ struct radeon_ib *ib);
+static inline void radeon_atom_put(struct radeon_atom *atom)
+{
+ kref_put(&atom->kref, atom->release);
+}
+
+/* R600 */
+extern int r600_atoms_init(struct radeon_device *rdev, struct r600_atoms *atoms);
+extern void r600_atoms_release(struct radeon_device *rdev, struct r600_atoms *atoms);
+extern int r600_atom_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct drm_radeon_atom *patom);
+extern int r600_batches_queue(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct drm_r600_batch *batch);
+extern int r600_batches_flush(struct radeon_device *rdev, struct r600_atoms *atoms);
+/* R700 */
+
+#endif
diff --git a/radeon_device.c b/radeon_device.c
new file mode 100644
index 0000000..1568f74
--- /dev/null
+++ b/radeon_device.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "radeon_device.h"
+
+#pragma pack(1)
+struct ib_reloc_gem {
+ uint32_t handle;
+ uint32_t read_domain;
+ uint32_t write_domain;
+ uint32_t flags;
+};
+#pragma pack()
+#define RELOC_SIZE (sizeof(struct ib_reloc_gem) / sizeof(uint32_t))
+
+u32 radeon_ib_reloc(struct radeon_ib *ib, struct radeon_bo *bo, u32 d)
+{
+ struct ib_reloc_gem *reloc;
+ int i;
+
+ for (i = 0; i < ib->crelocs; i++) {
+ reloc = (struct ib_reloc_gem*)&ib->relocs[i * RELOC_SIZE];
+ if (reloc->handle == bo->handle) {
+ reloc->read_domain |= d;
+ return (i * RELOC_SIZE);
+ }
+ }
+ if (ib->crelocs >= ib->nrelocs)
+ return 0xFFFFFFFFUL;
+ i = ib->crelocs++;
+ reloc = (struct ib_reloc_gem*)&ib->relocs[i * RELOC_SIZE];
+ reloc->handle = bo->handle;
+ reloc->read_domain = d;
+ reloc->write_domain = 0;
+ reloc->flags = 0;
+ return (i * RELOC_SIZE);
+}
+
+int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
+{
+ struct radeon_ib *lib;
+
+ lib = malloc(sizeof(*lib));
+ if (lib == NULL)
+ return -ENOMEM;
+ memset(lib, sizeof(*lib), 0);
+ lib->pkts = malloc(64 * 1024);
+ if (lib->pkts == NULL) {
+ free(lib);
+ return -ENOMEM;
+ }
+ lib->cpkts = 0;
+ lib->length_dw = 64 * 1024 / 4;
+ lib->relocs = malloc(64 * 1024);
+ if (lib->relocs == NULL) {
+ free(lib->pkts);
+ free(lib);
+ return -ENOMEM;
+ }
+ lib->nrelocs = 64 * 1024 / RELOC_SIZE;
+ lib->crelocs = 0;
+ *ib = lib;
+ return 0;
+}
+
+void radeon_ib_free(struct radeon_ib *ib)
+{
+ if (ib == NULL)
+ return;
+ free(ib->pkts);
+ free(ib->relocs);
+ free(ib);
+}
+
+int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
+{
+ struct drm_radeon_cs drmib;
+ struct drm_radeon_cs_chunk chunks[2];
+ uint64_t chunk_array[2];
+ int r;
+
+ drmib.num_chunks = 2;
+ drmib.chunks = (uint64_t)(uintptr_t)chunk_array;
+ chunks[0].chunk_id = RADEON_CHUNK_ID_IB;
+ chunks[0].length_dw = ib->cpkts;
+ chunks[0].chunk_data = (uint64_t)(uintptr_t)ib->pkts;
+ chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
+ chunks[1].length_dw = ib->crelocs * 4;
+ chunks[1].chunk_data = (uint64_t)(uintptr_t)ib->relocs;
+ chunk_array[0] = (uint64_t)(uintptr_t)&chunks[0];
+ chunk_array[1] = (uint64_t)(uintptr_t)&chunks[1];
+ r = drmCommandWriteRead(rdev->fd, DRM_RADEON_CS, &drmib,
+ sizeof(struct drm_radeon_cs));
+ return r;
+}
+
+int idr_pre_get(struct idr *idp, int gfp_mask)
+{
+ return 0;
+}
+
+int idr_get_new(struct idr *idp, void *ptr, int *id)
+{
+ *id = ++idp->cid;
+ return 0;
+}
+
+void idr_destroy(struct idr *idp)
+{
+}
+
+void idr_init(struct idr *idp)
+{
+ idp->cid = 0;
+}
+
+int radeon_device_init(struct radeon_device **rdev, struct radeon *radeon)
+{
+ struct radeon_device *dev;
+ int r;
+
+ *rdev = NULL;
+ dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev == NULL)
+ return -ENOMEM;
+ memset(dev, 0, sizeof(struct radeon_device));
+ dev->radeon = radeon;
+ dev->fd = radeon->fd;
+ dev->asic.r700.npipes = 2;
+ dev->asic.r700.nbanks = 4;
+ dev->asic.r700.group_bytes = 256;
+ r = r600_atoms_init(dev, &dev->asic.r700.atoms);
+ if (r)
+ return r;
+ *rdev = dev;
+ return r;
+}
+
+void radeon_device_release(struct radeon_device *rdev)
+{
+ r600_atoms_release(rdev, &rdev->asic.r700.atoms);
+ memset(rdev, 0, sizeof(struct radeon_device));
+ kfree(rdev);
+}
+
+void kref_set(struct kref *kref, int num)
+{
+ kref->refcount = num;
+}
+
+/**
+ * kref_init - initialize object.
+ * @kref: object in question.
+ */
+void kref_init(struct kref *kref)
+{
+ kref_set(kref, 1);
+}
+
+/**
+ * kref_get - increment refcount for object.
+ * @kref: object.
+ */
+void kref_get(struct kref *kref)
+{
+ kref->refcount++;
+}
+
+/**
+ * kref_put - decrement refcount for object.
+ * @kref: object.
+ * @release: pointer to the function that will clean up the object when the
+ * last reference to the object is released.
+ * This pointer is required, and it is not acceptable to pass kfree
+ * in as this function.
+ *
+ * Decrement the refcount, and if 0, call release().
+ * Return 1 if the object was removed, otherwise return 0. Beware, if this
+ * function returns 0, you still can not count on the kref from remaining in
+ * memory. Only use the return value if you want to see if the kref is now
+ * gone, not present.
+ */
+int kref_put(struct kref *kref, void (*release)(struct kref *kref))
+{
+ kref->refcount--;
+ if (!kref->refcount) {
+ release(kref);
+ return 1;
+ }
+ return 0;
+}
diff --git a/radeon_device.h b/radeon_device.h
new file mode 100644
index 0000000..2ac8f24
--- /dev/null
+++ b/radeon_device.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef RADEON_DEVICE_H
+#define RADEON_DEVICE_H
+
+#include "radeon.h"
+#include "lwrapper.h"
+#include "radeon_atom.h"
+
+struct radeon_device;
+struct radeon_ib;
+struct radeon_atom;
+
+/* R700 */
+struct r700_asic {
+ unsigned npipes;
+ unsigned nbanks;
+ unsigned group_bytes;
+ struct r600_atoms atoms;
+};
+
+union radeon_asic {
+ struct r700_asic r700;
+};
+
+/* Wrapper to make it looks like kernel *************************************/
+#define radeon_bo_size(bo) ((bo)->size)
+
+struct radeon_device {
+ struct radeon *radeon;
+ int fd;
+ union radeon_asic asic;
+};
+
+struct radeon_ib {
+ u32 *pkts;
+ u32 cpkts;
+ u32 length_dw;
+ u32 *relocs;
+ u32 crelocs;
+ u32 nrelocs;
+};
+
+extern u32 radeon_ib_reloc(struct radeon_ib *ib, struct radeon_bo *bo, u32 d);
+extern int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib);
+extern void radeon_ib_free(struct radeon_ib *ib);
+extern int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib);
+
+static inline int radeon_ib_begin(struct radeon_ib *ib, u32 ndw)
+{
+ if ((ib->cpkts + ndw) > ib->length_dw)
+ return -ENOMEM;
+ return 0;
+}
+
+static inline int radeon_ib_copy(struct radeon_ib *ib, u32 *pkts, u32 ndw)
+{
+ if ((ib->cpkts + ndw) > ib->length_dw)
+ return -ENOMEM;
+ memcpy(&ib->pkts[ib->cpkts], pkts, ndw * 4);
+ ib->cpkts += ndw;
+ return 0;
+}
+
+#endif
diff --git a/test.c b/test.c
new file mode 100644
index 0000000..9d5a5bb
--- /dev/null
+++ b/test.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright © 2009 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include "radeon.h"
+#include "r600_winsys.h"
+
+int r600_tri_flat(struct radeon *radeon);
+
+int main(void)
+{
+ struct radeon radeon;
+ int r;
+ int i;
+
+ r = radeon_init(&radeon);
+ if (r) {
+ radeon_fini(&radeon);
+ return r;
+ }
+ memset_bo(radeon.mode.bo, 0x0000FF);
+ r600_tri_flat(&radeon);
+ getchar();
+ radeon_fini(&radeon);
+ return 0;
+}
+
+int r600_tri_flat(struct radeon *radeon)
+{
+ struct radeon_device *rdev;
+ struct drm_r600_cb cb;
+ struct drm_r600_tp tp;
+ struct drm_r600_pa pa;
+ struct drm_r600_cb_cntl cb_cntl;
+ struct drm_r600_batch batch;
+ struct drm_radeon_atom atom;
+ int r;
+
+ r = radeon_device_init(&rdev, radeon);
+ if (r)
+ return r;
+ /* build cb */
+ cb.pitch = radeon->mode.pitch / 4;
+ cb.height = radeon->mode.height;
+ cb.nsamples = 1;
+ cb.color_info = 0x08110068;
+ cb.placements[0] = RADEON_GEM_DOMAIN_VRAM;
+ cb.placements[1] = 0;
+ cb.bo = radeon->mode.bo;
+ atom.type = R600_ATOM_CB;
+ atom.id = 0;
+ atom.data = (uint64_t)(uintptr_t)&cb;
+ r = radeon_atom_create(rdev, &atom);
+ if (r)
+ return r;
+ batch.cb_id = atom.id;
+ /* build tp */
+ tp.ta_cntl_aux = 0x07000002;
+ atom.type = R600_ATOM_TP;
+ atom.id = 0;
+ atom.data = (uint64_t)(uintptr_t)&tp;
+ r = radeon_atom_create(rdev, &atom);
+ if (r)
+ return r;
+ batch.tp_id = atom.id;
+ /* build pa */
+ pa.pa_sc_mpass_ps_cntl = 0x00000000;
+ pa.pa_sc_mode_cntl = 0x00514000;
+ pa.pa_sc_line_cntl = 0x00000400;
+ pa.pa_sc_screen_scissor_tl = 0x80000000;
+ pa.pa_sc_screen_scissor_br = 0x00fa00fa;
+ pa.pa_sc_window_offset = 0x00000000;
+ pa.pa_sc_window_scissor_tl = 0x80000000;
+ pa.pa_sc_window_scissor_br = 0x00fa00fa;
+ pa.pa_sc_cliprect_rule = 0x0000ffff;
+ pa.pa_sc_cliprect_0_tl = 0x00000000;
+ pa.pa_sc_cliprect_0_br = 0x00fa00fa;
+ pa.pa_sc_cliprect_1_tl = 0x00000000;
+ pa.pa_sc_cliprect_1_br = 0x00fa00fa;
+ pa.pa_sc_cliprect_2_tl = 0x00000000;
+ pa.pa_sc_cliprect_2_br = 0x00fa00fa;
+ pa.pa_sc_cliprect_3_tl = 0x00000000;
+ pa.pa_sc_cliprect_3_br = 0x00fa00fa;
+ pa.pa_sc_generic_scissor_tl = 0x80000000;
+ pa.pa_sc_generic_scissor_br = 0x00fa00fa;
+ pa.pa_sc_aa_config = 0x00000000;
+ pa.pa_sc_aa_sample_locs_mctx = 0x00000000;
+ pa.pa_sc_aa_mask = 0xffffffff;
+ pa.pa_cl_clip_cntl = 0x00000000;
+ pa.pa_cl_vte_cntl = 0x0000043f;
+ pa.pa_cl_vs_out_cntl = 0x00000000;
+ pa.pa_cl_naninf_cntl = 0x00000000;
+ pa.pa_cl_gb_vert_clip_adj = 0x3f800000;
+ pa.pa_cl_gb_vert_disc_adj = 0x3f800000;
+ pa.pa_cl_gb_horz_clip_adj = 0x3f800000;
+ pa.pa_cl_gb_horz_disc_adj = 0x3f800000;
+ pa.pa_su_sc_mode_cntl = 0x00080000;
+ pa.pa_su_point_size = 0x00080008;
+ pa.pa_su_point_minmax = 0x80000000;
+ pa.pa_su_line_cntl = 0x00000008;
+ pa.pa_sc_line_stipple = 0x00000005;
+ pa.pa_su_poly_offset_db_fmt_cntl = 0x00000000;
+ pa.pa_su_poly_offset_clamp = 0x00000000;
+ pa.pa_su_poly_offset_front_scale = 0x00000000;
+ pa.pa_su_poly_offset_front_offset = 0x00000000;
+ pa.pa_su_poly_offset_back_scale = 0x00000000;
+ pa.pa_su_poly_offset_back_offset = 0x00000000;
+ atom.type = R600_ATOM_PA;
+ atom.id = 0;
+ atom.data = (uint64_t)(uintptr_t)&pa;
+ r = radeon_atom_create(rdev, &atom);
+ if (r)
+ return r;
+ batch.pa_id = atom.id;
+ /* cb control */
+ cb_cntl.cb_target_mask = 0x0000000f;
+ cb_cntl.cb_shader_mask = 0x0000000f;
+ cb_cntl.cb_clrcmp_control = 0x01000000;
+ cb_cntl.cb_clrcmp_src = 0x00000000;
+ cb_cntl.cb_clrcmp_dst = 0x000000ff;
+ cb_cntl.cb_clrcmp_msk = 0xffffffff;
+ cb_cntl.cb_color_control = 0x00cc0000;
+ atom.type = R600_ATOM_CB_CNTL;
+ atom.id = 0;
+ atom.data = (uint64_t)(uintptr_t)&cb_cntl;
+ r = radeon_atom_create(rdev, &atom);
+ if (r)
+ return r;
+ batch.cb_cntl_id = atom.id;
+
+ r = radeon_batches_queue(rdev, &batch);
+ if (r)
+ return r;
+ r = radeon_batches_flush(rdev);
+ radeon_device_release(rdev);
+ return r;
+}
diff --git a/triflat.cs b/triflat.cs
new file mode 100644
index 0000000..bf0c681
--- /dev/null
+++ b/triflat.cs
@@ -0,0 +1,830 @@
+(3) PACKET3(0x28, 1, CONTEXT_CONTROL)
+(4) 0x80000000
+(5) 0x80000000
+(6) PACKET3(0x46, 0, EVENT_WRITE)
+(7) 0x00000016
+(8) PACKET3(0x68, 1, SET_CONFIG_REG)
+(9) 0x00000010 (index)
+(10) 0x00008040 = 0x00028000 (unknown)
+(11) PACKET3(0x68, 6, SET_CONFIG_REG)
+(12) 0x00000300 (index)
+(13) 0x00008C00 = 0x0000000D SQ_CONFIG
+(14) 0x00008C04 = 0x40240054 SQ_GPR_RESOURCE_MGMT_1
+(15) 0x00008C08 = 0x00000000 SQ_GPR_RESOURCE_MGMT_2
+(16) 0x00008C0C = 0x00003CBC SQ_THREAD_RESOURCE_MGMT
+(17) 0x00008C10 = 0x00800080 SQ_STACK_RESOURCE_MGMT_1
+(18) 0x00008C14 = 0x00000000 SQ_STACK_RESOURCE_MGMT_2
+(19) PACKET3(0x68, 1, SET_CONFIG_REG)
+(20) 0x00000542 (index)
+(21) 0x00009508 = 0x07000002 TA_CNTL_AUX
+(22) PACKET3(0x68, 1, SET_CONFIG_REG)
+(23) 0x000005C5 (index)
+(24) 0x00009714 = 0x00000000 (unknown)
+(25) PACKET3(0x68, 1, SET_CONFIG_REG)
+(26) 0x00000363 (index)
+(27) 0x00008D8C = 0x00004000 (unknown)
+(28) PACKET3(0x68, 1, SET_CONFIG_REG)
+(29) 0x0000060C (index)
+(30) 0x00009830 = 0x00000000 (unknown)
+(31) PACKET3(0x68, 1, SET_CONFIG_REG)
+(32) 0x0000060E (index)
+(33) 0x00009838 = 0x00420204 (unknown)
+(34) PACKET3(0x69, 9, SET_CONTEXT_REG)
+(35) 0x0000022A (index)
+(36) 0x000288A8 = 0x00000000 SQ_ESGS_RING_ITEMSIZE
+(37) 0x000288AC = 0x00000000 SQ_GSVS_RING_ITEMSIZE
+(38) 0x000288B0 = 0x00000000 SQ_ESTMP_RING_ITEMSIZE
+(39) 0x000288B4 = 0x00000000 SQ_GSTMP_RING_ITEMSIZE
+(40) 0x000288B8 = 0x00000000 SQ_VSTMP_RING_ITEMSIZE
+(41) 0x000288BC = 0x00000000 SQ_PSTMP_RING_ITEMSIZE
+(42) 0x000288C0 = 0x00000000 SQ_FBUF_RING_ITEMSIZE
+(43) 0x000288C4 = 0x00000000 SQ_REDUC_RING_ITEMSIZE
+(44) 0x000288C8 = 0x00000000 SQ_GS_VERT_ITEMSIZE
+(45) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(46) 0x0000000A (index)
+(47) 0x00028028 = 0x00000000 DB_STENCIL_CLEAR
+(48) 0x0002802C = 0x3F800000 DB_DEPTH_CLEAR
+(49) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(50) 0x00000200 (index)
+(51) 0x00028800 = 0x00700700 DB_DEPTH_CONTROL
+(52) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(53) 0x00000203 (index)
+(54) 0x0002880C = 0x00000210 DB_SHADER_CONTROL
+(55) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(56) 0x00000343 (index)
+(57) 0x00028D0C = 0x00000060 DB_RENDER_CONTROL
+(58) 0x00028D10 = 0x0000002A DB_RENDER_OVERRIDE
+(59) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(60) 0x00000351 (index)
+(61) 0x00028D44 = 0x0000AA00 (unknown)
+(62) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(63) 0x0000010C (index)
+(64) 0x00028430 = 0xFFFFFF00 DB_STENCILREFMASK
+(65) 0x00028434 = 0xFFFFFF00 DB_STENCILREFMASK_BF
+(66) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(67) 0x0000008C (index)
+(68) 0x00028230 = 0xAAAAAAAA (unknown)
+(69) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(70) 0x00000283 (index)
+(71) 0x00028A0C = 0x00000000 PA_SC_LINE_STIPPLE
+(72) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(73) 0x00000292 (index)
+(74) 0x00028A48 = 0x00000000 PA_SC_MPASS_PS_CNTL
+(75) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(76) 0x00000293 (index)
+(77) 0x00028A4C = 0x00514000 PA_SC_MODE_CNTL
+(78) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(79) 0x00000300 (index)
+(80) 0x00028C00 = 0x00000400 PA_SC_LINE_CNTL
+(81) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(82) 0x0000000C (index)
+(83) 0x00028030 = 0x80000000 PA_SC_SCREEN_SCISSOR_TL
+(84) 0x00028034 = 0x00FA00FA PA_SC_SCREEN_SCISSOR_BR
+(85) PACKET3(0x69, 12, SET_CONTEXT_REG)
+(86) 0x00000080 (index)
+(87) 0x00028200 = 0x00000000 PA_SC_WINDOW_OFFSET
+(88) 0x00028204 = 0x80000000 PA_SC_WINDOW_SCISSOR_TL
+(89) 0x00028208 = 0x00FA00FA PA_SC_WINDOW_SCISSOR_BR
+(90) 0x0002820C = 0x0000FFFF PA_SC_CLIPRECT_RULE
+(91) 0x00028210 = 0x00000000 PA_SC_CLIPRECT_0_TL
+(92) 0x00028214 = 0x00FA00FA PA_SC_CLIPRECT_0_BR
+(93) 0x00028218 = 0x00000000 PA_SC_CLIPRECT_1_TL
+(94) 0x0002821C = 0x00FA00FA PA_SC_CLIPRECT_1_BR
+(95) 0x00028220 = 0x00000000 PA_SC_CLIPRECT_2_TL
+(96) 0x00028224 = 0x00FA00FA PA_SC_CLIPRECT_2_BR
+(97) 0x00028228 = 0x00000000 PA_SC_CLIPRECT_3_TL
+(98) 0x0002822C = 0x00FA00FA PA_SC_CLIPRECT_3_BR
+(99) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(100) 0x00000090 (index)
+(101) 0x00028240 = 0x80000000 PA_SC_GENERIC_SCISSOR_TL
+(102) 0x00028244 = 0x00FA00FA PA_SC_GENERIC_SCISSOR_BR
+(103) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(104) 0x00000301 (index)
+(105) 0x00028C04 = 0x00000000 PA_SC_AA_CONFIG
+(106) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(107) 0x00000307 (index)
+(108) 0x00028C1C = 0x00000000 PA_SC_AA_SAMPLE_LOCS_MCTX
+(109) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(110) 0x00000308 (index)
+(111) 0x00028C20 = 0x00000000 (unknown)
+(112) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(113) 0x00000312 (index)
+(114) 0x00028C48 = 0xFFFFFFFF PA_SC_AA_MASK
+(115) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(116) 0x00000204 (index)
+(117) 0x00028810 = 0x00000000 PA_CL_CLIP_CNTL
+(118) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(119) 0x00000206 (index)
+(120) 0x00028818 = 0x0000043F PA_CL_VTE_CNTL
+(121) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(122) 0x00000207 (index)
+(123) 0x0002881C = 0x00000000 PA_CL_VS_OUT_CNTL
+(124) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(125) 0x00000208 (index)
+(126) 0x00028820 = 0x00000000 PA_CL_NANINF_CNTL
+(127) PACKET3(0x69, 4, SET_CONTEXT_REG)
+(128) 0x00000303 (index)
+(129) 0x00028C0C = 0x3F800000 PA_CL_GB_VERT_CLIP_ADJ
+(130) 0x00028C10 = 0x3F800000 PA_CL_GB_VERT_DISC_ADJ
+(131) 0x00028C14 = 0x3F800000 PA_CL_GB_HORZ_CLIP_ADJ
+(132) 0x00028C18 = 0x3F800000 PA_CL_GB_HORZ_DISC_ADJ
+(133) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(134) 0x00000205 (index)
+(135) 0x00028814 = 0x00080000 PA_SU_SC_MODE_CNTL
+(136) PACKET3(0x69, 4, SET_CONTEXT_REG)
+(137) 0x00000280 (index)
+(138) 0x00028A00 = 0x00080008 PA_SU_POINT_SIZE
+(139) 0x00028A04 = 0x80000000 PA_SU_POINT_MINMAX
+(140) 0x00028A08 = 0x00000008 PA_SU_LINE_CNTL
+(141) 0x00028A0C = 0x00000005 PA_SC_LINE_STIPPLE
+(142) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(143) 0x0000037E (index)
+(144) 0x00028DF8 = 0x00000000 PA_SU_POLY_OFFSET_DB_FMT_CNTL
+(145) 0x00028DFC = 0x00000000 PA_SU_POLY_OFFSET_CLAMP
+(146) PACKET3(0x69, 4, SET_CONTEXT_REG)
+(147) 0x00000380 (index)
+(148) 0x00028E00 = 0x00000000 PA_SU_POLY_OFFSET_FRONT_SCALE
+(149) 0x00028E04 = 0x00000000 PA_SU_POLY_OFFSET_FRONT_OFFSET
+(150) 0x00028E08 = 0x00000000 PA_SU_POLY_OFFSET_BACK_SCALE
+(151) 0x00028E0C = 0x00000000 PA_SU_POLY_OFFSET_BACK_OFFSET
+(152) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(153) 0x0000008E (index)
+(154) 0x00028238 = 0x0000000F CB_TARGET_MASK
+(155) 0x0002823C = 0x0000000F CB_SHADER_MASK
+(156) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(157) 0x000001E8 (index)
+(158) 0x000287A0 = 0x00000003 (unknown)
+(159) PACKET3(0x69, 4, SET_CONTEXT_REG)
+(160) 0x0000030C (index)
+(161) 0x00028C30 = 0x01000000 CB_CLRCMP_CONTROL
+(162) 0x00028C34 = 0x00000000 CB_CLRCMP_SRC
+(163) 0x00028C38 = 0x000000FF CB_CLRCMP_DST
+(164) 0x00028C3C = 0xFFFFFFFF CB_CLRCMP_MSK
+(165) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(166) 0x00000010 (index)
+(167) 0x00028040 = 0x00000000 CB_COLOR0_BASE
+(168) PACKET3(0x10, 0, NOP)
+(169) 0x00000000
+(170) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(171) 0x00000018 (index)
+(172) 0x00028060 = 0xFFFFFC1F CB_COLOR0_SIZE
+(173) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(174) 0x00000020 (index)
+(175) 0x00028080 = 0x00000000 CB_COLOR0_VIEW
+(176) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(177) 0x00000028 (index)
+(178) 0x000280A0 = 0x08110068 CB_COLOR0_INFO
+(179) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(180) 0x00000030 (index)
+(181) 0x000280C0 = 0x00000000 CB_COLOR0_TILE
+(182) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(183) 0x00000038 (index)
+(184) 0x000280E0 = 0x00000000 CB_COLOR0_FRAG
+(185) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(186) 0x00000040 (index)
+(187) 0x00028100 = 0x00000000 CB_COLOR0_MASK
+(188) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(189) 0x00000202 (index)
+(190) 0x00028808 = 0x00CC0000 CB_COLOR_CONTROL
+(191) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(192) 0x000001E0 (index)
+(193) 0x00028780 = 0x00010001 CB_BLEND0_CONTROL
+(194) PACKET3(0x69, 4, SET_CONTEXT_REG)
+(195) 0x00000105 (index)
+(196) 0x00028414 = 0x00000000 CB_BLEND_RED
+(197) 0x00028418 = 0x00000000 CB_BLEND_GREEN
+(198) 0x0002841C = 0x00000000 CB_BLEND_BLUE
+(199) 0x00028420 = 0x00000000 CB_BLEND_ALPHA
+(200) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(201) 0x000000D4 (index)
+(202) 0x00028350 = 0x00000000 SX_MISC
+(203) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(204) 0x00000104 (index)
+(205) 0x00028410 = 0x00000000 SX_ALPHA_TEST_CONTROL
+(206) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(207) 0x0000010E (index)
+(208) 0x00028438 = 0x00000000 SX_ALPHA_REF
+(209) PACKET3(0x69, 4, SET_CONTEXT_REG)
+(210) 0x00000100 (index)
+(211) 0x00028400 = 0x00FFFFFF VGT_MAX_VTX_INDX
+(212) 0x00028404 = 0x00000000 VGT_MIN_VTX_INDX
+(213) 0x00028408 = 0x00000000 VGT_INDX_OFFSET
+(214) 0x0002840C = 0x00000000 VGT_MULTI_PRIM_IB_RESET_INDX
+(215) PACKET3(0x69, 13, SET_CONTEXT_REG)
+(216) 0x00000284 (index)
+(217) 0x00028A10 = 0x00000000 VGT_OUTPUT_PATH_CNTL
+(218) 0x00028A14 = 0x00000000 VGT_HOS_CNTL
+(219) 0x00028A18 = 0x00000000 VGT_HOS_MAX_TESS_LEVEL
+(220) 0x00028A1C = 0x00000000 VGT_HOS_MIN_TESS_LEVEL
+(221) 0x00028A20 = 0x00000000 VGT_HOS_REUSE_DEPTH
+(222) 0x00028A24 = 0x00000000 VGT_GROUP_PRIM_TYPE
+(223) 0x00028A28 = 0x00000000 VGT_GROUP_FIRST_DECR
+(224) 0x00028A2C = 0x00000000 VGT_GROUP_DECR
+(225) 0x00028A30 = 0x00000000 VGT_GROUP_VECT_0_CNTL
+(226) 0x00028A34 = 0x00000000 VGT_GROUP_VECT_1_CNTL
+(227) 0x00028A38 = 0x00000000 VGT_GROUP_VECT_0_FMT_CNTL
+(228) 0x00028A3C = 0x00000000 VGT_GROUP_VECT_1_FMT_CNTL
+(229) 0x00028A40 = 0x00000000 VGT_GS_MODE
+(230) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(231) 0x000002A1 (index)
+(232) 0x00028A84 = 0x00000000 VGT_PRIMITIVEID_EN
+(233) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(234) 0x000002A5 (index)
+(235) 0x00028A94 = 0x00000000 VGT_MULTI_PRIM_IB_RESET_EN
+(236) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(237) 0x000002A8 (index)
+(238) 0x00028AA0 = 0x00000000 VGT_INSTANCE_STEP_RATE_0
+(239) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(240) 0x000002A9 (index)
+(241) 0x00028AA4 = 0x00000000 VGT_INSTANCE_STEP_RATE_1
+(242) PACKET3(0x69, 3, SET_CONTEXT_REG)
+(243) 0x000002AC (index)
+(244) 0x00028AB0 = 0x00000000 VGT_STRMOUT_EN
+(245) 0x00028AB4 = 0x00000001 VGT_REUSE_OFF
+(246) 0x00028AB8 = 0x00000000 VGT_VTX_CNT_EN
+(247) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(248) 0x000002C8 (index)
+(249) 0x00028B20 = 0x00000000 VGT_STRMOUT_BUFFER_EN
+(250) PACKET3(0x69, 32, SET_CONTEXT_REG)
+(251) 0x000000E0 (index)
+(252) 0x00028380 = 0x00000000 SQ_VTX_SEMANTIC_0
+(253) 0x00028384 = 0x00000000 SQ_VTX_SEMANTIC_1
+(254) 0x00028388 = 0x00000000 SQ_VTX_SEMANTIC_2
+(255) 0x0002838C = 0x00000000 SQ_VTX_SEMANTIC_3
+(256) 0x00028390 = 0x00000000 SQ_VTX_SEMANTIC_4
+(257) 0x00028394 = 0x00000000 SQ_VTX_SEMANTIC_5
+(258) 0x00028398 = 0x00000000 SQ_VTX_SEMANTIC_6
+(259) 0x0002839C = 0x00000000 SQ_VTX_SEMANTIC_7
+(260) 0x000283A0 = 0x00000000 SQ_VTX_SEMANTIC_8
+(261) 0x000283A4 = 0x00000000 SQ_VTX_SEMANTIC_9
+(262) 0x000283A8 = 0x00000000 SQ_VTX_SEMANTIC_10
+(263) 0x000283AC = 0x00000000 SQ_VTX_SEMANTIC_11
+(264) 0x000283B0 = 0x00000000 SQ_VTX_SEMANTIC_12
+(265) 0x000283B4 = 0x00000000 SQ_VTX_SEMANTIC_13
+(266) 0x000283B8 = 0x00000000 SQ_VTX_SEMANTIC_14
+(267) 0x000283BC = 0x00000000 SQ_VTX_SEMANTIC_15
+(268) 0x000283C0 = 0x00000000 SQ_VTX_SEMANTIC_16
+(269) 0x000283C4 = 0x00000000 SQ_VTX_SEMANTIC_17
+(270) 0x000283C8 = 0x00000000 SQ_VTX_SEMANTIC_18
+(271) 0x000283CC = 0x00000000 SQ_VTX_SEMANTIC_19
+(272) 0x000283D0 = 0x00000000 SQ_VTX_SEMANTIC_20
+(273) 0x000283D4 = 0x00000000 SQ_VTX_SEMANTIC_21
+(274) 0x000283D8 = 0x00000000 SQ_VTX_SEMANTIC_22
+(275) 0x000283DC = 0x00000000 SQ_VTX_SEMANTIC_23
+(276) 0x000283E0 = 0x00000000 SQ_VTX_SEMANTIC_24
+(277) 0x000283E4 = 0x00000000 SQ_VTX_SEMANTIC_25
+(278) 0x000283E8 = 0x00000000 SQ_VTX_SEMANTIC_26
+(279) 0x000283EC = 0x00000000 SQ_VTX_SEMANTIC_27
+(280) 0x000283F0 = 0x00000000 SQ_VTX_SEMANTIC_28
+(281) 0x000283F4 = 0x00000000 SQ_VTX_SEMANTIC_29
+(282) 0x000283F8 = 0x00000000 SQ_VTX_SEMANTIC_30
+(283) 0x000283FC = 0x00000000 SQ_VTX_SEMANTIC_31
+(284) PACKET3(0x69, 10, SET_CONTEXT_REG)
+(285) 0x00000185 (index)
+(286) 0x00028614 = 0x03020100 SPI_VS_OUT_ID_0
+(287) 0x00028618 = 0x07060504 SPI_VS_OUT_ID_1
+(288) 0x0002861C = 0x0B0A0908 SPI_VS_OUT_ID_2
+(289) 0x00028620 = 0x0F0E0D0C SPI_VS_OUT_ID_3
+(290) 0x00028624 = 0x00000000 SPI_VS_OUT_ID_4
+(291) 0x00028628 = 0x00000000 SPI_VS_OUT_ID_5
+(292) 0x0002862C = 0x00000000 SPI_VS_OUT_ID_6
+(293) 0x00028630 = 0x00000000 SPI_VS_OUT_ID_7
+(294) 0x00028634 = 0x00000000 SPI_VS_OUT_ID_8
+(295) 0x00028638 = 0x00000000 SPI_VS_OUT_ID_9
+(296) PACKET3(0x69, 9, SET_CONTEXT_REG)
+(297) 0x000001B1 (index)
+(298) 0x000286C4 = 0x00000000 SPI_VS_OUT_CONFIG
+(299) 0x000286C8 = 0x00000001 (unknown)
+(300) 0x000286CC = 0x10000001 SPI_PS_IN_CONTROL_0
+(301) 0x000286D0 = 0x00000000 SPI_PS_IN_CONTROL_1
+(302) 0x000286D4 = 0x00000000 SPI_INTERP_CONTROL_0
+(303) 0x000286D8 = 0x00000000 SPI_INPUT_Z
+(304) 0x000286DC = 0x00000000 SPI_FOG_CNTL
+(305) 0x000286E0 = 0x00000000 SPI_FOG_FUNC_SCALE
+(306) 0x000286E4 = 0x00000000 SPI_FOG_FUNC_BIAS
+(307) PACKET3(0x69, 32, SET_CONTEXT_REG)
+(308) 0x00000191 (index)
+(309) 0x00028644 = 0x00000800 SPI_PS_INPUT_CNTL_0
+(310) 0x00028648 = 0x00000000 SPI_PS_INPUT_CNTL_1
+(311) 0x0002864C = 0x00000000 SPI_PS_INPUT_CNTL_2
+(312) 0x00028650 = 0x00000000 SPI_PS_INPUT_CNTL_3
+(313) 0x00028654 = 0x00000000 SPI_PS_INPUT_CNTL_4
+(314) 0x00028658 = 0x00000000 SPI_PS_INPUT_CNTL_5
+(315) 0x0002865C = 0x00000000 SPI_PS_INPUT_CNTL_6
+(316) 0x00028660 = 0x00000000 SPI_PS_INPUT_CNTL_7
+(317) 0x00028664 = 0x00000000 SPI_PS_INPUT_CNTL_8
+(318) 0x00028668 = 0x00000000 SPI_PS_INPUT_CNTL_9
+(319) 0x0002866C = 0x00000000 SPI_PS_INPUT_CNTL_10
+(320) 0x00028670 = 0x00000000 SPI_PS_INPUT_CNTL_11
+(321) 0x00028674 = 0x00000000 SPI_PS_INPUT_CNTL_12
+(322) 0x00028678 = 0x00000000 SPI_PS_INPUT_CNTL_13
+(323) 0x0002867C = 0x00000000 SPI_PS_INPUT_CNTL_14
+(324) 0x00028680 = 0x00000000 SPI_PS_INPUT_CNTL_15
+(325) 0x00028684 = 0x00000000 SPI_PS_INPUT_CNTL_16
+(326) 0x00028688 = 0x00000000 SPI_PS_INPUT_CNTL_17
+(327) 0x0002868C = 0x00000000 SPI_PS_INPUT_CNTL_18
+(328) 0x00028690 = 0x00000000 SPI_PS_INPUT_CNTL_19
+(329) 0x00028694 = 0x00000000 SPI_PS_INPUT_CNTL_20
+(330) 0x00028698 = 0x00000000 SPI_PS_INPUT_CNTL_21
+(331) 0x0002869C = 0x00000000 SPI_PS_INPUT_CNTL_22
+(332) 0x000286A0 = 0x00000000 SPI_PS_INPUT_CNTL_23
+(333) 0x000286A4 = 0x00000000 SPI_PS_INPUT_CNTL_24
+(334) 0x000286A8 = 0x00000000 SPI_PS_INPUT_CNTL_25
+(335) 0x000286AC = 0x00000000 SPI_PS_INPUT_CNTL_26
+(336) 0x000286B0 = 0x00000000 SPI_PS_INPUT_CNTL_27
+(337) 0x000286B4 = 0x00000000 SPI_PS_INPUT_CNTL_28
+(338) 0x000286B8 = 0x00000000 SPI_PS_INPUT_CNTL_29
+(339) 0x000286BC = 0x00000000 SPI_PS_INPUT_CNTL_30
+(340) 0x000286C0 = 0x00000000 SPI_PS_INPUT_CNTL_31
+(341) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(342) 0x00000094 (index)
+(343) 0x00028250 = 0x80000000 (unknown)
+(344) 0x00028254 = 0x00FA00FA (unknown)
+(345) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(346) 0x000000B4 (index)
+(347) 0x000282D0 = 0x00000000 PA_SC_VPORT_ZMIN_0
+(348) 0x000282D4 = 0x3F800000 PA_SC_VPORT_ZMAX_0
+(349) PACKET3(0x69, 6, SET_CONTEXT_REG)
+(350) 0x0000010F (index)
+(351) 0x0002843C = 0x42FA0000 PA_CL_VPORT_XSCALE_0
+(352) 0x00028440 = 0x42FA0000 PA_CL_VPORT_XOFFSET_0
+(353) 0x00028444 = 0xC2FA0000 PA_CL_VPORT_YSCALE_0
+(354) 0x00028448 = 0x42FA0000 PA_CL_VPORT_YOFFSET_0
+(355) 0x0002844C = 0x3F000000 PA_CL_VPORT_ZSCALE_0
+(356) 0x00028450 = 0x3F000000 PA_CL_VPORT_ZOFFSET_0
+(357) PACKET3(0x43, 3, SURFACE_SYNC)
+(358) 0x08000000
+(359) 0x00000001
+(360) 0x00000000
+(361) 0x0000000A
+(362) PACKET3(0x10, 0, NOP)
+(363) 0x00000004
+(364) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(365) 0x00000225 (index)
+(366) 0x00028894 = 0x00000000 SQ_PGM_START_FS
+(367) PACKET3(0x10, 0, NOP)
+(368) 0x00000004
+(369) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(370) 0x00000229 (index)
+(371) 0x000288A4 = 0x00000000 SQ_PGM_RESOURCES_FS
+(372) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(373) 0x00000237 (index)
+(374) 0x000288DC = 0x00000000 SQ_PGM_CF_OFFSET_FS
+(375) PACKET3(0x43, 3, SURFACE_SYNC)
+(376) 0x08000000
+(377) 0x00000001
+(378) 0x00000000
+(379) 0x0000000A
+(380) PACKET3(0x10, 0, NOP)
+(381) 0x00000004
+(382) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(383) 0x00000216 (index)
+(384) 0x00028858 = 0x00000000 SQ_PGM_START_VS
+(385) PACKET3(0x10, 0, NOP)
+(386) 0x00000004
+(387) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(388) 0x0000021A (index)
+(389) 0x00028868 = 0x00000006 SQ_PGM_RESOURCES_VS
+(390) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(391) 0x00000234 (index)
+(392) 0x000288D0 = 0x00000000 SQ_PGM_CF_OFFSET_VS
+(393) PACKET3(0x6C, 1, SET_LOOP_CONST)
+(394) 0x00000020
+(395) 0x0100000F
+(396) PACKET3(0x43, 3, SURFACE_SYNC)
+(397) 0x08000000
+(398) 0x00000001
+(399) 0x00000000
+(400) 0x0000000A
+(401) PACKET3(0x10, 0, NOP)
+(402) 0x00000008
+(403) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(404) 0x00000210 (index)
+(405) 0x00028840 = 0x00000000 SQ_PGM_START_PS
+(406) PACKET3(0x10, 0, NOP)
+(407) 0x00000008
+(408) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(409) 0x00000214 (index)
+(410) 0x00028850 = 0x00000003 SQ_PGM_RESOURCES_PS
+(411) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(412) 0x00000215 (index)
+(413) 0x00028854 = 0x00000002 SQ_PGM_EXPORTS_PS
+(414) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(415) 0x00000233 (index)
+(416) 0x000288CC = 0x00000000 SQ_PGM_CF_OFFSET_PS
+(417) PACKET3(0x6C, 1, SET_LOOP_CONST)
+(418) 0x00000000
+(419) 0x01000FFF
+(420) PACKET3(0x6A, 16, SET_ALU_CONST)
+(421) 0x00000400
+(422) 0x3C03126F
+(423) 0x00000000
+(424) 0x00000000
+(425) 0xBF800000
+(426) 0x00000000
+(427) 0x3C03126F
+(428) 0x00000000
+(429) 0xBF800000
+(430) 0x00000000
+(431) 0x00000000
+(432) 0xBF800000
+(433) 0x00000000
+(434) 0x00000000
+(435) 0x00000000
+(436) 0x00000000
+(437) 0x3F800000
+(438) PACKET3(0x6F, 1, SET_CTL_CONST)
+(439) 0x00000000
+(440) 0x00000000
+(441) PACKET3(0x6F, 1, SET_CTL_CONST)
+(442) 0x00000001
+(443) 0x00000000
+(444) PACKET3(0x43, 3, SURFACE_SYNC)
+(445) 0x01000000
+(446) 0x00000001
+(447) 0x00000000
+(448) 0x0000000A
+(449) PACKET3(0x10, 0, NOP)
+(450) 0x0000000C
+(451) PACKET3(0x6D, 7, SET_RESOURCE)
+(452) 0x00000460
+(453) 0x00000000
+(454) 0x0000006F
+(455) 0x03001C00
+(456) 0x00000001
+(457) 0x00000000
+(458) 0x00000000
+(459) 0xC0000000
+(460) PACKET3(0x10, 0, NOP)
+(461) 0x0000000C
+(462) PACKET3(0x43, 3, SURFACE_SYNC)
+(463) 0x01000000
+(464) 0x00000001
+(465) 0x00000000
+(466) 0x0000000A
+(467) PACKET3(0x10, 0, NOP)
+(468) 0x0000000C
+(469) PACKET3(0x6D, 7, SET_RESOURCE)
+(470) 0x00000475
+(471) 0x0000000C
+(472) 0x0000006F
+(473) 0x02301C00
+(474) 0x00000001
+(475) 0x00000000
+(476) 0x00000000
+(477) 0xC0000000
+(478) PACKET3(0x10, 0, NOP)
+(479) 0x0000000C
+(480) PACKET3(0x68, 1, SET_CONFIG_REG)
+(481) 0x00000256 (index)
+(482) 0x00008958 = 0x00000005 VGT_PRIMITIVE_TYPE
+(483) PACKET3(0x2A, 0, INDEX_TYPE)
+(484) 0x00000000
+(485) PACKET3(0x2F, 0, NUM_INSTANCES)
+(486) 0x00000001
+(487) PACKET3(0x2D, 1, DRAW_INDEX_AUTO)
+(488) 0x00000004
+(489) 0x00000002
+(490) PACKET3(0x46, 0, EVENT_WRITE)
+(491) 0x00000016
+(492) PACKET3(0x68, 1, SET_CONFIG_REG)
+(493) 0x00000010 (index)
+(494) 0x00008040 = 0x00028000 (unknown)
+(495) PACKET3(0x43, 3, SURFACE_SYNC)
+(496) 0x02000040
+(497) 0x000003F0
+(498) 0x00000000
+(499) 0x0000000A
+(500) PACKET3(0x10, 0, NOP)
+(501) 0x00000000
+(502) PACKET3(0x28, 1, CONTEXT_CONTROL)
+(503) 0x80000000
+(504) 0x80000000
+(505) PACKET3(0x46, 0, EVENT_WRITE)
+(506) 0x00000016
+(507) PACKET3(0x68, 1, SET_CONFIG_REG)
+(508) 0x00000010 (index)
+(509) 0x00008040 = 0x00028000 (unknown)
+(510) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(511) 0x0000000A (index)
+(512) 0x00028028 = 0x00000000 DB_STENCIL_CLEAR
+(513) 0x0002802C = 0x3F800000 DB_DEPTH_CLEAR
+(514) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(515) 0x00000200 (index)
+(516) 0x00028800 = 0x00700700 DB_DEPTH_CONTROL
+(517) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(518) 0x00000203 (index)
+(519) 0x0002880C = 0x00000210 DB_SHADER_CONTROL
+(520) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(521) 0x00000343 (index)
+(522) 0x00028D0C = 0x00000060 DB_RENDER_CONTROL
+(523) 0x00028D10 = 0x0000002A DB_RENDER_OVERRIDE
+(524) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(525) 0x00000351 (index)
+(526) 0x00028D44 = 0x0000AA00 (unknown)
+(527) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(528) 0x0000010C (index)
+(529) 0x00028430 = 0xFFFFFF00 DB_STENCILREFMASK
+(530) 0x00028434 = 0xFFFFFF00 DB_STENCILREFMASK_BF
+(531) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(532) 0x0000000C (index)
+(533) 0x00028030 = 0x80000000 PA_SC_SCREEN_SCISSOR_TL
+(534) 0x00028034 = 0x00FA00FA PA_SC_SCREEN_SCISSOR_BR
+(535) PACKET3(0x69, 12, SET_CONTEXT_REG)
+(536) 0x00000080 (index)
+(537) 0x00028200 = 0x00000000 PA_SC_WINDOW_OFFSET
+(538) 0x00028204 = 0x80000000 PA_SC_WINDOW_SCISSOR_TL
+(539) 0x00028208 = 0x00FA00FA PA_SC_WINDOW_SCISSOR_BR
+(540) 0x0002820C = 0x0000FFFF PA_SC_CLIPRECT_RULE
+(541) 0x00028210 = 0x00000000 PA_SC_CLIPRECT_0_TL
+(542) 0x00028214 = 0x00FA00FA PA_SC_CLIPRECT_0_BR
+(543) 0x00028218 = 0x00000000 PA_SC_CLIPRECT_1_TL
+(544) 0x0002821C = 0x00FA00FA PA_SC_CLIPRECT_1_BR
+(545) 0x00028220 = 0x00000000 PA_SC_CLIPRECT_2_TL
+(546) 0x00028224 = 0x00FA00FA PA_SC_CLIPRECT_2_BR
+(547) 0x00028228 = 0x00000000 PA_SC_CLIPRECT_3_TL
+(548) 0x0002822C = 0x00FA00FA PA_SC_CLIPRECT_3_BR
+(549) PACKET3(0x69, 2, SET_CONTEXT_REG)
+(550) 0x00000090 (index)
+(551) 0x00028240 = 0x80000000 PA_SC_GENERIC_SCISSOR_TL
+(552) 0x00028244 = 0x00FA00FA PA_SC_GENERIC_SCISSOR_BR
+(553) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(554) 0x00000204 (index)
+(555) 0x00028810 = 0x00000000 PA_CL_CLIP_CNTL
+(556) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(557) 0x00000206 (index)
+(558) 0x00028818 = 0x0000043F PA_CL_VTE_CNTL
+(559) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(560) 0x00000207 (index)
+(561) 0x0002881C = 0x00000000 PA_CL_VS_OUT_CNTL
+(562) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(563) 0x00000208 (index)
+(564) 0x00028820 = 0x00000000 PA_CL_NANINF_CNTL
+(565) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(566) 0x00000205 (index)
+(567) 0x00028814 = 0x00080000 PA_SU_SC_MODE_CNTL
+(568) PACKET3(0x69, 4, SET_CONTEXT_REG)
+(569) 0x00000280 (index)
+(570) 0x00028A00 = 0x00080008 PA_SU_POINT_SIZE
+(571) 0x00028A04 = 0x80000000 PA_SU_POINT_MINMAX
+(572) 0x00028A08 = 0x00000008 PA_SU_LINE_CNTL
+(573) 0x00028A0C = 0x00000005 PA_SC_LINE_STIPPLE
+(574) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(575) 0x00000010 (index)
+(576) 0x00028040 = 0x00000000 CB_COLOR0_BASE
+(577) PACKET3(0x10, 0, NOP)
+(578) 0x00000000
+(579) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(580) 0x00000018 (index)
+(581) 0x00028060 = 0xFFFFFC1F CB_COLOR0_SIZE
+(582) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(583) 0x00000020 (index)
+(584) 0x00028080 = 0x00000000 CB_COLOR0_VIEW
+(585) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(586) 0x00000028 (index)
+(587) 0x000280A0 = 0x08110068 CB_COLOR0_INFO
+(588) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(589) 0x00000030 (index)
+(590) 0x000280C0 = 0x00000000 CB_COLOR0_TILE
+(591) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(592) 0x00000038 (index)
+(593) 0x000280E0 = 0x00000000 CB_COLOR0_FRAG
+(594) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(595) 0x00000040 (index)
+(596) 0x00028100 = 0x00000000 CB_COLOR0_MASK
+(597) PACKET3(0x69, 32, SET_CONTEXT_REG)
+(598) 0x000000E0 (index)
+(599) 0x00028380 = 0x00000000 SQ_VTX_SEMANTIC_0
+(600) 0x00028384 = 0x00000000 SQ_VTX_SEMANTIC_1
+(601) 0x00028388 = 0x00000000 SQ_VTX_SEMANTIC_2
+(602) 0x0002838C = 0x00000000 SQ_VTX_SEMANTIC_3
+(603) 0x00028390 = 0x00000000 SQ_VTX_SEMANTIC_4
+(604) 0x00028394 = 0x00000000 SQ_VTX_SEMANTIC_5
+(605) 0x00028398 = 0x00000000 SQ_VTX_SEMANTIC_6
+(606) 0x0002839C = 0x00000000 SQ_VTX_SEMANTIC_7
+(607) 0x000283A0 = 0x00000000 SQ_VTX_SEMANTIC_8
+(608) 0x000283A4 = 0x00000000 SQ_VTX_SEMANTIC_9
+(609) 0x000283A8 = 0x00000000 SQ_VTX_SEMANTIC_10
+(610) 0x000283AC = 0x00000000 SQ_VTX_SEMANTIC_11
+(611) 0x000283B0 = 0x00000000 SQ_VTX_SEMANTIC_12
+(612) 0x000283B4 = 0x00000000 SQ_VTX_SEMANTIC_13
+(613) 0x000283B8 = 0x00000000 SQ_VTX_SEMANTIC_14
+(614) 0x000283BC = 0x00000000 SQ_VTX_SEMANTIC_15
+(615) 0x000283C0 = 0x00000000 SQ_VTX_SEMANTIC_16
+(616) 0x000283C4 = 0x00000000 SQ_VTX_SEMANTIC_17
+(617) 0x000283C8 = 0x00000000 SQ_VTX_SEMANTIC_18
+(618) 0x000283CC = 0x00000000 SQ_VTX_SEMANTIC_19
+(619) 0x000283D0 = 0x00000000 SQ_VTX_SEMANTIC_20
+(620) 0x000283D4 = 0x00000000 SQ_VTX_SEMANTIC_21
+(621) 0x000283D8 = 0x00000000 SQ_VTX_SEMANTIC_22
+(622) 0x000283DC = 0x00000000 SQ_VTX_SEMANTIC_23
+(623) 0x000283E0 = 0x00000000 SQ_VTX_SEMANTIC_24
+(624) 0x000283E4 = 0x00000000 SQ_VTX_SEMANTIC_25
+(625) 0x000283E8 = 0x00000000 SQ_VTX_SEMANTIC_26
+(626) 0x000283EC = 0x00000000 SQ_VTX_SEMANTIC_27
+(627) 0x000283F0 = 0x00000000 SQ_VTX_SEMANTIC_28
+(628) 0x000283F4 = 0x00000000 SQ_VTX_SEMANTIC_29
+(629) 0x000283F8 = 0x00000000 SQ_VTX_SEMANTIC_30
+(630) 0x000283FC = 0x00000000 SQ_VTX_SEMANTIC_31
+(631) PACKET3(0x69, 10, SET_CONTEXT_REG)
+(632) 0x00000185 (index)
+(633) 0x00028614 = 0x03020100 SPI_VS_OUT_ID_0
+(634) 0x00028618 = 0x07060504 SPI_VS_OUT_ID_1
+(635) 0x0002861C = 0x0B0A0908 SPI_VS_OUT_ID_2
+(636) 0x00028620 = 0x0F0E0D0C SPI_VS_OUT_ID_3
+(637) 0x00028624 = 0x00000000 SPI_VS_OUT_ID_4
+(638) 0x00028628 = 0x00000000 SPI_VS_OUT_ID_5
+(639) 0x0002862C = 0x00000000 SPI_VS_OUT_ID_6
+(640) 0x00028630 = 0x00000000 SPI_VS_OUT_ID_7
+(641) 0x00028634 = 0x00000000 SPI_VS_OUT_ID_8
+(642) 0x00028638 = 0x00000000 SPI_VS_OUT_ID_9
+(643) PACKET3(0x69, 9, SET_CONTEXT_REG)
+(644) 0x000001B1 (index)
+(645) 0x000286C4 = 0x00000000 SPI_VS_OUT_CONFIG
+(646) 0x000286C8 = 0x00000001 (unknown)
+(647) 0x000286CC = 0x10000001 SPI_PS_IN_CONTROL_0
+(648) 0x000286D0 = 0x00000000 SPI_PS_IN_CONTROL_1
+(649) 0x000286D4 = 0x00000001 SPI_INTERP_CONTROL_0
+(650) 0x000286D8 = 0x00000000 SPI_INPUT_Z
+(651) 0x000286DC = 0x00000000 SPI_FOG_CNTL
+(652) 0x000286E0 = 0x00000000 SPI_FOG_FUNC_SCALE
+(653) 0x000286E4 = 0x00000000 SPI_FOG_FUNC_BIAS
+(654) PACKET3(0x69, 32, SET_CONTEXT_REG)
+(655) 0x00000191 (index)
+(656) 0x00028644 = 0x00000C00 SPI_PS_INPUT_CNTL_0
+(657) 0x00028648 = 0x00000000 SPI_PS_INPUT_CNTL_1
+(658) 0x0002864C = 0x00000000 SPI_PS_INPUT_CNTL_2
+(659) 0x00028650 = 0x00000000 SPI_PS_INPUT_CNTL_3
+(660) 0x00028654 = 0x00000000 SPI_PS_INPUT_CNTL_4
+(661) 0x00028658 = 0x00000000 SPI_PS_INPUT_CNTL_5
+(662) 0x0002865C = 0x00000000 SPI_PS_INPUT_CNTL_6
+(663) 0x00028660 = 0x00000000 SPI_PS_INPUT_CNTL_7
+(664) 0x00028664 = 0x00000000 SPI_PS_INPUT_CNTL_8
+(665) 0x00028668 = 0x00000000 SPI_PS_INPUT_CNTL_9
+(666) 0x0002866C = 0x00000000 SPI_PS_INPUT_CNTL_10
+(667) 0x00028670 = 0x00000000 SPI_PS_INPUT_CNTL_11
+(668) 0x00028674 = 0x00000000 SPI_PS_INPUT_CNTL_12
+(669) 0x00028678 = 0x00000000 SPI_PS_INPUT_CNTL_13
+(670) 0x0002867C = 0x00000000 SPI_PS_INPUT_CNTL_14
+(671) 0x00028680 = 0x00000000 SPI_PS_INPUT_CNTL_15
+(672) 0x00028684 = 0x00000000 SPI_PS_INPUT_CNTL_16
+(673) 0x00028688 = 0x00000000 SPI_PS_INPUT_CNTL_17
+(674) 0x0002868C = 0x00000000 SPI_PS_INPUT_CNTL_18
+(675) 0x00028690 = 0x00000000 SPI_PS_INPUT_CNTL_19
+(676) 0x00028694 = 0x00000000 SPI_PS_INPUT_CNTL_20
+(677) 0x00028698 = 0x00000000 SPI_PS_INPUT_CNTL_21
+(678) 0x0002869C = 0x00000000 SPI_PS_INPUT_CNTL_22
+(679) 0x000286A0 = 0x00000000 SPI_PS_INPUT_CNTL_23
+(680) 0x000286A4 = 0x00000000 SPI_PS_INPUT_CNTL_24
+(681) 0x000286A8 = 0x00000000 SPI_PS_INPUT_CNTL_25
+(682) 0x000286AC = 0x00000000 SPI_PS_INPUT_CNTL_26
+(683) 0x000286B0 = 0x00000000 SPI_PS_INPUT_CNTL_27
+(684) 0x000286B4 = 0x00000000 SPI_PS_INPUT_CNTL_28
+(685) 0x000286B8 = 0x00000000 SPI_PS_INPUT_CNTL_29
+(686) 0x000286BC = 0x00000000 SPI_PS_INPUT_CNTL_30
+(687) 0x000286C0 = 0x00000000 SPI_PS_INPUT_CNTL_31
+(688) PACKET3(0x43, 3, SURFACE_SYNC)
+(689) 0x08000000
+(690) 0x00000001
+(691) 0x00000000
+(692) 0x0000000A
+(693) PACKET3(0x10, 0, NOP)
+(694) 0x00000010
+(695) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(696) 0x00000225 (index)
+(697) 0x00028894 = 0x00000000 SQ_PGM_START_FS
+(698) PACKET3(0x10, 0, NOP)
+(699) 0x00000010
+(700) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(701) 0x00000229 (index)
+(702) 0x000288A4 = 0x00000000 SQ_PGM_RESOURCES_FS
+(703) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(704) 0x00000237 (index)
+(705) 0x000288DC = 0x00000000 SQ_PGM_CF_OFFSET_FS
+(706) PACKET3(0x43, 3, SURFACE_SYNC)
+(707) 0x08000000
+(708) 0x00000001
+(709) 0x00000000
+(710) 0x0000000A
+(711) PACKET3(0x10, 0, NOP)
+(712) 0x00000010
+(713) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(714) 0x00000216 (index)
+(715) 0x00028858 = 0x00000000 SQ_PGM_START_VS
+(716) PACKET3(0x10, 0, NOP)
+(717) 0x00000010
+(718) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(719) 0x0000021A (index)
+(720) 0x00028868 = 0x00000006 SQ_PGM_RESOURCES_VS
+(721) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(722) 0x00000234 (index)
+(723) 0x000288D0 = 0x00000000 SQ_PGM_CF_OFFSET_VS
+(724) PACKET3(0x6C, 1, SET_LOOP_CONST)
+(725) 0x00000020
+(726) 0x0100000F
+(727) PACKET3(0x43, 3, SURFACE_SYNC)
+(728) 0x08000000
+(729) 0x00000001
+(730) 0x00000000
+(731) 0x0000000A
+(732) PACKET3(0x10, 0, NOP)
+(733) 0x00000008
+(734) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(735) 0x00000210 (index)
+(736) 0x00028840 = 0x00000000 SQ_PGM_START_PS
+(737) PACKET3(0x10, 0, NOP)
+(738) 0x00000008
+(739) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(740) 0x00000214 (index)
+(741) 0x00028850 = 0x00000003 SQ_PGM_RESOURCES_PS
+(742) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(743) 0x00000215 (index)
+(744) 0x00028854 = 0x00000002 SQ_PGM_EXPORTS_PS
+(745) PACKET3(0x69, 1, SET_CONTEXT_REG)
+(746) 0x00000233 (index)
+(747) 0x000288CC = 0x00000000 SQ_PGM_CF_OFFSET_PS
+(748) PACKET3(0x6C, 1, SET_LOOP_CONST)
+(749) 0x00000000
+(750) 0x01000FFF
+(751) PACKET3(0x6A, 16, SET_ALU_CONST)
+(752) 0x00000400
+(753) 0x3F800000
+(754) 0x00000000
+(755) 0x00000000
+(756) 0x00000000
+(757) 0x00000000
+(758) 0x3F800000
+(759) 0x00000000
+(760) 0x00000000
+(761) 0x00000000
+(762) 0x00000000
+(763) 0xBB0301AA
+(764) 0xBF7FBE7F
+(765) 0x00000000
+(766) 0x00000000
+(767) 0x00000000
+(768) 0x3F800000
+(769) PACKET3(0x6F, 1, SET_CTL_CONST)
+(770) 0x00000000
+(771) 0x00000000
+(772) PACKET3(0x6F, 1, SET_CTL_CONST)
+(773) 0x00000001
+(774) 0x00000000
+(775) PACKET3(0x43, 3, SURFACE_SYNC)
+(776) 0x01000000
+(777) 0x00000100
+(778) 0x00000000
+(779) 0x0000000A
+(780) PACKET3(0x10, 0, NOP)
+(781) 0x00000014
+(782) PACKET3(0x6D, 7, SET_RESOURCE)
+(783) 0x00000460
+(784) 0x00000000
+(785) 0x00000023
+(786) 0x03000C00
+(787) 0x00000001
+(788) 0x00000000
+(789) 0x00000000
+(790) 0xC0000000
+(791) PACKET3(0x10, 0, NOP)
+(792) 0x00000014
+(793) PACKET3(0x43, 3, SURFACE_SYNC)
+(794) 0x01000000
+(795) 0x00000100
+(796) 0x00000000
+(797) 0x0000000A
+(798) PACKET3(0x10, 0, NOP)
+(799) 0x00000014
+(800) PACKET3(0x6D, 7, SET_RESOURCE)
+(801) 0x00000475
+(802) 0x00000040
+(803) 0x00000023
+(804) 0x03000C00
+(805) 0x00000001
+(806) 0x00000000
+(807) 0x00000000
+(808) 0xC0000000
+(809) PACKET3(0x10, 0, NOP)
+(810) 0x00000014
+(811) PACKET3(0x68, 1, SET_CONFIG_REG)
+(812) 0x00000256 (index)
+(813) 0x00008958 = 0x00000004 VGT_PRIMITIVE_TYPE
+(814) PACKET3(0x2A, 0, INDEX_TYPE)
+(815) 0x00000000
+(816) PACKET3(0x2F, 0, NUM_INSTANCES)
+(817) 0x00000001
+(818) PACKET3(0x2D, 1, DRAW_INDEX_AUTO)
+(819) 0x00000003
+(820) 0x00000002
+(821) PACKET3(0x46, 0, EVENT_WRITE)
+(822) 0x00000016
+(823) PACKET3(0x68, 1, SET_CONFIG_REG)
+(824) 0x00000010 (index)
+(825) 0x00008040 = 0x00028000 (unknown)
+(826) PACKET3(0x43, 3, SURFACE_SYNC)
+(827) 0x02000040
+(828) 0x000003F0
+(829) 0x00000000
+(830) 0x0000000A
+(831) PACKET3(0x10, 0, NOP)
+(832) 0x00000000