summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/r600
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/r600')
-rw-r--r--src/gallium/winsys/r600/Android.mk38
-rw-r--r--src/gallium/winsys/r600/drm/Makefile5
-rw-r--r--src/gallium/winsys/r600/drm/SConscript10
-rw-r--r--src/gallium/winsys/r600/drm/bof.c2
-rw-r--r--src/gallium/winsys/r600/drm/evergreen_hw_context.c76
-rw-r--r--src/gallium/winsys/r600/drm/r600.c175
-rw-r--r--src/gallium/winsys/r600/drm/r600_bo.c174
-rw-r--r--src/gallium/winsys/r600/drm/r600_bomgr.c161
-rw-r--r--src/gallium/winsys/r600/drm/r600_drm.c280
-rw-r--r--src/gallium/winsys/r600/drm/r600_hw_context.c238
-rw-r--r--src/gallium/winsys/r600/drm/r600_priv.h125
-rw-r--r--src/gallium/winsys/r600/drm/r600d.h18
-rw-r--r--src/gallium/winsys/r600/drm/radeon_bo.c31
-rw-r--r--src/gallium/winsys/r600/drm/radeon_bo_pb.c260
-rw-r--r--src/gallium/winsys/r600/drm/radeon_pciid.c114
15 files changed, 881 insertions, 826 deletions
diff --git a/src/gallium/winsys/r600/Android.mk b/src/gallium/winsys/r600/Android.mk
new file mode 100644
index 0000000000..643a59dc42
--- /dev/null
+++ b/src/gallium/winsys/r600/Android.mk
@@ -0,0 +1,38 @@
+ifeq ($(strip $(MESA_BUILD_R600G)),true)
+
+LOCAL_PATH := $(call my-dir)
+
+# from drm/Makefile
+C_SOURCES = \
+ bof.c \
+ evergreen_hw_context.c \
+ radeon_bo.c \
+ radeon_pciid.c \
+ r600_bo.c \
+ r600_drm.c \
+ r600_hw_context.c \
+ r600_bomgr.c
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ $(addprefix drm/, $(C_SOURCES))
+
+LOCAL_CFLAGS := \
+ -std=c99 \
+ -fvisibility=hidden \
+ -Wno-sign-compare
+
+LOCAL_C_INCLUDES := \
+ external/mesa/include \
+ external/mesa/src/gallium/include \
+ external/mesa/src/gallium/auxiliary \
+ external/mesa/src/gallium/drivers/r600 \
+ external/drm \
+ external/drm/include/drm
+
+LOCAL_MODULE := libmesa_winsys_r600
+
+include $(BUILD_STATIC_LIBRARY)
+
+endif # MESA_BUILD_R600G
diff --git a/src/gallium/winsys/r600/drm/Makefile b/src/gallium/winsys/r600/drm/Makefile
index a396205f89..7310734f05 100644
--- a/src/gallium/winsys/r600/drm/Makefile
+++ b/src/gallium/winsys/r600/drm/Makefile
@@ -8,12 +8,11 @@ C_SOURCES = \
bof.c \
evergreen_hw_context.c \
radeon_bo.c \
- radeon_bo_pb.c \
radeon_pciid.c \
- r600.c \
r600_bo.c \
r600_drm.c \
- r600_hw_context.c
+ r600_hw_context.c \
+ r600_bomgr.c
LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r600 \
$(shell pkg-config libdrm --cflags-only-I)
diff --git a/src/gallium/winsys/r600/drm/SConscript b/src/gallium/winsys/r600/drm/SConscript
index cc053c06dd..cc9a06a239 100644
--- a/src/gallium/winsys/r600/drm/SConscript
+++ b/src/gallium/winsys/r600/drm/SConscript
@@ -6,15 +6,19 @@ r600_sources = [
'bof.c',
'evergreen_hw_context.c',
'radeon_bo.c',
- 'radeon_bo_pb.c',
'radeon_pciid.c',
- 'r600.c',
'r600_bo.c',
'r600_drm.c',
'r600_hw_context.c',
+ 'r600_bomgr.c',
]
-env.ParseConfig('pkg-config --cflags libdrm_radeon')
+try:
+ env.ParseConfig('pkg-config --cflags libdrm_radeon')
+except OSError:
+ print 'warning: not building r600g'
+ Return()
+
env.Append(CPPPATH = '#/src/gallium/drivers/r600')
r600winsys = env.ConvenienceLibrary(
diff --git a/src/gallium/winsys/r600/drm/bof.c b/src/gallium/winsys/r600/drm/bof.c
index 0598cc6bc0..5c923ad38d 100644
--- a/src/gallium/winsys/r600/drm/bof.c
+++ b/src/gallium/winsys/r600/drm/bof.c
@@ -46,7 +46,7 @@ static int bof_entry_grow(bof_t *bof)
}
/*
- * object
+ * object
*/
bof_t *bof_object(void)
{
diff --git a/src/gallium/winsys/r600/drm/evergreen_hw_context.c b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
index e1f163eab6..66398afa69 100644
--- a/src/gallium/winsys/r600/drm/evergreen_hw_context.c
+++ b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
@@ -36,7 +36,6 @@
#include "pipe/p_compiler.h"
#include "util/u_inlines.h"
#include "util/u_memory.h"
-#include <pipebuffer/pb_bufmgr.h>
#include "r600_priv.h"
#define GROUP_FORCE_NEW_BLOCK 0
@@ -622,10 +621,9 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon)
/* save 16dwords space for fence mecanism */
ctx->pm4_ndwords -= 16;
- r = r600_context_init_fence(ctx);
- if (r) {
- goto out_err;
- }
+ ctx->max_db = 8;
+
+ LIST_INITHEAD(&ctx->fenced_bo);
/* init dirty list */
LIST_INITHEAD(&ctx->dirty);
@@ -836,25 +834,25 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr
}
/* draw packet */
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_index_type;
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NUM_INSTANCES, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NUM_INSTANCES, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_instances;
if (draw->indices) {
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX, 3);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX, 3, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->indices_bo_offset + r600_bo_offset(draw->indices);
ctx->pm4[ctx->pm4_cdwords++] = 0;
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_indices;
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_draw_initiator;
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = 0;
r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], draw->indices);
} else {
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_indices;
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_draw_initiator;
}
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0);
/* flush color buffer */
@@ -881,59 +879,3 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr
ctx->pm4_dirty_cdwords = 0;
}
-static inline void evergreen_resource_set(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset)
-{
- struct r600_range *range;
- struct r600_block *block;
-
- range = &ctx->range[CTX_RANGE_ID(ctx, offset)];
- block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
- block->reg[0] = state->regs[0].value;
- block->reg[1] = state->regs[1].value;
- block->reg[2] = state->regs[2].value;
- block->reg[3] = state->regs[3].value;
- block->reg[4] = state->regs[4].value;
- block->reg[5] = state->regs[5].value;
- block->reg[6] = state->regs[6].value;
- block->reg[7] = state->regs[7].value;
- r600_bo_reference(ctx->radeon, &block->reloc[1].bo, NULL);
- r600_bo_reference(ctx->radeon , &block->reloc[2].bo, NULL);
- if (state->regs[0].bo) {
- /* VERTEX RESOURCE, we preted there is 2 bo to relocate so
- * we have single case btw VERTEX & TEXTURE resource
- */
- r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[0].bo);
- r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->regs[0].bo);
- } else {
- /* TEXTURE RESOURCE */
- r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[2].bo);
- r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->regs[3].bo);
- }
- if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
- block->status |= R600_BLOCK_STATUS_ENABLED;
- block->status |= R600_BLOCK_STATUS_DIRTY;
- ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords;
- LIST_ADDTAIL(&block->list,&ctx->dirty);
- }
-}
-
-void evergreen_ps_resource_set(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid)
-{
- unsigned offset = R_030000_RESOURCE0_WORD0 + 0x20 * rid;
-
- evergreen_resource_set(ctx, state, offset);
-}
-
-void evergreen_vs_resource_set(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid)
-{
- unsigned offset = R_030000_RESOURCE0_WORD0 + 0x1600 + 0x20 * rid;
-
- evergreen_resource_set(ctx, state, offset);
-}
-
-void evergreen_fs_resource_set(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid)
-{
- unsigned offset = R_030000_RESOURCE0_WORD0 + 0x7C00 + 0x20 * rid;
-
- evergreen_resource_set(ctx, state, offset);
-}
diff --git a/src/gallium/winsys/r600/drm/r600.c b/src/gallium/winsys/r600/drm/r600.c
deleted file mode 100644
index f5e53e21f5..0000000000
--- a/src/gallium/winsys/r600/drm/r600.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jerome Glisse
- */
-#include "xf86drm.h"
-#include "radeon_drm.h"
-#include "pipe/p_compiler.h"
-#include "util/u_inlines.h"
-#include <pipebuffer/pb_bufmgr.h>
-#include "r600_priv.h"
-
-enum radeon_family r600_get_family(struct radeon *r600)
-{
- return r600->family;
-}
-
-enum chip_class r600_get_family_class(struct radeon *radeon)
-{
- return radeon->chip_class;
-}
-
-struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon)
-{
- return &radeon->tiling_info;
-}
-
-static int r600_get_device(struct radeon *r600)
-{
- struct drm_radeon_info info;
-
- r600->device = 0;
- info.request = RADEON_INFO_DEVICE_ID;
- info.value = (uintptr_t)&r600->device;
- return drmCommandWriteRead(r600->fd, DRM_RADEON_INFO, &info, sizeof(struct drm_radeon_info));
-}
-
-struct radeon *r600_new(int fd, unsigned device)
-{
- struct radeon *r600;
- int r;
-
- r600 = calloc(1, sizeof(*r600));
- if (r600 == NULL) {
- return NULL;
- }
- r600->fd = fd;
- r600->device = device;
- if (fd >= 0) {
- r = r600_get_device(r600);
- if (r) {
- R600_ERR("Failed to get device id\n");
- r600_delete(r600);
- return NULL;
- }
- }
- r600->family = radeon_family_from_device(r600->device);
- if (r600->family == CHIP_UNKNOWN) {
- R600_ERR("Unknown chipset 0x%04X\n", r600->device);
- r600_delete(r600);
- return NULL;
- }
- switch (r600->family) {
- case CHIP_R600:
- case CHIP_RV610:
- case CHIP_RV630:
- case CHIP_RV670:
- case CHIP_RV620:
- case CHIP_RV635:
- case CHIP_RS780:
- case CHIP_RS880:
- case CHIP_RV770:
- case CHIP_RV730:
- case CHIP_RV710:
- case CHIP_RV740:
- case CHIP_CEDAR:
- case CHIP_REDWOOD:
- case CHIP_JUNIPER:
- case CHIP_CYPRESS:
- case CHIP_HEMLOCK:
- case CHIP_PALM:
- break;
- case CHIP_R100:
- case CHIP_RV100:
- case CHIP_RS100:
- case CHIP_RV200:
- case CHIP_RS200:
- case CHIP_R200:
- case CHIP_RV250:
- case CHIP_RS300:
- case CHIP_RV280:
- case CHIP_R300:
- case CHIP_R350:
- case CHIP_RV350:
- case CHIP_RV380:
- case CHIP_R420:
- case CHIP_R423:
- case CHIP_RV410:
- case CHIP_RS400:
- case CHIP_RS480:
- case CHIP_RS600:
- case CHIP_RS690:
- case CHIP_RS740:
- case CHIP_RV515:
- case CHIP_R520:
- case CHIP_RV530:
- case CHIP_RV560:
- case CHIP_RV570:
- case CHIP_R580:
- default:
- R600_ERR("unknown or unsupported chipset 0x%04X\n", r600->device);
- break;
- }
-
- /* setup class */
- switch (r600->family) {
- case CHIP_R600:
- case CHIP_RV610:
- case CHIP_RV630:
- case CHIP_RV670:
- case CHIP_RV620:
- case CHIP_RV635:
- case CHIP_RS780:
- case CHIP_RS880:
- r600->chip_class = R600;
- break;
- case CHIP_RV770:
- case CHIP_RV730:
- case CHIP_RV710:
- case CHIP_RV740:
- r600->chip_class = R700;
- break;
- case CHIP_CEDAR:
- case CHIP_REDWOOD:
- case CHIP_JUNIPER:
- case CHIP_CYPRESS:
- case CHIP_HEMLOCK:
- case CHIP_PALM:
- r600->chip_class = EVERGREEN;
- break;
- default:
- R600_ERR("unknown or unsupported chipset 0x%04X\n", r600->device);
- break;
- }
-
- return r600;
-}
-
-void r600_delete(struct radeon *r600)
-{
- if (r600 == NULL)
- return;
- drmClose(r600->fd);
- free(r600);
-}
diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c
index 251f009a6b..122a68884b 100644
--- a/src/gallium/winsys/r600/drm/r600_bo.c
+++ b/src/gallium/winsys/r600/drm/r600_bo.c
@@ -36,142 +36,152 @@ struct r600_bo *r600_bo(struct radeon *radeon,
unsigned size, unsigned alignment,
unsigned binding, unsigned usage)
{
- struct r600_bo *ws_bo = calloc(1, sizeof(struct r600_bo));
- struct pb_desc desc;
- struct pb_manager *man;
+ struct r600_bo *bo;
+ struct radeon_bo *rbo;
- desc.alignment = alignment;
- desc.usage = (PB_USAGE_CPU_READ_WRITE | PB_USAGE_GPU_READ_WRITE);
- ws_bo->size = size;
+ if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) {
+ bo = r600_bomgr_bo_create(radeon->bomgr, size, alignment, *radeon->cfence);
+ if (bo) {
+ return bo;
+ }
+ }
- if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
- man = radeon->cman;
- else
- man = radeon->kman;
+ rbo = radeon_bo(radeon, 0, size, alignment);
+ if (rbo == NULL) {
+ return NULL;
+ }
+
+ bo = calloc(1, sizeof(struct r600_bo));
+ bo->size = size;
+ bo->alignment = alignment;
+ bo->bo = rbo;
+ if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) {
+ r600_bomgr_bo_init(radeon->bomgr, bo);
+ }
/* Staging resources particpate in transfers and blits only
* and are used for uploads and downloads from regular
* resources. We generate them internally for some transfers.
*/
if (usage == PIPE_USAGE_STAGING)
- ws_bo->domains = RADEON_GEM_DOMAIN_CPU | RADEON_GEM_DOMAIN_GTT;
- else
- ws_bo->domains = (RADEON_GEM_DOMAIN_CPU |
- RADEON_GEM_DOMAIN_GTT |
- RADEON_GEM_DOMAIN_VRAM);
-
-
- ws_bo->pb = man->create_buffer(man, size, &desc);
- if (ws_bo->pb == NULL) {
- free(ws_bo);
- return NULL;
- }
+ bo->domains = RADEON_GEM_DOMAIN_CPU | RADEON_GEM_DOMAIN_GTT;
+ else
+ bo->domains = (RADEON_GEM_DOMAIN_CPU |
+ RADEON_GEM_DOMAIN_GTT |
+ RADEON_GEM_DOMAIN_VRAM);
- pipe_reference_init(&ws_bo->reference, 1);
- return ws_bo;
+ pipe_reference_init(&bo->reference, 1);
+ return bo;
}
struct r600_bo *r600_bo_handle(struct radeon *radeon,
unsigned handle, unsigned *array_mode)
{
- struct r600_bo *ws_bo = calloc(1, sizeof(struct r600_bo));
- struct radeon_bo *bo;
+ struct r600_bo *bo = calloc(1, sizeof(struct r600_bo));
+ struct radeon_bo *rbo;
- ws_bo->pb = radeon_bo_pb_create_buffer_from_handle(radeon->kman, handle);
- if (!ws_bo->pb) {
- free(ws_bo);
+ rbo = bo->bo = radeon_bo(radeon, handle, 0, 0);
+ if (rbo == NULL) {
+ free(bo);
return NULL;
}
- bo = radeon_bo_pb_get_bo(ws_bo->pb);
- ws_bo->size = bo->size;
- ws_bo->domains = (RADEON_GEM_DOMAIN_CPU |
- RADEON_GEM_DOMAIN_GTT |
- RADEON_GEM_DOMAIN_VRAM);
+ bo->size = rbo->size;
+ bo->domains = (RADEON_GEM_DOMAIN_CPU |
+ RADEON_GEM_DOMAIN_GTT |
+ RADEON_GEM_DOMAIN_VRAM);
- pipe_reference_init(&ws_bo->reference, 1);
+ pipe_reference_init(&bo->reference, 1);
- radeon_bo_get_tiling_flags(radeon, bo, &ws_bo->tiling_flags,
- &ws_bo->kernel_pitch);
+ radeon_bo_get_tiling_flags(radeon, rbo, &bo->tiling_flags, &bo->kernel_pitch);
if (array_mode) {
- if (ws_bo->tiling_flags) {
- if (ws_bo->tiling_flags & RADEON_TILING_MICRO)
- *array_mode = V_0280A0_ARRAY_1D_TILED_THIN1;
- if ((ws_bo->tiling_flags & (RADEON_TILING_MICRO | RADEON_TILING_MACRO)) ==
- (RADEON_TILING_MICRO | RADEON_TILING_MACRO))
+ if (bo->tiling_flags) {
+ if (bo->tiling_flags & RADEON_TILING_MACRO)
*array_mode = V_0280A0_ARRAY_2D_TILED_THIN1;
+ else if (bo->tiling_flags & RADEON_TILING_MICRO)
+ *array_mode = V_0280A0_ARRAY_1D_TILED_THIN1;
} else {
*array_mode = 0;
}
}
- return ws_bo;
+ return bo;
}
void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, void *ctx)
{
- return pb_map(bo->pb, usage, ctx);
+ struct pipe_context *pctx = ctx;
+
+ if (usage & PB_USAGE_UNSYNCHRONIZED) {
+ radeon_bo_map(radeon, bo->bo);
+ return (uint8_t *) bo->bo->data + bo->offset;
+ }
+
+ if (p_atomic_read(&bo->bo->reference.count) > 1) {
+ if (usage & PB_USAGE_DONTBLOCK) {
+ return NULL;
+ }
+ if (ctx) {
+ pctx->flush(pctx, NULL);
+ }
+ }
+
+ if (usage & PB_USAGE_DONTBLOCK) {
+ uint32_t domain;
+
+ if (radeon_bo_busy(radeon, bo->bo, &domain))
+ return NULL;
+ if (radeon_bo_map(radeon, bo->bo)) {
+ return NULL;
+ }
+ goto out;
+ }
+
+ radeon_bo_map(radeon, bo->bo);
+ if (radeon_bo_wait(radeon, bo->bo)) {
+ radeon_bo_unmap(radeon, bo->bo);
+ return NULL;
+ }
+
+out:
+ return (uint8_t *) bo->bo->data + bo->offset;
}
void r600_bo_unmap(struct radeon *radeon, struct r600_bo *bo)
{
- pb_unmap(bo->pb);
+ radeon_bo_unmap(radeon, bo->bo);
}
-static void r600_bo_destroy(struct radeon *radeon, struct r600_bo *bo)
+void r600_bo_destroy(struct radeon *radeon, struct r600_bo *bo)
{
- if (bo->pb)
- pb_reference(&bo->pb, NULL);
+ if (bo->manager_id) {
+ if (!r600_bomgr_bo_destroy(radeon->bomgr, bo)) {
+ /* destroy is delayed by buffer manager */
+ return;
+ }
+ }
+ radeon_bo_reference(radeon, &bo->bo, NULL);
free(bo);
}
-void r600_bo_reference(struct radeon *radeon, struct r600_bo **dst,
- struct r600_bo *src)
+void r600_bo_reference(struct radeon *radeon, struct r600_bo **dst, struct r600_bo *src)
{
struct r600_bo *old = *dst;
-
+
if (pipe_reference(&(*dst)->reference, &src->reference)) {
r600_bo_destroy(radeon, old);
}
*dst = src;
}
-unsigned r600_bo_get_handle(struct r600_bo *pb_bo)
-{
- struct radeon_bo *bo;
-
- bo = radeon_bo_pb_get_bo(pb_bo->pb);
- if (!bo)
- return 0;
-
- return bo->handle;
-}
-
-unsigned r600_bo_get_size(struct r600_bo *pb_bo)
-{
- struct radeon_bo *bo;
-
- bo = radeon_bo_pb_get_bo(pb_bo->pb);
- if (!bo)
- return 0;
-
- return bo->size;
-}
-
-boolean r600_bo_get_winsys_handle(struct radeon *radeon, struct r600_bo *pb_bo,
+boolean r600_bo_get_winsys_handle(struct radeon *radeon, struct r600_bo *bo,
unsigned stride, struct winsys_handle *whandle)
{
- struct radeon_bo *bo;
-
- bo = radeon_bo_pb_get_bo(pb_bo->pb);
- if (!bo)
- return FALSE;
-
whandle->stride = stride;
switch(whandle->type) {
case DRM_API_HANDLE_TYPE_KMS:
- whandle->handle = r600_bo_get_handle(pb_bo);
+ whandle->handle = r600_bo_get_handle(bo);
break;
case DRM_API_HANDLE_TYPE_SHARED:
- if (radeon_bo_get_name(radeon, bo, &whandle->handle))
+ if (radeon_bo_get_name(radeon, bo->bo, &whandle->handle))
return FALSE;
break;
default:
diff --git a/src/gallium/winsys/r600/drm/r600_bomgr.c b/src/gallium/winsys/r600/drm/r600_bomgr.c
new file mode 100644
index 0000000000..446ef0f9cf
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/r600_bomgr.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2010 VMWare.
+ * Copyright 2010 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jose Fonseca <jrfonseca-at-vmware-dot-com>
+ * Thomas Hellström <thomas-at-vmware-dot-com>
+ * Jerome Glisse <jglisse@redhat.com>
+ */
+#include <util/u_memory.h>
+#include <util/u_double_list.h>
+#include <util/u_time.h>
+#include <pipebuffer/pb_bufmgr.h>
+#include "r600_priv.h"
+
+static void r600_bomgr_timeout_flush(struct r600_bomgr *mgr)
+{
+ struct r600_bo *bo, *tmp;
+ int64_t now;
+
+ now = os_time_get();
+ LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &mgr->delayed, list) {
+ if(!os_time_timeout(bo->start, bo->end, now))
+ break;
+
+ mgr->num_delayed--;
+ bo->manager_id = 0;
+ LIST_DEL(&bo->list);
+ r600_bo_destroy(mgr->radeon, bo);
+ }
+}
+
+static INLINE int r600_bo_is_compat(struct r600_bomgr *mgr,
+ struct r600_bo *bo,
+ unsigned size,
+ unsigned alignment,
+ unsigned cfence)
+{
+ if(bo->size < size) {
+ return 0;
+ }
+
+ /* be lenient with size */
+ if(bo->size >= 2*size) {
+ return 0;
+ }
+
+ if(!pb_check_alignment(alignment, bo->alignment)) {
+ return 0;
+ }
+
+ if (!fence_is_after(cfence, bo->fence)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+struct r600_bo *r600_bomgr_bo_create(struct r600_bomgr *mgr,
+ unsigned size,
+ unsigned alignment,
+ unsigned cfence)
+{
+ struct r600_bo *bo, *tmp;
+ int64_t now;
+
+
+ pipe_mutex_lock(mgr->mutex);
+
+ now = os_time_get();
+ LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &mgr->delayed, list) {
+ if(r600_bo_is_compat(mgr, bo, size, alignment, cfence)) {
+ LIST_DEL(&bo->list);
+ --mgr->num_delayed;
+ r600_bomgr_timeout_flush(mgr);
+ pipe_mutex_unlock(mgr->mutex);
+ LIST_INITHEAD(&bo->list);
+ pipe_reference_init(&bo->reference, 1);
+ return bo;
+ }
+
+ if(os_time_timeout(bo->start, bo->end, now)) {
+ mgr->num_delayed--;
+ bo->manager_id = 0;
+ LIST_DEL(&bo->list);
+ r600_bo_destroy(mgr->radeon, bo);
+ }
+ }
+
+ pipe_mutex_unlock(mgr->mutex);
+ return NULL;
+}
+
+void r600_bomgr_bo_init(struct r600_bomgr *mgr, struct r600_bo *bo)
+{
+ LIST_INITHEAD(&bo->list);
+ bo->manager_id = 1;
+}
+
+bool r600_bomgr_bo_destroy(struct r600_bomgr *mgr, struct r600_bo *bo)
+{
+ bo->start = os_time_get();
+ bo->end = bo->start + mgr->usecs;
+ pipe_mutex_lock(mgr->mutex);
+ LIST_ADDTAIL(&bo->list, &mgr->delayed);
+ ++mgr->num_delayed;
+ pipe_mutex_unlock(mgr->mutex);
+ return FALSE;
+}
+
+void r600_bomgr_destroy(struct r600_bomgr *mgr)
+{
+ struct r600_bo *bo, *tmp;
+
+ pipe_mutex_lock(mgr->mutex);
+ LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &mgr->delayed, list) {
+ mgr->num_delayed--;
+ bo->manager_id = 0;
+ LIST_DEL(&bo->list);
+ r600_bo_destroy(mgr->radeon, bo);
+ }
+ pipe_mutex_unlock(mgr->mutex);
+
+ FREE(mgr);
+}
+
+struct r600_bomgr *r600_bomgr_create(struct radeon *radeon, unsigned usecs)
+{
+ struct r600_bomgr *mgr;
+
+ mgr = CALLOC_STRUCT(r600_bomgr);
+ if (mgr == NULL)
+ return NULL;
+
+ mgr->radeon = radeon;
+ mgr->usecs = usecs;
+ LIST_INITHEAD(&mgr->delayed);
+ mgr->num_delayed = 0;
+ pipe_mutex_init(mgr->mutex);
+
+ return mgr;
+}
diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c
index 8c847122f8..c081abb4dc 100644
--- a/src/gallium/winsys/r600/drm/r600_drm.c
+++ b/src/gallium/winsys/r600/drm/r600_drm.c
@@ -41,11 +41,48 @@
#define RADEON_INFO_TILING_CONFIG 0x6
#endif
-static struct radeon *radeon_new(int fd, unsigned device);
+#ifndef RADEON_INFO_CLOCK_CRYSTAL_FREQ
+#define RADEON_INFO_CLOCK_CRYSTAL_FREQ 0x9
+#endif
+
+#ifndef RADEON_INFO_NUM_BACKENDS
+#define RADEON_INFO_NUM_BACKENDS 0xa
+#endif
+
+enum radeon_family r600_get_family(struct radeon *r600)
+{
+ return r600->family;
+}
+
+enum chip_class r600_get_family_class(struct radeon *radeon)
+{
+ return radeon->chip_class;
+}
+
+struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon)
+{
+ return &radeon->tiling_info;
+}
+
+unsigned r600_get_clock_crystal_freq(struct radeon *radeon)
+{
+ return radeon->clock_crystal_freq;
+}
+
+unsigned r600_get_num_backends(struct radeon *radeon)
+{
+ return radeon->num_backends;
+}
+
+unsigned r600_get_minor_version(struct radeon *radeon)
+{
+ return radeon->minor_version;
+}
+
static int radeon_get_device(struct radeon *radeon)
{
- struct drm_radeon_info info;
+ struct drm_radeon_info info = {};
int r;
radeon->device = 0;
@@ -56,20 +93,8 @@ static int radeon_get_device(struct radeon *radeon)
return r;
}
-static int radeon_drm_get_tiling(struct radeon *radeon)
+static int r600_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
{
- struct drm_radeon_info info;
- int r;
- uint32_t tiling_config;
-
- info.request = RADEON_INFO_TILING_CONFIG;
- info.value = (uintptr_t)&tiling_config;
- r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
- sizeof(struct drm_radeon_info));
-
- if (r)
- return 0;
-
switch ((tiling_config & 0xe) >> 1) {
case 0:
radeon->tiling_info.num_channels = 1;
@@ -111,10 +136,117 @@ static int radeon_drm_get_tiling(struct radeon *radeon)
return 0;
}
+static int eg_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
+{
+ switch (tiling_config & 0xf) {
+ case 0:
+ radeon->tiling_info.num_channels = 1;
+ break;
+ case 1:
+ radeon->tiling_info.num_channels = 2;
+ break;
+ case 2:
+ radeon->tiling_info.num_channels = 4;
+ break;
+ case 3:
+ radeon->tiling_info.num_channels = 8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ radeon->tiling_info.num_banks = (tiling_config & 0xf0) >> 4;
+
+ switch ((tiling_config & 0xf00) >> 8) {
+ case 0:
+ radeon->tiling_info.group_bytes = 256;
+ break;
+ case 1:
+ radeon->tiling_info.group_bytes = 512;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int radeon_drm_get_tiling(struct radeon *radeon)
+{
+ struct drm_radeon_info info;
+ int r;
+ uint32_t tiling_config = 0;
+
+ info.request = RADEON_INFO_TILING_CONFIG;
+ info.value = (uintptr_t)&tiling_config;
+ r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
+ sizeof(struct drm_radeon_info));
+
+ if (r)
+ return 0;
+
+ if (radeon->chip_class == R600 || radeon->chip_class == R700) {
+ r = r600_interpret_tiling(radeon, tiling_config);
+ } else {
+ r = eg_interpret_tiling(radeon, tiling_config);
+ }
+ return r;
+}
+
+static int radeon_get_clock_crystal_freq(struct radeon *radeon)
+{
+ struct drm_radeon_info info;
+ uint32_t clock_crystal_freq;
+ int r;
+
+ radeon->device = 0;
+ info.request = RADEON_INFO_CLOCK_CRYSTAL_FREQ;
+ info.value = (uintptr_t)&clock_crystal_freq;
+ r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
+ sizeof(struct drm_radeon_info));
+ if (r)
+ return r;
+
+ radeon->clock_crystal_freq = clock_crystal_freq;
+ return 0;
+}
+
+
+static int radeon_get_num_backends(struct radeon *radeon)
+{
+ struct drm_radeon_info info;
+ uint32_t num_backends;
+ int r;
+
+ radeon->device = 0;
+ info.request = RADEON_INFO_NUM_BACKENDS;
+ info.value = (uintptr_t)&num_backends;
+ r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
+ sizeof(struct drm_radeon_info));
+ if (r)
+ return r;
+
+ radeon->num_backends = num_backends;
+ return 0;
+}
+
+
+static int radeon_init_fence(struct radeon *radeon)
+{
+ radeon->fence = 1;
+ radeon->fence_bo = r600_bo(radeon, 4096, 0, 0, 0);
+ if (radeon->fence_bo == NULL) {
+ return -ENOMEM;
+ }
+ radeon->cfence = r600_bo_map(radeon, radeon->fence_bo, PB_USAGE_UNSYNCHRONIZED, NULL);
+ *radeon->cfence = 0;
+ return 0;
+}
+
static struct radeon *radeon_new(int fd, unsigned device)
{
struct radeon *radeon;
int r;
+ drmVersionPtr version;
radeon = calloc(1, sizeof(*radeon));
if (radeon == NULL) {
@@ -123,71 +255,32 @@ static struct radeon *radeon_new(int fd, unsigned device)
radeon->fd = fd;
radeon->device = device;
radeon->refcount = 1;
- if (fd >= 0) {
- r = radeon_get_device(radeon);
- if (r) {
- fprintf(stderr, "Failed to get device id\n");
- return radeon_decref(radeon);
- }
+
+ version = drmGetVersion(radeon->fd);
+ if (version->version_major != 2) {
+ fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
+ "only compatible with 2.x.x\n", __FUNCTION__,
+ version->version_major, version->version_minor,
+ version->version_patchlevel);
+ drmFreeVersion(version);
+ exit(1);
+ }
+
+ radeon->minor_version = version->version_minor;
+
+ drmFreeVersion(version);
+
+ r = radeon_get_device(radeon);
+ if (r) {
+ fprintf(stderr, "Failed to get device id\n");
+ return radeon_decref(radeon);
}
+
radeon->family = radeon_family_from_device(radeon->device);
if (radeon->family == CHIP_UNKNOWN) {
fprintf(stderr, "Unknown chipset 0x%04X\n", radeon->device);
return radeon_decref(radeon);
}
- switch (radeon->family) {
- case CHIP_R600:
- case CHIP_RV610:
- case CHIP_RV630:
- case CHIP_RV670:
- case CHIP_RV620:
- case CHIP_RV635:
- case CHIP_RS780:
- case CHIP_RS880:
- case CHIP_RV770:
- case CHIP_RV730:
- case CHIP_RV710:
- case CHIP_RV740:
- case CHIP_CEDAR:
- case CHIP_REDWOOD:
- case CHIP_JUNIPER:
- case CHIP_CYPRESS:
- case CHIP_HEMLOCK:
- case CHIP_PALM:
- break;
- case CHIP_R100:
- case CHIP_RV100:
- case CHIP_RS100:
- case CHIP_RV200:
- case CHIP_RS200:
- case CHIP_R200:
- case CHIP_RV250:
- case CHIP_RS300:
- case CHIP_RV280:
- case CHIP_R300:
- case CHIP_R350:
- case CHIP_RV350:
- case CHIP_RV380:
- case CHIP_R420:
- case CHIP_R423:
- case CHIP_RV410:
- case CHIP_RS400:
- case CHIP_RS480:
- case CHIP_RS600:
- case CHIP_RS690:
- case CHIP_RS740:
- case CHIP_RV515:
- case CHIP_R520:
- case CHIP_RV530:
- case CHIP_RV560:
- case CHIP_RV570:
- case CHIP_R580:
- default:
- fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
- __func__, radeon->device);
- break;
- }
-
/* setup class */
switch (radeon->family) {
case CHIP_R600:
@@ -216,6 +309,9 @@ static struct radeon *radeon_new(int fd, unsigned device)
case CHIP_CYPRESS:
case CHIP_HEMLOCK:
case CHIP_PALM:
+ case CHIP_BARTS:
+ case CHIP_TURKS:
+ case CHIP_CAICOS:
radeon->chip_class = EVERGREEN;
/* set default group bytes, overridden by tiling info ioctl */
radeon->tiling_info.group_bytes = 512;
@@ -226,16 +322,24 @@ static struct radeon *radeon_new(int fd, unsigned device)
break;
}
- if (radeon->chip_class == R600 || radeon->chip_class == R700) {
- if (radeon_drm_get_tiling(radeon))
- return NULL;
- }
- radeon->kman = radeon_bo_pbmgr_create(radeon);
- if (!radeon->kman)
+ if (radeon_drm_get_tiling(radeon))
return NULL;
- radeon->cman = pb_cache_manager_create(radeon->kman, 1000000);
- if (!radeon->cman)
+
+ /* get the GPU counter frequency, failure is non fatal */
+ radeon_get_clock_crystal_freq(radeon);
+
+ if (radeon->minor_version >= 9)
+ radeon_get_num_backends(radeon);
+
+ radeon->bomgr = r600_bomgr_create(radeon, 1000000);
+ if (radeon->bomgr == NULL) {
return NULL;
+ }
+ r = radeon_init_fence(radeon);
+ if (r) {
+ radeon_decref(radeon);
+ return NULL;
+ }
return radeon;
}
@@ -252,14 +356,12 @@ struct radeon *radeon_decref(struct radeon *radeon)
return NULL;
}
- if (radeon->cman)
- radeon->cman->destroy(radeon->cman);
-
- if (radeon->kman)
- radeon->kman->destroy(radeon->kman);
+ if (radeon->fence_bo) {
+ r600_bo_reference(radeon, &radeon->fence_bo, NULL);
+ }
- if (radeon->fd >= 0)
- drmClose(radeon->fd);
+ if (radeon->bomgr)
+ r600_bomgr_destroy(radeon->bomgr);
free(radeon);
return NULL;
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c
index 0f2724f61c..a7c21784e5 100644
--- a/src/gallium/winsys/r600/drm/r600_hw_context.c
+++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
@@ -28,39 +28,25 @@
#include <string.h>
#include <stdlib.h>
#include <assert.h>
+#include <pipe/p_compiler.h>
+#include <util/u_inlines.h>
+#include <util/u_memory.h>
+#include <pipebuffer/pb_bufmgr.h>
#include "xf86drm.h"
-#include "r600.h"
-#include "r600d.h"
#include "radeon_drm.h"
-#include "bof.h"
-#include "pipe/p_compiler.h"
-#include "util/u_inlines.h"
-#include "util/u_memory.h"
-#include <pipebuffer/pb_bufmgr.h>
#include "r600_priv.h"
+#include "bof.h"
+#include "r600d.h"
#define GROUP_FORCE_NEW_BLOCK 0
-int r600_context_init_fence(struct r600_context *ctx)
-{
- ctx->fence = 1;
- ctx->fence_bo = r600_bo(ctx->radeon, 4096, 0, 0, 0);
- if (ctx->fence_bo == NULL) {
- return -ENOMEM;
- }
- ctx->cfence = r600_bo_map(ctx->radeon, ctx->fence_bo, PB_USAGE_UNSYNCHRONIZED, NULL);
- *ctx->cfence = 0;
- LIST_INITHEAD(&ctx->fenced_bo);
- return 0;
-}
-
static void INLINE r600_context_update_fenced_list(struct r600_context *ctx)
{
for (int i = 0; i < ctx->creloc; i++) {
if (!LIST_IS_EMPTY(&ctx->bo[i]->fencedlist))
LIST_DELINIT(&ctx->bo[i]->fencedlist);
LIST_ADDTAIL(&ctx->bo[i]->fencedlist, &ctx->fenced_bo);
- ctx->bo[i]->fence = ctx->fence;
+ ctx->bo[i]->fence = ctx->radeon->fence;
ctx->bo[i]->ctx = ctx;
}
}
@@ -71,7 +57,7 @@ static void INLINE r600_context_fence_wraparound(struct r600_context *ctx, unsig
struct radeon_bo *tmp;
LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &ctx->fenced_bo, fencedlist) {
- if (bo->fence <= *ctx->cfence) {
+ if (bo->fence <= *ctx->radeon->cfence) {
LIST_DELINIT(&bo->fencedlist);
bo->fence = 0;
} else {
@@ -121,7 +107,7 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg,
/* initialize block */
block->start_offset = reg[i].offset;
- block->pm4[block->pm4_ndwords++] = PKT3(reg[i].opcode, n);
+ block->pm4[block->pm4_ndwords++] = PKT3(reg[i].opcode, n, 0);
block->pm4[block->pm4_ndwords++] = (block->start_offset - reg[i].offset_base) >> 2;
block->reg = &block->pm4[block->pm4_ndwords];
block->pm4_ndwords += n;
@@ -133,7 +119,7 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg,
block->nbo++;
assert(block->nbo < R600_BLOCK_MAX_BO);
block->pm4_bo_index[j] = block->nbo;
- block->pm4[block->pm4_ndwords++] = PKT3(PKT3_NOP, 0);
+ block->pm4[block->pm4_ndwords++] = PKT3(PKT3_NOP, 0, 0);
block->pm4[block->pm4_ndwords++] = 0x00000000;
block->reloc[block->nbo].flush_flags = reg[i+j].flush_flags;
block->reloc[block->nbo].flush_mask = reg[i+j].flush_mask;
@@ -632,9 +618,6 @@ void r600_context_fini(struct r600_context *ctx)
free(ctx->pm4);
r600_context_clear_fenced_bo(ctx);
- if (ctx->fence_bo) {
- r600_bo_reference(ctx->radeon, &ctx->fence_bo, NULL);
- }
memset(ctx, 0, sizeof(struct r600_context));
}
@@ -654,7 +637,8 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon)
ctx->range[i].end_offset = ((i + 1) << ctx->hash_shift) - 1;
ctx->range[i].blocks = calloc(1 << ctx->hash_shift, sizeof(void*));
if (ctx->range[i].blocks == NULL) {
- return -ENOMEM;
+ r = -ENOMEM;
+ goto out_err;
}
}
@@ -763,19 +747,30 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon)
/* save 16dwords space for fence mecanism */
ctx->pm4_ndwords -= 16;
- r = r600_context_init_fence(ctx);
- if (r) {
- goto out_err;
- }
+ LIST_INITHEAD(&ctx->fenced_bo);
/* init dirty list */
LIST_INITHEAD(&ctx->dirty);
+
+ ctx->max_db = 4;
+
return 0;
out_err:
r600_context_fini(ctx);
return r;
}
+static void rv6xx_context_surface_base_update(struct r600_context *ctx,
+ unsigned base_update_flags)
+{
+ /* need to emit surface base update on rv6xx */
+ if ((ctx->radeon->family > CHIP_R600) &&
+ (ctx->radeon->family < CHIP_RV770)) {
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = base_update_flags;
+ }
+}
+
void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags,
unsigned flush_mask, struct r600_bo *rbo)
{
@@ -787,12 +782,12 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags,
bo->last_flush &= flush_mask;
return;
}
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_SYNC, 3);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_SYNC, 3, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = flush_flags;
ctx->pm4[ctx->pm4_cdwords++] = (bo->size + 255) >> 8;
ctx->pm4[ctx->pm4_cdwords++] = 0x00000000;
ctx->pm4[ctx->pm4_cdwords++] = 0x0000000A;
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = bo->reloc_id;
bo->last_flush = (bo->last_flush | flush_flags) & flush_mask;
}
@@ -814,6 +809,7 @@ void r600_context_bo_reloc(struct r600_context *ctx, u32 *pm4, struct r600_bo *r
ctx->reloc[ctx->creloc].write_domain = rbo->domains & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM);
ctx->reloc[ctx->creloc].flags = 0;
radeon_bo_reference(ctx->radeon, &ctx->bo[ctx->creloc], bo);
+ rbo->fence = ctx->radeon->fence;
ctx->creloc++;
/* set PKT3 to point to proper reloc */
*pm4 = bo->reloc_id;
@@ -836,6 +832,7 @@ void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_stat
/* find relocation */
id = block->pm4_bo_index[id];
r600_bo_reference(ctx->radeon, &block->reloc[id].bo, state->regs[i].bo);
+ state->regs[i].bo->fence = ctx->radeon->fence;
}
if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
block->status |= R600_BLOCK_STATUS_ENABLED;
@@ -875,10 +872,13 @@ static inline void r600_context_pipe_state_set_resource(struct r600_context *ctx
*/
r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[0].bo);
r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->regs[0].bo);
+ state->regs[0].bo->fence = ctx->radeon->fence;
} else {
/* TEXTURE RESOURCE */
r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[2].bo);
r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->regs[3].bo);
+ state->regs[2].bo->fence = ctx->radeon->fence;
+ state->regs[3].bo->fence = ctx->radeon->fence;
}
if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
block->status |= R600_BLOCK_STATUS_ENABLED;
@@ -1002,6 +1002,7 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw)
unsigned ndwords = 9;
struct r600_block *dirty_block = NULL;
struct r600_block *next_block;
+ unsigned rv6xx_surface_base_update = 0;
if (draw->indices) {
ndwords = 13;
@@ -1024,10 +1025,14 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw)
for (int i = 0; i < 8; i++) {
if (cb[i]) {
ndwords += 7;
+ rv6xx_surface_base_update |= SURFACE_BASE_UPDATE_COLOR(i);
}
}
- if (db)
+ if (db) {
ndwords += 7;
+ rv6xx_surface_base_update |= SURFACE_BASE_UPDATE_DEPTH;
+ }
+ /* XXX also need to update SURFACE_BASE_UPDATE_STRMOUT when we support it */
/* queries need some special values */
if (ctx->num_query_running) {
@@ -1054,30 +1059,34 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw)
}
/* enough room to copy packet */
- LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &ctx->dirty,list) {
+ LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &ctx->dirty, list) {
r600_context_block_emit_dirty(ctx, dirty_block);
}
+ /* rv6xx surface base udpate */
+ if (rv6xx_surface_base_update)
+ rv6xx_context_surface_base_update(ctx, rv6xx_surface_base_update);
+
/* draw packet */
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_index_type;
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NUM_INSTANCES, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NUM_INSTANCES, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_instances;
if (draw->indices) {
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX, 3);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX, 3, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->indices_bo_offset + r600_bo_offset(draw->indices);
ctx->pm4[ctx->pm4_cdwords++] = 0;
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_indices;
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_draw_initiator;
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = 0;
r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], draw->indices);
} else {
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_indices;
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_draw_initiator;
}
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0);
/* flush color buffer */
@@ -1099,7 +1108,7 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw)
void r600_context_flush(struct r600_context *ctx)
{
- struct drm_radeon_cs drmib;
+ struct drm_radeon_cs drmib = {};
struct drm_radeon_cs_chunk chunks[2];
uint64_t chunk_array[2];
unsigned fence;
@@ -1112,17 +1121,17 @@ void r600_context_flush(struct r600_context *ctx)
r600_context_queries_suspend(ctx);
/* emit fence */
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4);
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0);
ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
ctx->pm4[ctx->pm4_cdwords++] = 0;
ctx->pm4[ctx->pm4_cdwords++] = (1 << 29) | (0 << 24);
- ctx->pm4[ctx->pm4_cdwords++] = ctx->fence;
+ ctx->pm4[ctx->pm4_cdwords++] = ctx->radeon->fence;
ctx->pm4[ctx->pm4_cdwords++] = 0;
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, 0);
ctx->pm4[ctx->pm4_cdwords++] = 0;
- r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], ctx->fence_bo);
+ r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], ctx->radeon->fence_bo);
#if 1
/* emit cs */
@@ -1139,18 +1148,18 @@ void r600_context_flush(struct r600_context *ctx)
r = drmCommandWriteRead(ctx->radeon->fd, DRM_RADEON_CS, &drmib,
sizeof(struct drm_radeon_cs));
#else
- *ctx->cfence = ctx->fence;
+ *ctx->radeon->cfence = ctx->radeon->fence;
#endif
r600_context_update_fenced_list(ctx);
- fence = ctx->fence + 1;
- if (fence < ctx->fence) {
+ fence = ctx->radeon->fence + 1;
+ if (fence < ctx->radeon->fence) {
/* wrap around */
fence = 1;
r600_context_fence_wraparound(ctx, fence);
}
- ctx->fence = fence;
+ ctx->radeon->fence = fence;
/* restart */
for (int i = 0; i < ctx->creloc; i++) {
@@ -1261,44 +1270,90 @@ out_err:
bof_decref(root);
}
-static void r600_query_result(struct r600_context *ctx, struct r600_query *query)
+static boolean r600_query_result(struct r600_context *ctx, struct r600_query *query, boolean wait)
{
u64 start, end;
u32 *results;
int i;
+ int size;
+
+ if (wait)
+ results = r600_bo_map(ctx->radeon, query->buffer, PB_USAGE_CPU_READ, NULL);
+ else
+ results = r600_bo_map(ctx->radeon, query->buffer, PB_USAGE_DONTBLOCK | PB_USAGE_CPU_READ, NULL);
+ if (!results)
+ return FALSE;
- results = r600_bo_map(ctx->radeon, query->buffer, 0, NULL);
- for (i = 0; i < query->num_results; i += 4) {
+ size = query->num_results * (query->type == PIPE_QUERY_OCCLUSION_COUNTER ? ctx->max_db : 1);
+ for (i = 0; i < size; i += 4) {
start = (u64)results[i] | (u64)results[i + 1] << 32;
end = (u64)results[i + 2] | (u64)results[i + 3] << 32;
- if ((start & 0x8000000000000000UL) && (end & 0x8000000000000000UL)) {
+ if (((start & 0x8000000000000000UL) && (end & 0x8000000000000000UL))
+ || query->type == PIPE_QUERY_TIME_ELAPSED) {
query->result += end - start;
}
}
r600_bo_unmap(ctx->radeon, query->buffer);
query->num_results = 0;
+
+ return TRUE;
}
void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
{
- /* query request needs 6 dwords for begin + 6 dwords for end */
- if ((12 + ctx->pm4_cdwords) > ctx->pm4_ndwords) {
+ unsigned required_space;
+ int num_backends = r600_get_num_backends(ctx->radeon);
+
+ /* query request needs 6/8 dwords for begin + 6/8 dwords for end */
+ if (query->type == PIPE_QUERY_TIME_ELAPSED)
+ required_space = 16;
+ else
+ required_space = 12;
+
+ if ((required_space + ctx->pm4_cdwords) > ctx->pm4_ndwords) {
/* need to flush */
r600_context_flush(ctx);
}
/* if query buffer is full force a flush */
- if (query->num_results >= ((query->buffer_size >> 2) - 2)) {
+ if (query->num_results*4 >= query->buffer_size - 16) {
r600_context_flush(ctx);
- r600_query_result(ctx, query);
+ r600_query_result(ctx, query, TRUE);
}
+ if (query->type == PIPE_QUERY_OCCLUSION_COUNTER &&
+ num_backends > 0 && num_backends < ctx->max_db) {
+ /* as per info on ZPASS the driver must set the unusued DB top bits */
+ u32 *results;
+ int i;
+
+ results = r600_bo_map(ctx->radeon, query->buffer, PB_USAGE_DONTBLOCK | PB_USAGE_CPU_WRITE, NULL);
+ if (results) {
+ memset(results + (query->num_results * 4), 0, ctx->max_db * 4 * 4);
+
+ for (i = num_backends; i < ctx->max_db; i++) {
+ results[(i * 4)+1] = 0x80000000;
+ results[(i * 4)+3] = 0x80000000;
+ }
+ r600_bo_unmap(ctx->radeon, query->buffer);
+ }
+ }
+
/* emit begin query */
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2);
- ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
- ctx->pm4[ctx->pm4_cdwords++] = query->num_results + r600_bo_offset(query->buffer);
- ctx->pm4[ctx->pm4_cdwords++] = 0;
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0);
+ if (query->type == PIPE_QUERY_TIME_ELAPSED) {
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
+ ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + r600_bo_offset(query->buffer);
+ ctx->pm4[ctx->pm4_cdwords++] = (3 << 29);
+ ctx->pm4[ctx->pm4_cdwords++] = 0;
+ ctx->pm4[ctx->pm4_cdwords++] = 0;
+ } else {
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
+ ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + r600_bo_offset(query->buffer);
+ ctx->pm4[ctx->pm4_cdwords++] = 0;
+ }
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, 0);
ctx->pm4[ctx->pm4_cdwords++] = 0;
r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], query->buffer);
@@ -1310,25 +1365,56 @@ void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
void r600_query_end(struct r600_context *ctx, struct r600_query *query)
{
/* emit begin query */
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2);
- ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
- ctx->pm4[ctx->pm4_cdwords++] = query->num_results + 8 + r600_bo_offset(query->buffer);
- ctx->pm4[ctx->pm4_cdwords++] = 0;
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0);
+ if (query->type == PIPE_QUERY_TIME_ELAPSED) {
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
+ ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + 8 + r600_bo_offset(query->buffer);
+ ctx->pm4[ctx->pm4_cdwords++] = (3 << 29);
+ ctx->pm4[ctx->pm4_cdwords++] = 0;
+ ctx->pm4[ctx->pm4_cdwords++] = 0;
+ } else {
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
+ ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + 8 + r600_bo_offset(query->buffer);
+ ctx->pm4[ctx->pm4_cdwords++] = 0;
+ }
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, 0);
ctx->pm4[ctx->pm4_cdwords++] = 0;
r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], query->buffer);
- query->num_results += 16;
+ query->num_results += 4 * (query->type == PIPE_QUERY_OCCLUSION_COUNTER ? ctx->max_db : 1);
query->state ^= R600_QUERY_STATE_STARTED;
query->state |= R600_QUERY_STATE_ENDED;
ctx->num_query_running--;
}
+void r600_query_predication(struct r600_context *ctx, struct r600_query *query, int operation,
+ int flag_wait)
+{
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SET_PREDICATION, 1, 0);
+
+ if (operation == PREDICATION_OP_CLEAR) {
+ ctx->pm4[ctx->pm4_cdwords++] = 0;
+ ctx->pm4[ctx->pm4_cdwords++] = PRED_OP(PREDICATION_OP_CLEAR);
+ } else {
+ int results_base = query->num_results - (4 * ctx->max_db);
+
+ if (results_base < 0)
+ results_base = 0;
+
+ ctx->pm4[ctx->pm4_cdwords++] = results_base*4 + r600_bo_offset(query->buffer);
+ ctx->pm4[ctx->pm4_cdwords++] = PRED_OP(operation) | (flag_wait ? PREDICATION_HINT_WAIT : PREDICATION_HINT_NOWAIT_DRAW) | PREDICATION_DRAW_VISIBLE;
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = 0;
+ r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], query->buffer);
+ }
+}
+
struct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned query_type)
{
struct r600_query *query;
- if (query_type != PIPE_QUERY_OCCLUSION_COUNTER)
+ if (query_type != PIPE_QUERY_OCCLUSION_COUNTER && query_type != PIPE_QUERY_TIME_ELAPSED)
return NULL;
query = calloc(1, sizeof(struct r600_query));
@@ -1370,8 +1456,12 @@ boolean r600_context_query_result(struct r600_context *ctx,
if (query->num_results) {
r600_context_flush(ctx);
}
- r600_query_result(ctx, query);
- *result = query->result;
+ if (!r600_query_result(ctx, query, wait))
+ return FALSE;
+ if (query->type == PIPE_QUERY_TIME_ELAPSED)
+ *result = (1000000*query->result)/r600_get_clock_crystal_freq(ctx->radeon);
+ else
+ *result = query->result;
query->result = 0;
return TRUE;
}
diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h
index 193af984f8..41c5ee02c3 100644
--- a/src/gallium/winsys/r600/drm/r600_priv.h
+++ b/src/gallium/winsys/r600/drm/r600_priv.h
@@ -30,24 +30,30 @@
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
-#include <pipebuffer/pb_bufmgr.h>
-#include "util/u_double_list.h"
+#include <util/u_double_list.h>
+#include <util/u_inlines.h>
+#include <os/os_thread.h>
#include "r600.h"
+struct r600_bomgr;
+struct r600_bo;
+
struct radeon {
int fd;
int refcount;
unsigned device;
unsigned family;
enum chip_class chip_class;
- struct pb_manager *kman; /* kernel bo manager */
- struct pb_manager *cman; /* cached bo manager */
- struct r600_tiling_info tiling_info;
+ struct r600_tiling_info tiling_info;
+ struct r600_bomgr *bomgr;
+ unsigned fence;
+ unsigned *cfence;
+ struct r600_bo *fence_bo;
+ unsigned clock_crystal_freq;
+ unsigned num_backends;
+ unsigned minor_version;
};
-struct radeon *r600_new(int fd, unsigned device);
-void r600_delete(struct radeon *r600);
-
struct r600_reg {
unsigned opcode;
unsigned offset_base;
@@ -75,25 +81,49 @@ struct radeon_bo {
struct r600_bo {
struct pipe_reference reference;
- struct pb_buffer *pb;
unsigned size;
unsigned tiling_flags;
unsigned kernel_pitch;
unsigned domains;
+ struct radeon_bo *bo;
+ unsigned fence;
+ /* manager data */
+ struct list_head list;
+ unsigned manager_id;
+ unsigned alignment;
+ unsigned offset;
+ int64_t start;
+ int64_t end;
};
+struct r600_bomgr {
+ struct radeon *radeon;
+ unsigned usecs;
+ pipe_mutex mutex;
+ struct list_head delayed;
+ unsigned num_delayed;
+};
-/* radeon_pciid.c */
+/*
+ * r600_drm.c
+ */
+struct radeon *r600_new(int fd, unsigned device);
+void r600_delete(struct radeon *r600);
+
+/*
+ * radeon_pciid.c
+ */
unsigned radeon_family_from_device(unsigned device);
-/* radeon_bo.c */
+/*
+ * radeon_bo.c
+ */
struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
unsigned size, unsigned alignment);
void radeon_bo_reference(struct radeon *radeon, struct radeon_bo **dst,
struct radeon_bo *src);
int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo);
int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain);
-void radeon_bo_pbmgr_flush_maps(struct pb_manager *_mgr);
int radeon_bo_fencelist(struct radeon *radeon, struct radeon_bo **bolist, uint32_t num_bo);
int radeon_bo_get_tiling_flags(struct radeon *radeon,
struct radeon_bo *bo,
@@ -103,13 +133,9 @@ int radeon_bo_get_name(struct radeon *radeon,
struct radeon_bo *bo,
uint32_t *name);
-/* radeon_bo_pb.c */
-struct radeon_bo *radeon_bo_pb_get_bo(struct pb_buffer *_buf);
-struct pb_manager *radeon_bo_pbmgr_create(struct radeon *radeon);
-struct pb_buffer *radeon_bo_pb_create_buffer_from_handle(struct pb_manager *_mgr,
- uint32_t handle);
-
-/* r600_hw_context.c */
+/*
+ * r600_hw_context.c
+ */
int r600_context_init_fence(struct r600_context *ctx);
void r600_context_bo_reloc(struct r600_context *ctx, u32 *pm4, struct r600_bo *rbo);
void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags,
@@ -117,14 +143,27 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags,
struct r600_bo *r600_context_reg_bo(struct r600_context *ctx, unsigned offset);
int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, unsigned nreg);
-/* r600_bo.c */
-unsigned r600_bo_get_handle(struct r600_bo *bo);
-unsigned r600_bo_get_size(struct r600_bo *bo);
-static INLINE struct radeon_bo *r600_bo_get_bo(struct r600_bo *bo)
-{
- return radeon_bo_pb_get_bo(bo->pb);
-}
+/*
+ * r600_bo.c
+ */
+void r600_bo_destroy(struct radeon *radeon, struct r600_bo *bo);
+/*
+ * r600_bomgr.c
+ */
+struct r600_bomgr *r600_bomgr_create(struct radeon *radeon, unsigned usecs);
+void r600_bomgr_destroy(struct r600_bomgr *mgr);
+bool r600_bomgr_bo_destroy(struct r600_bomgr *mgr, struct r600_bo *bo);
+void r600_bomgr_bo_init(struct r600_bomgr *mgr, struct r600_bo *bo);
+struct r600_bo *r600_bomgr_bo_create(struct r600_bomgr *mgr,
+ unsigned size,
+ unsigned alignment,
+ unsigned cfence);
+
+
+/*
+ * helpers
+ */
#define CTX_RANGE_ID(ctx, offset) (((offset) >> (ctx)->hash_shift) & 255)
#define CTX_BLOCK_ID(ctx, offset) ((offset) & ((1 << (ctx)->hash_shift) - 1))
@@ -172,6 +211,9 @@ static inline void r600_context_block_emit_dirty(struct r600_context *ctx, struc
LIST_DELINIT(&block->list);
}
+/*
+ * radeon_bo.c
+ */
static inline int radeon_bo_map(struct radeon *radeon, struct radeon_bo *bo)
{
bo->map_count++;
@@ -184,4 +226,35 @@ static inline void radeon_bo_unmap(struct radeon *radeon, struct radeon_bo *bo)
assert(bo->map_count >= 0);
}
+/*
+ * r600_bo
+ */
+static inline struct radeon_bo *r600_bo_get_bo(struct r600_bo *bo)
+{
+ return bo->bo;
+}
+
+static unsigned inline r600_bo_get_handle(struct r600_bo *bo)
+{
+ return bo->bo->handle;
+}
+
+static unsigned inline r600_bo_get_size(struct r600_bo *bo)
+{
+ return bo->size;
+}
+
+/*
+ * fence
+ */
+static inline bool fence_is_after(unsigned fence, unsigned ofence)
+{
+ /* handle wrap around */
+ if (fence < 0x80000000 && ofence > 0x80000000)
+ return TRUE;
+ if (fence > ofence)
+ return TRUE;
+ return FALSE;
+}
+
#endif
diff --git a/src/gallium/winsys/r600/drm/r600d.h b/src/gallium/winsys/r600/drm/r600d.h
index 1c1ac76fe6..8042481804 100644
--- a/src/gallium/winsys/r600/drm/r600d.h
+++ b/src/gallium/winsys/r600/drm/r600d.h
@@ -90,6 +90,9 @@
#define PKT3_SET_SAMPLER 0x6E
#define PKT3_SET_CTL_CONST 0x6F
#define PKT3_SURFACE_BASE_UPDATE 0x73
+#define SURFACE_BASE_UPDATE_DEPTH (1 << 0)
+#define SURFACE_BASE_UPDATE_COLOR(x) (2 << (x))
+#define SURFACE_BASE_UPDATE_STRMOUT(x) (0x200 << (x))
#define EVENT_TYPE_PS_PARTIAL_FLUSH 0x10
#define EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT 0x14
@@ -105,6 +108,18 @@
* 5 - TS events
*/
+#define PREDICATION_OP_CLEAR 0x0
+#define PREDICATION_OP_ZPASS 0x1
+#define PREDICATION_OP_PRIMCOUNT 0x2
+
+#define PRED_OP(x) ((x) << 16)
+
+#define PREDICATION_HINT_WAIT (0 << 12)
+#define PREDICATION_HINT_NOWAIT_DRAW (1 << 12)
+
+#define PREDICATION_DRAW_NOT_VISIBLE (0 << 8)
+#define PREDICATION_DRAW_VISIBLE (1 << 8)
+
#define PKT_TYPE_S(x) (((x) & 0x3) << 30)
#define PKT_TYPE_G(x) (((x) >> 30) & 0x3)
#define PKT_TYPE_C 0x3FFFFFFF
@@ -117,8 +132,9 @@
#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 PKT3_PRED_S(x) (((x) >> 0) & 0x1)
#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))
+#define PKT3(op, count, predicate) (PKT_TYPE_S(3) | PKT3_IT_OPCODE_S(op) | PKT_COUNT_S(count) | PKT3_PRED_S(predicate))
/* Registers */
#define R_0280A0_CB_COLOR0_INFO 0x0280A0
diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c
index 557cfb9597..ba02a3c2bd 100644
--- a/src/gallium/winsys/r600/drm/radeon_bo.c
+++ b/src/gallium/winsys/r600/drm/radeon_bo.c
@@ -33,6 +33,25 @@
#include "xf86drm.h"
#include "radeon_drm.h"
+#ifdef ANDROID
+
+extern void* __mmap2(void*, size_t, int, int, int, size_t);
+
+#define MMAP2_SHIFT 12
+static void* android_mmap2(void *addr, size_t size, int prot, int flags, int fd, unsigned long long offset)
+{
+ if ( offset & ((1UL << MMAP2_SHIFT)-1) ) {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+
+ return __mmap2(addr, size, prot, flags, fd, (size_t)(offset >> MMAP2_SHIFT));
+}
+
+#define mmap(addr, size, prot, flags, fd, offset) android_mmap2(addr, size, prot, flags, fd, offset)
+
+#endif /* ANDROID */
+
static int radeon_bo_fixed_map(struct radeon *radeon, struct radeon_bo *bo)
{
struct drm_radeon_gem_mmap args;
@@ -98,7 +117,7 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
bo->size = open_arg.size;
bo->shared = TRUE;
} else {
- struct drm_radeon_gem_create args;
+ struct drm_radeon_gem_create args = {};
args.size = size;
args.alignment = alignment;
@@ -156,7 +175,7 @@ int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo)
if (!bo->shared) {
if (!bo->fence)
return 0;
- if (bo->fence <= *bo->ctx->cfence) {
+ if (bo->fence <= *radeon->cfence) {
LIST_DELINIT(&bo->fencedlist);
bo->fence = 0;
return 0;
@@ -181,7 +200,7 @@ int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain
if (!bo->shared) {
if (!bo->fence)
return 0;
- if (bo->fence <= *bo->ctx->cfence) {
+ if (bo->fence <= *radeon->cfence) {
LIST_DELINIT(&bo->fencedlist);
bo->fence = 0;
return 0;
@@ -204,15 +223,15 @@ int radeon_bo_get_tiling_flags(struct radeon *radeon,
uint32_t *tiling_flags,
uint32_t *pitch)
{
- struct drm_radeon_gem_get_tiling args;
+ struct drm_radeon_gem_get_tiling args = {};
int ret;
-
+
args.handle = bo->handle;
ret = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_GET_TILING,
&args, sizeof(args));
if (ret)
return ret;
-
+
*tiling_flags = args.tiling_flags;
*pitch = args.pitch;
return ret;
diff --git a/src/gallium/winsys/r600/drm/radeon_bo_pb.c b/src/gallium/winsys/r600/drm/radeon_bo_pb.c
deleted file mode 100644
index 4bd3ae3ca1..0000000000
--- a/src/gallium/winsys/r600/drm/radeon_bo_pb.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright 2010 Dave Airlie
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Dave Airlie
- */
-#include <util/u_inlines.h>
-#include <util/u_memory.h>
-#include <util/u_double_list.h>
-#include <pipebuffer/pb_buffer.h>
-#include <pipebuffer/pb_bufmgr.h>
-#include "r600_priv.h"
-
-struct radeon_bo_pb {
- struct pb_buffer b;
- struct radeon_bo *bo;
-
- struct radeon_bo_pbmgr *mgr;
-};
-
-extern const struct pb_vtbl radeon_bo_pb_vtbl;
-
-static INLINE struct radeon_bo_pb *radeon_bo_pb(struct pb_buffer *buf)
-{
- assert(buf);
- assert(buf->vtbl == &radeon_bo_pb_vtbl);
- return (struct radeon_bo_pb *)buf;
-}
-
-struct radeon_bo_pbmgr {
- struct pb_manager b;
- struct radeon *radeon;
-};
-
-static INLINE struct radeon_bo_pbmgr *radeon_bo_pbmgr(struct pb_manager *mgr)
-{
- assert(mgr);
- return (struct radeon_bo_pbmgr *)mgr;
-}
-
-static void radeon_bo_pb_destroy(struct pb_buffer *_buf)
-{
- struct radeon_bo_pb *buf = radeon_bo_pb(_buf);
-
- /* If this buffer is on the list of buffers to unmap,
- * do the unmapping now.
- */
- radeon_bo_unmap(buf->mgr->radeon, buf->bo);
- radeon_bo_reference(buf->mgr->radeon, &buf->bo, NULL);
- FREE(buf);
-}
-
-static void *
-radeon_bo_pb_map_internal(struct pb_buffer *_buf,
- unsigned flags, void *ctx)
-{
- struct radeon_bo_pb *buf = radeon_bo_pb(_buf);
- struct pipe_context *pctx = ctx;
-
- if (flags & PB_USAGE_UNSYNCHRONIZED) {
- if (radeon_bo_map(buf->mgr->radeon, buf->bo)) {
- return NULL;
- }
- return buf->bo->data;
- }
-
- if (p_atomic_read(&buf->bo->reference.count) > 1) {
- if (flags & PB_USAGE_DONTBLOCK) {
- return NULL;
- }
- if (ctx) {
- pctx->flush(pctx, 0, NULL);
- }
- }
-
- if (flags & PB_USAGE_DONTBLOCK) {
- uint32_t domain;
- if (radeon_bo_busy(buf->mgr->radeon, buf->bo, &domain))
- return NULL;
- if (radeon_bo_map(buf->mgr->radeon, buf->bo)) {
- return NULL;
- }
- goto out;
- }
-
- if (radeon_bo_map(buf->mgr->radeon, buf->bo)) {
- return NULL;
- }
- if (radeon_bo_wait(buf->mgr->radeon, buf->bo)) {
- radeon_bo_unmap(buf->mgr->radeon, buf->bo);
- return NULL;
- }
-out:
- return buf->bo->data;
-}
-
-static void radeon_bo_pb_unmap_internal(struct pb_buffer *_buf)
-{
-}
-
-static void
-radeon_bo_pb_get_base_buffer(struct pb_buffer *buf,
- struct pb_buffer **base_buf,
- unsigned *offset)
-{
- *base_buf = buf;
- *offset = 0;
-}
-
-static enum pipe_error
-radeon_bo_pb_validate(struct pb_buffer *_buf,
- struct pb_validate *vl,
- unsigned flags)
-{
- /* Always pinned */
- return PIPE_OK;
-}
-
-static void
-radeon_bo_pb_fence(struct pb_buffer *buf,
- struct pipe_fence_handle *fence)
-{
-}
-
-const struct pb_vtbl radeon_bo_pb_vtbl = {
- radeon_bo_pb_destroy,
- radeon_bo_pb_map_internal,
- radeon_bo_pb_unmap_internal,
- radeon_bo_pb_validate,
- radeon_bo_pb_fence,
- radeon_bo_pb_get_base_buffer,
-};
-
-struct pb_buffer *
-radeon_bo_pb_create_buffer_from_handle(struct pb_manager *_mgr,
- uint32_t handle)
-{
- struct radeon_bo_pbmgr *mgr = radeon_bo_pbmgr(_mgr);
- struct radeon *radeon = mgr->radeon;
- struct radeon_bo_pb *bo;
- struct radeon_bo *hw_bo;
-
- hw_bo = radeon_bo(radeon, handle, 0, 0);
- if (hw_bo == NULL)
- return NULL;
-
- bo = CALLOC_STRUCT(radeon_bo_pb);
- if (!bo) {
- radeon_bo_reference(radeon, &hw_bo, NULL);
- return NULL;
- }
-
- pipe_reference_init(&bo->b.base.reference, 1);
- bo->b.base.alignment = 0;
- bo->b.base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
- bo->b.base.size = hw_bo->size;
- bo->b.vtbl = &radeon_bo_pb_vtbl;
- bo->mgr = mgr;
-
- bo->bo = hw_bo;
-
- return &bo->b;
-}
-
-static struct pb_buffer *
-radeon_bo_pb_create_buffer(struct pb_manager *_mgr,
- pb_size size,
- const struct pb_desc *desc)
-{
- struct radeon_bo_pbmgr *mgr = radeon_bo_pbmgr(_mgr);
- struct radeon *radeon = mgr->radeon;
- struct radeon_bo_pb *bo;
-
- bo = CALLOC_STRUCT(radeon_bo_pb);
- if (!bo)
- goto error1;
-
- pipe_reference_init(&bo->b.base.reference, 1);
- bo->b.base.alignment = desc->alignment;
- bo->b.base.usage = desc->usage;
- bo->b.base.size = size;
- bo->b.vtbl = &radeon_bo_pb_vtbl;
- bo->mgr = mgr;
-
- bo->bo = radeon_bo(radeon, 0, size, desc->alignment);
- if (bo->bo == NULL)
- goto error2;
- return &bo->b;
-
-error2:
- FREE(bo);
-error1:
- return NULL;
-}
-
-static void
-radeon_bo_pbmgr_flush(struct pb_manager *mgr)
-{
- /* NOP */
-}
-
-static void
-radeon_bo_pbmgr_destroy(struct pb_manager *_mgr)
-{
- struct radeon_bo_pbmgr *mgr = radeon_bo_pbmgr(_mgr);
- FREE(mgr);
-}
-
-struct pb_manager *radeon_bo_pbmgr_create(struct radeon *radeon)
-{
- struct radeon_bo_pbmgr *mgr;
-
- mgr = CALLOC_STRUCT(radeon_bo_pbmgr);
- if (!mgr)
- return NULL;
-
- mgr->b.destroy = radeon_bo_pbmgr_destroy;
- mgr->b.create_buffer = radeon_bo_pb_create_buffer;
- mgr->b.flush = radeon_bo_pbmgr_flush;
-
- mgr->radeon = radeon;
- return &mgr->b;
-}
-
-struct radeon_bo *radeon_bo_pb_get_bo(struct pb_buffer *_buf)
-{
- struct radeon_bo_pb *buf;
- if (_buf->vtbl == &radeon_bo_pb_vtbl) {
- buf = radeon_bo_pb(_buf);
- return buf->bo;
- } else {
- struct pb_buffer *base_buf;
- pb_size offset;
- pb_get_base_buffer(_buf, &base_buf, &offset);
- if (base_buf->vtbl == &radeon_bo_pb_vtbl) {
- buf = radeon_bo_pb(base_buf);
- return buf->bo;
- }
- }
- return NULL;
-}
diff --git a/src/gallium/winsys/r600/drm/radeon_pciid.c b/src/gallium/winsys/r600/drm/radeon_pciid.c
index 92560a488a..f19956931d 100644
--- a/src/gallium/winsys/r600/drm/radeon_pciid.c
+++ b/src/gallium/winsys/r600/drm/radeon_pciid.c
@@ -32,7 +32,7 @@ struct pci_id {
unsigned family;
};
-struct pci_id radeon_pci_id[] = {
+static const struct pci_id radeon_pci_id[] = {
{0x1002, 0x3150, CHIP_RV380},
{0x1002, 0x3152, CHIP_RV380},
{0x1002, 0x3154, CHIP_RV380},
@@ -40,29 +40,29 @@ struct pci_id radeon_pci_id[] = {
{0x1002, 0x3E54, CHIP_RV380},
{0x1002, 0x4136, CHIP_RS100},
{0x1002, 0x4137, CHIP_RS200},
- {0x1002, 0x4144, CHIP_R300},
- {0x1002, 0x4145, CHIP_R300},
- {0x1002, 0x4146, CHIP_R300},
- {0x1002, 0x4147, CHIP_R300},
- {0x1002, 0x4148, CHIP_R350},
- {0x1002, 0x4149, CHIP_R350},
- {0x1002, 0x414A, CHIP_R350},
- {0x1002, 0x414B, CHIP_R350},
- {0x1002, 0x4150, CHIP_RV350},
- {0x1002, 0x4151, CHIP_RV350},
- {0x1002, 0x4152, CHIP_RV350},
- {0x1002, 0x4153, CHIP_RV350},
- {0x1002, 0x4154, CHIP_RV350},
- {0x1002, 0x4155, CHIP_RV350},
- {0x1002, 0x4156, CHIP_RV350},
+ {0x1002, 0x4144, CHIP_R300},
+ {0x1002, 0x4145, CHIP_R300},
+ {0x1002, 0x4146, CHIP_R300},
+ {0x1002, 0x4147, CHIP_R300},
+ {0x1002, 0x4148, CHIP_R350},
+ {0x1002, 0x4149, CHIP_R350},
+ {0x1002, 0x414A, CHIP_R350},
+ {0x1002, 0x414B, CHIP_R350},
+ {0x1002, 0x4150, CHIP_RV350},
+ {0x1002, 0x4151, CHIP_RV350},
+ {0x1002, 0x4152, CHIP_RV350},
+ {0x1002, 0x4153, CHIP_RV350},
+ {0x1002, 0x4154, CHIP_RV350},
+ {0x1002, 0x4155, CHIP_RV350},
+ {0x1002, 0x4156, CHIP_RV350},
{0x1002, 0x4237, CHIP_RS200},
- {0x1002, 0x4242, CHIP_R200},
- {0x1002, 0x4243, CHIP_R200},
+ {0x1002, 0x4242, CHIP_R200},
+ {0x1002, 0x4243, CHIP_R200},
{0x1002, 0x4336, CHIP_RS100},
{0x1002, 0x4337, CHIP_RS200},
{0x1002, 0x4437, CHIP_RS200},
- {0x1002, 0x4966, CHIP_RV250},
- {0x1002, 0x4967, CHIP_RV250},
+ {0x1002, 0x4966, CHIP_RV250},
+ {0x1002, 0x4967, CHIP_RV250},
{0x1002, 0x4A48, CHIP_R420},
{0x1002, 0x4A49, CHIP_R420},
{0x1002, 0x4A4A, CHIP_R420},
@@ -85,14 +85,14 @@ struct pci_id radeon_pci_id[] = {
{0x1002, 0x4C64, CHIP_RV250},
{0x1002, 0x4C66, CHIP_RV250},
{0x1002, 0x4C67, CHIP_RV250},
- {0x1002, 0x4E44, CHIP_R300},
- {0x1002, 0x4E45, CHIP_R300},
- {0x1002, 0x4E46, CHIP_R300},
- {0x1002, 0x4E47, CHIP_R300},
- {0x1002, 0x4E48, CHIP_R350},
- {0x1002, 0x4E49, CHIP_R350},
- {0x1002, 0x4E4A, CHIP_R350},
- {0x1002, 0x4E4B, CHIP_R350},
+ {0x1002, 0x4E44, CHIP_R300},
+ {0x1002, 0x4E45, CHIP_R300},
+ {0x1002, 0x4E46, CHIP_R300},
+ {0x1002, 0x4E47, CHIP_R300},
+ {0x1002, 0x4E48, CHIP_R350},
+ {0x1002, 0x4E49, CHIP_R350},
+ {0x1002, 0x4E4A, CHIP_R350},
+ {0x1002, 0x4E4B, CHIP_R350},
{0x1002, 0x4E50, CHIP_RV350},
{0x1002, 0x4E51, CHIP_RV350},
{0x1002, 0x4E52, CHIP_RV350},
@@ -103,13 +103,13 @@ struct pci_id radeon_pci_id[] = {
{0x1002, 0x5145, CHIP_R100},
{0x1002, 0x5146, CHIP_R100},
{0x1002, 0x5147, CHIP_R100},
- {0x1002, 0x5148, CHIP_R200},
- {0x1002, 0x514C, CHIP_R200},
- {0x1002, 0x514D, CHIP_R200},
- {0x1002, 0x5157, CHIP_RV200},
- {0x1002, 0x5158, CHIP_RV200},
- {0x1002, 0x5159, CHIP_RV100},
- {0x1002, 0x515A, CHIP_RV100},
+ {0x1002, 0x5148, CHIP_R200},
+ {0x1002, 0x514C, CHIP_R200},
+ {0x1002, 0x514D, CHIP_R200},
+ {0x1002, 0x5157, CHIP_RV200},
+ {0x1002, 0x5158, CHIP_RV200},
+ {0x1002, 0x5159, CHIP_RV100},
+ {0x1002, 0x515A, CHIP_RV100},
{0x1002, 0x515E, CHIP_RV100},
{0x1002, 0x5460, CHIP_RV380},
{0x1002, 0x5462, CHIP_RV380},
@@ -138,10 +138,10 @@ struct pci_id radeon_pci_id[] = {
{0x1002, 0x5955, CHIP_RS480},
{0x1002, 0x5974, CHIP_RS480},
{0x1002, 0x5975, CHIP_RS480},
- {0x1002, 0x5960, CHIP_RV280},
- {0x1002, 0x5961, CHIP_RV280},
- {0x1002, 0x5962, CHIP_RV280},
- {0x1002, 0x5964, CHIP_RV280},
+ {0x1002, 0x5960, CHIP_RV280},
+ {0x1002, 0x5961, CHIP_RV280},
+ {0x1002, 0x5962, CHIP_RV280},
+ {0x1002, 0x5964, CHIP_RV280},
{0x1002, 0x5965, CHIP_RV280},
{0x1002, 0x5969, CHIP_RV100},
{0x1002, 0x5a41, CHIP_RS400},
@@ -445,6 +445,42 @@ struct pci_id radeon_pci_id[] = {
{0x1002, 0x9803, CHIP_PALM},
{0x1002, 0x9804, CHIP_PALM},
{0x1002, 0x9805, CHIP_PALM},
+ {0x1002, 0x6720, CHIP_BARTS},
+ {0x1002, 0x6721, CHIP_BARTS},
+ {0x1002, 0x6722, CHIP_BARTS},
+ {0x1002, 0x6723, CHIP_BARTS},
+ {0x1002, 0x6724, CHIP_BARTS},
+ {0x1002, 0x6725, CHIP_BARTS},
+ {0x1002, 0x6726, CHIP_BARTS},
+ {0x1002, 0x6727, CHIP_BARTS},
+ {0x1002, 0x6728, CHIP_BARTS},
+ {0x1002, 0x6729, CHIP_BARTS},
+ {0x1002, 0x6738, CHIP_BARTS},
+ {0x1002, 0x6739, CHIP_BARTS},
+ {0x1002, 0x6740, CHIP_TURKS},
+ {0x1002, 0x6741, CHIP_TURKS},
+ {0x1002, 0x6742, CHIP_TURKS},
+ {0x1002, 0x6743, CHIP_TURKS},
+ {0x1002, 0x6744, CHIP_TURKS},
+ {0x1002, 0x6745, CHIP_TURKS},
+ {0x1002, 0x6746, CHIP_TURKS},
+ {0x1002, 0x6747, CHIP_TURKS},
+ {0x1002, 0x6748, CHIP_TURKS},
+ {0x1002, 0x6749, CHIP_TURKS},
+ {0x1002, 0x6750, CHIP_TURKS},
+ {0x1002, 0x6758, CHIP_TURKS},
+ {0x1002, 0x6759, CHIP_TURKS},
+ {0x1002, 0x6760, CHIP_CAICOS},
+ {0x1002, 0x6761, CHIP_CAICOS},
+ {0x1002, 0x6762, CHIP_CAICOS},
+ {0x1002, 0x6763, CHIP_CAICOS},
+ {0x1002, 0x6764, CHIP_CAICOS},
+ {0x1002, 0x6765, CHIP_CAICOS},
+ {0x1002, 0x6766, CHIP_CAICOS},
+ {0x1002, 0x6767, CHIP_CAICOS},
+ {0x1002, 0x6768, CHIP_CAICOS},
+ {0x1002, 0x6770, CHIP_CAICOS},
+ {0x1002, 0x6779, CHIP_CAICOS},
{0, 0},
};