#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
+#include <util/u_double_list.h>
+#include <util/u_inlines.h>
+#include "util/u_hash_table.h"
+#include <os/os_thread.h>
#include "r600.h"
+#define PKT_COUNT_C 0xC000FFFF
+#define PKT_COUNT_S(x) (((x) & 0x3FFF) << 16)
+
+struct r600_bomgr;
+struct r600_bo;
struct radeon {
int fd;
unsigned device;
unsigned family;
enum chip_class chip_class;
- boolean use_mem_constant; /* true for evergreen */
- struct pb_manager *mman; /* malloc manager */
- struct pb_manager *kman; /* kernel bo manager */
- struct pb_manager *cman; /* cached bo manager */
+ 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;
+
+ /* List of buffer handles and its mutex. */
+ struct util_hash_table *bo_handles;
+ pipe_mutex bo_handles_mutex;
};
-struct radeon *r600_new(int fd, unsigned device);
-void r600_delete(struct radeon *r600);
+#define REG_FLAG_NEED_BO 1
+#define REG_FLAG_DIRTY_ALWAYS 2
+#define REG_FLAG_RV6XX_SBU 4
struct r600_reg {
unsigned opcode;
unsigned offset_base;
unsigned offset;
- unsigned need_bo;
+ unsigned flags;
unsigned flush_flags;
+ unsigned flush_mask;
+};
+
+struct radeon_bo {
+ struct pipe_reference reference;
+ unsigned handle;
+ unsigned size;
+ unsigned alignment;
+ int map_count;
+ void *data;
+ struct list_head fencedlist;
+ unsigned fence;
+ struct r600_context *ctx;
+ boolean shared;
+ struct r600_reloc *reloc;
+ unsigned reloc_id;
+ unsigned last_flush;
+ unsigned name;
+};
+
+struct r600_bo {
+ struct pipe_reference reference;
+ 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;
};
-/* radeon_pciid.c */
+struct r600_bomgr {
+ struct radeon *radeon;
+ unsigned usecs;
+ pipe_mutex mutex;
+ struct list_head delayed;
+ unsigned num_delayed;
+};
+
+/*
+ * 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
+ */
+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);
+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,
+ uint32_t *tiling_flags,
+ uint32_t *pitch);
+int radeon_bo_get_name(struct radeon *radeon,
+ struct radeon_bo *bo,
+ uint32_t *name);
+
+/*
+ * 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,
+ unsigned flush_mask, struct r600_bo *rbo);
+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);
+void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset);
+void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block *block);
+void r600_context_dirty_block(struct r600_context *ctx, struct r600_block *block,
+ int dirty, int index);
+
+void r600_context_reg(struct r600_context *ctx,
+ unsigned offset, unsigned value,
+ unsigned mask);
+/*
+ * 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))
-
-static void inline r600_context_reg(struct r600_context *ctx,
- unsigned offset, unsigned value,
- unsigned mask)
+/*
+ * radeon_bo.c
+ */
+static inline int radeon_bo_map(struct radeon *radeon, struct radeon_bo *bo)
{
- struct r600_range *range;
- struct r600_block *block;
- unsigned id;
-
- range = &ctx->range[CTX_RANGE_ID(ctx, offset)];
- block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
- id = (offset - block->start_offset) >> 2;
- block->reg[id] &= ~mask;
- block->reg[id] |= value;
- if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
- ctx->pm4_dirty_cdwords += block->pm4_ndwords;
- }
- block->status |= R600_BLOCK_STATUS_ENABLED;
- block->status |= R600_BLOCK_STATUS_DIRTY;
+ bo->map_count++;
+ return 0;
}
-struct radeon_bo *radeon_bo_pb_get_bo(struct pb_buffer *_buf);
-void r600_context_bo_reloc(struct r600_context *ctx, u32 *pm4, struct radeon_bo *bo);
-
-struct radeon_ws_bo {
- struct pipe_reference reference;
- struct pb_buffer *pb;
-};
+static inline void radeon_bo_unmap(struct radeon *radeon, struct radeon_bo *bo)
+{
+ bo->map_count--;
+ assert(bo->map_count >= 0);
+}
-static inline void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block *block)
+/*
+ * fence
+ */
+static inline bool fence_is_after(unsigned fence, unsigned ofence)
{
- struct radeon_bo *bo;
- int id;
-
- for (int j = 0; j < block->nreg; j++) {
- if (block->pm4_bo_index[j]) {
- /* find relocation */
- id = block->pm4_bo_index[j];
- bo = radeon_bo_pb_get_bo(block->reloc[id].bo->pb);
- for (int k = 0; k < block->reloc[id].nreloc; k++) {
- r600_context_bo_reloc(ctx,
- &block->pm4[block->reloc[id].bo_pm4_index[k]],
- bo);
- }
- }
- }
- memcpy(&ctx->pm4[ctx->pm4_cdwords], block->pm4, block->pm4_ndwords * 4);
- ctx->pm4_cdwords += block->pm4_ndwords;
- block->status ^= R600_BLOCK_STATUS_DIRTY;
+ /* handle wrap around */
+ if (fence < 0x80000000 && ofence > 0x80000000)
+ return TRUE;
+ if (fence > ofence)
+ return TRUE;
+ return FALSE;
}
#endif