X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr600%2Fr600.h;h=baf09c1d8aafe3efbd3d18e7d12daf3cee50c133;hb=f01431d0358ae337227a348e96b30adfd8d55f7c;hp=acacec0c413dc5437f92451bfac65a4a698dacf2;hpb=ac8a1ebe55b08180945ffaebcff6b3bed336c9ec;p=mesa.git diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index acacec0c413..baf09c1d8aa 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -26,53 +26,22 @@ #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/%s:%d - "fmt, __FILE__, __func__, __LINE__, ##args) + fprintf(stderr, "EE %s:%d %s - "fmt, __FILE__, __LINE__, __func__, ##args) typedef uint64_t u64; 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, @@ -90,6 +59,13 @@ enum radeon_family { CHIP_JUNIPER, CHIP_CYPRESS, CHIP_HEMLOCK, + CHIP_PALM, + CHIP_SUMO, + CHIP_SUMO2, + CHIP_BARTS, + CHIP_TURKS, + CHIP_CAICOS, + CHIP_CAYMAN, CHIP_LAST, }; @@ -97,37 +73,49 @@ enum chip_class { R600, R700, EVERGREEN, + CAYMAN, }; -enum radeon_family r600_get_family(struct radeon *rw); -enum chip_class r600_get_family_class(struct radeon *radeon); - -/* r600_bo.c */ -struct r600_bo; -struct r600_bo *r600_bo(struct radeon *radeon, - unsigned size, unsigned alignment, unsigned usage); -struct r600_bo *r600_bo_handle(struct radeon *radeon, - unsigned handle); -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); -static INLINE unsigned r600_bo_offset(struct r600_bo *bo) -{ - return 0; -} +struct r600_tiling_info { + unsigned num_channels; + unsigned num_banks; + unsigned group_bytes; +}; +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 { @@ -136,37 +124,38 @@ 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; - unsigned nreloc; + struct r600_resource *bo; + enum radeon_bo_usage bo_usage; unsigned flush_flags; unsigned flush_mask; - unsigned bo_pm4_index[R600_BLOCK_MAX_BO]; + unsigned bo_pm4_index; }; struct r600_block { struct list_head list; + struct list_head enable_list; unsigned status; + unsigned flags; unsigned start_offset; unsigned pm4_ndwords; unsigned pm4_flush_ndwords; unsigned nbo; - unsigned nreg; + u16 nreg; + u16 nreg_dirty; u32 *reg; u32 pm4[R600_BLOCK_MAX_REG]; unsigned pm4_bo_index[R600_BLOCK_MAX_REG]; @@ -174,66 +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; + 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 { @@ -242,18 +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_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); @@ -265,15 +281,55 @@ void r600_query_begin(struct r600_context *ctx, struct r600_query *query); void r600_query_end(struct r600_context *ctx, struct r600_query *query); 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_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 evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *draw); -void evergreen_ps_resource_set(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); -void evergreen_vs_resource_set(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); +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); -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); +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_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); +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