X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr600%2Fr600.h;h=baf09c1d8aafe3efbd3d18e7d12daf3cee50c133;hb=f01431d0358ae337227a348e96b30adfd8d55f7c;hp=0b0df9d019b4107b6feead87c31789cc28ad5cec;hpb=fa31b1095eeea97695125ad5770239805bed37da;p=mesa.git diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 0b0df9d019b..baf09c1d8aa 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -26,13 +26,9 @@ #ifndef R600_H #define R600_H -#include -#include -#include -#include -#include - -#define RADEON_CTX_MAX_PM4 (64 * 1024 / 4) +#include "../../winsys/radeon/drm/radeon_winsys.h" +#include "util/u_double_list.h" +#include "util/u_vbuf.h" #define R600_ERR(fmt, args...) \ fprintf(stderr, "EE %s:%d %s - "fmt, __FILE__, __LINE__, __func__, ##args) @@ -42,38 +38,10 @@ typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; -struct radeon; struct winsys_handle; enum radeon_family { CHIP_UNKNOWN, - CHIP_R100, - CHIP_RV100, - CHIP_RS100, - CHIP_RV200, - CHIP_RS200, - CHIP_R200, - CHIP_RV250, - CHIP_RS300, - CHIP_RV280, - CHIP_R300, - CHIP_R350, - CHIP_RV350, - CHIP_RV380, - CHIP_R420, - CHIP_R423, - CHIP_RV410, - CHIP_RS400, - CHIP_RS480, - CHIP_RS600, - CHIP_RS690, - CHIP_RS740, - CHIP_RV515, - CHIP_R520, - CHIP_RV530, - CHIP_RV560, - CHIP_RV570, - CHIP_R580, CHIP_R600, CHIP_RV610, CHIP_RV630, @@ -92,9 +60,12 @@ enum radeon_family { CHIP_CYPRESS, CHIP_HEMLOCK, CHIP_PALM, + CHIP_SUMO, + CHIP_SUMO2, CHIP_BARTS, CHIP_TURKS, CHIP_CAICOS, + CHIP_CAYMAN, CHIP_LAST, }; @@ -102,6 +73,7 @@ enum chip_class { R600, R700, EVERGREEN, + CAYMAN, }; struct r600_tiling_info { @@ -110,42 +82,40 @@ struct r600_tiling_info { unsigned group_bytes; }; -enum radeon_family r600_get_family(struct radeon *rw); -enum chip_class r600_get_family_class(struct radeon *radeon); -struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon); -unsigned r600_get_clock_crystal_freq(struct radeon *radeon); -unsigned r600_get_minor_version(struct radeon *radeon); -unsigned r600_get_num_backends(struct radeon *radeon); - -/* r600_bo.c */ -struct r600_bo; -struct r600_bo *r600_bo(struct radeon *radeon, - unsigned size, unsigned alignment, - unsigned binding, unsigned usage); -struct r600_bo *r600_bo_handle(struct radeon *radeon, - unsigned handle, unsigned *array_mode); -void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, void *ctx); -void r600_bo_unmap(struct radeon *radeon, struct r600_bo *bo); -void r600_bo_reference(struct radeon *radeon, struct r600_bo **dst, - struct r600_bo *src); -boolean r600_bo_get_winsys_handle(struct radeon *radeon, struct r600_bo *pb_bo, - unsigned stride, struct winsys_handle *whandle); -static INLINE unsigned r600_bo_offset(struct r600_bo *bo) -{ - return 0; -} +struct r600_resource { + struct u_vbuf_resource b; + /* Winsys objects. */ + struct pb_buffer *buf; + struct radeon_winsys_cs_handle *cs_buf; + + /* Resource state. */ + unsigned domains; +}; /* R600/R700 STATES */ #define R600_GROUP_MAX 16 #define R600_BLOCK_MAX_BO 32 #define R600_BLOCK_MAX_REG 128 +/* each range covers 9 bits of dword space = 512 dwords = 2k bytes */ +/* there is a block entry for each register so 512 blocks */ +/* we have no registers to read/write below 0x8000 (0x2000 in dw space) */ +/* we use some fake offsets at 0x40000 to do evergreen sampler borders so take 0x42000 as a max bound*/ +#define RANGE_OFFSET_START 0x8000 +#define HASH_SHIFT 9 +#define NUM_RANGES (0x42000 - RANGE_OFFSET_START) / (4 << HASH_SHIFT) /* 128 << 9 = 64k */ + +#define CTX_RANGE_ID(offset) ((((offset - RANGE_OFFSET_START) >> 2) >> HASH_SHIFT) & 255) +#define CTX_BLOCK_ID(offset) (((offset - RANGE_OFFSET_START) >> 2) & ((1 << HASH_SHIFT) - 1)) + struct r600_pipe_reg { - u32 offset; - u32 mask; u32 value; - struct r600_bo *bo; + u32 mask; + struct r600_block *block; + struct r600_resource *bo; + enum radeon_bo_usage bo_usage; + u32 id; }; struct r600_pipe_state { @@ -154,23 +124,22 @@ struct r600_pipe_state { struct r600_pipe_reg regs[R600_BLOCK_MAX_REG]; }; -static inline void r600_pipe_state_add_reg(struct r600_pipe_state *state, - u32 offset, u32 value, u32 mask, - struct r600_bo *bo) -{ - state->regs[state->nregs].offset = offset; - state->regs[state->nregs].value = value; - state->regs[state->nregs].mask = mask; - state->regs[state->nregs].bo = bo; - state->nregs++; - assert(state->nregs < R600_BLOCK_MAX_REG); -} +struct r600_pipe_resource_state { + unsigned id; + u32 val[8]; + struct r600_resource *bo[2]; + enum radeon_bo_usage bo_usage[2]; +}; #define R600_BLOCK_STATUS_ENABLED (1 << 0) #define R600_BLOCK_STATUS_DIRTY (1 << 1) +#define R600_BLOCK_STATUS_RESOURCE_DIRTY (1 << 2) + +#define R600_BLOCK_STATUS_RESOURCE_VERTEX (1 << 3) struct r600_block_reloc { - struct r600_bo *bo; + struct r600_resource *bo; + enum radeon_bo_usage bo_usage; unsigned flush_flags; unsigned flush_mask; unsigned bo_pm4_index; @@ -178,6 +147,7 @@ struct r600_block_reloc { struct r600_block { struct list_head list; + struct list_head enable_list; unsigned status; unsigned flags; unsigned start_offset; @@ -193,73 +163,92 @@ struct r600_block { }; struct r600_range { - unsigned start_offset; - unsigned end_offset; struct r600_block **blocks; }; -/* - * relocation - */ -#pragma pack(1) -struct r600_reloc { - uint32_t handle; - uint32_t read_domain; - uint32_t write_domain; - uint32_t flags; -}; -#pragma pack() - -/* - * query - */ struct r600_query { - u64 result; - /* The kind of query. Currently only OQ is supported. */ + union { + uint64_t u64; + boolean b; + struct pipe_query_data_so_statistics so; + } result; + /* The kind of query */ unsigned type; - /* How many results have been written, in dwords. It's incremented - * after end_query and flush. */ - unsigned num_results; - /* if we've flushed the query */ - unsigned state; - /* The buffer where query results are stored. */ - struct r600_bo *buffer; - unsigned buffer_size; + /* Offset of the first result for current query */ + unsigned results_start; + /* Offset of the next free result after current query data */ + unsigned results_end; + /* Size of the result in memory for both begin_query and end_query, + * this can be one or two numbers, or it could even be a size of a structure. */ + unsigned result_size; + /* The buffer where query results are stored. It's used as a ring, + * data blocks for current query are stored sequentially from + * results_start to results_end, with wrapping on the buffer end */ + struct r600_resource *buffer; + /* The number of dwords for begin_query or end_query. */ + unsigned num_cs_dw; /* linked list of queries */ struct list_head list; }; -#define R600_QUERY_STATE_STARTED (1 << 0) -#define R600_QUERY_STATE_ENDED (1 << 1) -#define R600_QUERY_STATE_SUSPENDED (1 << 2) +struct r600_so_target { + struct pipe_stream_output_target b; + + /* The buffer where BUFFER_FILLED_SIZE is stored. */ + struct r600_resource *filled_size; + unsigned stride_in_dw; + unsigned so_index; +}; #define R600_CONTEXT_DRAW_PENDING (1 << 0) #define R600_CONTEXT_DST_CACHES_DIRTY (1 << 1) +#define R600_CONTEXT_CHECK_EVENT_FLUSH (1 << 2) struct r600_context { - struct radeon *radeon; - unsigned hash_size; - unsigned hash_shift; - struct r600_range range[256]; + struct r600_screen *screen; + struct radeon_winsys *ws; + struct radeon_winsys_cs *cs; + struct pipe_context *pipe; + + void (*flush)(void *pipe, unsigned flags); + + struct r600_range *range; unsigned nblocks; struct r600_block **blocks; struct list_head dirty; - unsigned pm4_ndwords; - unsigned pm4_cdwords; + struct list_head resource_dirty; + struct list_head enable_list; unsigned pm4_dirty_cdwords; unsigned ctx_pm4_ndwords; - unsigned nreloc; + unsigned init_dwords; + unsigned creloc; - struct r600_reloc *reloc; - struct radeon_bo **bo; + struct r600_resource **bo; + u32 *pm4; - struct list_head query_list; - unsigned num_query_running; - struct list_head fenced_bo; + unsigned pm4_cdwords; + + /* The list of active queries. Only one query of each type can be active. */ + struct list_head active_query_list; + unsigned num_cs_dw_queries_suspend; + unsigned num_cs_dw_streamout_end; + + unsigned backend_mask; unsigned max_db; /* for OQ */ unsigned num_dest_buffers; unsigned flags; boolean predicate_drawing; + struct r600_range ps_resources; + struct r600_range vs_resources; + struct r600_range fs_resources; + int num_ps_resources, num_vs_resources, num_fs_resources; + boolean have_depth_texture, have_depth_fb; + + unsigned num_so_targets; + struct r600_so_target *so_targets[PIPE_MAX_SO_BUFFERS]; + boolean streamout_start; + unsigned streamout_append_bitmask; + unsigned *vs_so_stride_in_dw; }; struct r600_draw { @@ -268,19 +257,19 @@ struct r600_draw { u32 vgt_index_type; u32 vgt_draw_initiator; u32 indices_bo_offset; - struct r600_bo *indices; + struct r600_resource *indices; }; -int r600_context_init(struct r600_context *ctx, struct radeon *radeon); +void r600_get_backend_mask(struct r600_context *ctx); +int r600_context_init(struct r600_context *ctx, struct r600_screen *screen); void r600_context_fini(struct r600_context *ctx); void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_state *state); -void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); -void r600_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); -void r600_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); +void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); +void r600_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); +void r600_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); void r600_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); void r600_context_pipe_state_set_vs_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); -void r600_context_flush(struct r600_context *ctx); -void r600_context_dump_bof(struct r600_context *ctx, const char *file); +void r600_context_flush(struct r600_context *ctx, unsigned flags); void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw); struct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned query_type); @@ -294,20 +283,53 @@ void r600_context_queries_suspend(struct r600_context *ctx); void r600_context_queries_resume(struct r600_context *ctx); void r600_query_predication(struct r600_context *ctx, struct r600_query *query, int operation, int flag_wait); -void r600_context_emit_fence(struct r600_context *ctx, struct r600_bo *fence, +void r600_context_emit_fence(struct r600_context *ctx, struct r600_resource *fence, unsigned offset, unsigned value); void r600_context_flush_all(struct r600_context *ctx, unsigned flush_flags); void r600_context_flush_dest_caches(struct r600_context *ctx); -int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon); +void r600_context_streamout_begin(struct r600_context *ctx); +void r600_context_streamout_end(struct r600_context *ctx); +void r600_context_draw_opaque_count(struct r600_context *ctx, struct r600_so_target *t); + +int evergreen_context_init(struct r600_context *ctx, struct r600_screen *screen); void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *draw); void evergreen_context_flush_dest_caches(struct r600_context *ctx); -void evergreen_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); -void evergreen_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); -void evergreen_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); +void evergreen_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); +void evergreen_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); +void evergreen_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid); void evergreen_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); void evergreen_context_pipe_state_set_vs_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); -struct radeon *radeon_decref(struct radeon *radeon); +void _r600_pipe_state_add_reg(struct r600_context *ctx, + struct r600_pipe_state *state, + u32 offset, u32 value, u32 mask, + u32 range_id, u32 block_id, + struct r600_resource *bo, + enum radeon_bo_usage usage); + +void r600_pipe_state_add_reg_noblock(struct r600_pipe_state *state, + u32 offset, u32 value, u32 mask, + struct r600_resource *bo, + enum radeon_bo_usage usage); + +#define r600_pipe_state_add_reg(state, offset, value, mask, bo, usage) _r600_pipe_state_add_reg(&rctx->ctx, state, offset, value, mask, CTX_RANGE_ID(offset), CTX_BLOCK_ID(offset), bo, usage) + +static inline void r600_pipe_state_mod_reg(struct r600_pipe_state *state, + u32 value) +{ + state->regs[state->nregs].value = value; + state->nregs++; +} + +static inline void r600_pipe_state_mod_reg_bo(struct r600_pipe_state *state, + u32 value, struct r600_resource *bo, + enum radeon_bo_usage usage) +{ + state->regs[state->nregs].value = value; + state->regs[state->nregs].bo = bo; + state->regs[state->nregs].bo_usage = usage; + state->nregs++; +} #endif