struct si_screen;
struct si_context;
struct si_query;
+struct si_query_buffer;
struct si_query_hw;
-struct r600_resource;
+struct si_resource;
+
+#define SI_MAX_STREAMS 4
enum {
SI_QUERY_DRAW_CALLS = PIPE_QUERY_DRIVER_SPECIFIC,
SI_QUERY_GPIN_NUM_SE,
SI_QUERY_TIME_ELAPSED_SDMA,
SI_QUERY_TIME_ELAPSED_SDMA_SI, /* emulated, measured on the CPU */
+ SI_QUERY_PD_NUM_PRIMS_ACCEPTED,
+ SI_QUERY_PD_NUM_PRIMS_REJECTED,
+ SI_QUERY_PD_NUM_PRIMS_INELIGIBLE,
SI_QUERY_FIRST_PERFCOUNTER = PIPE_QUERY_DRIVER_SPECIFIC + 100,
};
};
struct si_query_ops {
- void (*destroy)(struct si_screen *, struct si_query *);
+ void (*destroy)(struct si_context *, struct si_query *);
bool (*begin)(struct si_context *, struct si_query *);
bool (*end)(struct si_context *, struct si_query *);
bool (*get_result)(struct si_context *,
int index,
struct pipe_resource *resource,
unsigned offset);
+
+ void (*suspend)(struct si_context *, struct si_query *);
+ void (*resume)(struct si_context *, struct si_query *);
};
struct si_query {
struct threaded_query b;
- struct si_query_ops *ops;
+ const struct si_query_ops *ops;
- /* The type of query */
+ /* The PIPE_QUERY_xxx type of query */
unsigned type;
+
+ /* The number of dwords for suspend. */
+ unsigned num_cs_dw_suspend;
+
+ /* Linked list of queries that must be suspended at end of CS. */
+ struct list_head active_list;
};
enum {
};
struct si_query_hw_ops {
- bool (*prepare_buffer)(struct si_screen *,
- struct si_query_hw *,
- struct r600_resource *);
+ bool (*prepare_buffer)(struct si_context *, struct si_query_buffer *);
void (*emit_start)(struct si_context *,
struct si_query_hw *,
- struct r600_resource *buffer, uint64_t va);
+ struct si_resource *buffer, uint64_t va);
void (*emit_stop)(struct si_context *,
struct si_query_hw *,
- struct r600_resource *buffer, uint64_t va);
+ struct si_resource *buffer, uint64_t va);
void (*clear_result)(struct si_query_hw *, union pipe_query_result *);
void (*add_result)(struct si_screen *screen,
struct si_query_hw *, void *buffer,
struct si_query_buffer {
/* The buffer where query results are stored. */
- struct r600_resource *buf;
- /* Offset of the next free result after current query data */
- unsigned results_end;
+ struct si_resource *buf;
/* If a query buffer is full, a new buffer is created and the old one
* is put in here. When we calculate the result, we sum up the samples
* from all buffers. */
struct si_query_buffer *previous;
+ /* Offset of the next free result after current query data */
+ unsigned results_end;
+ bool unprepared;
};
+void si_query_buffer_destroy(struct si_screen *sctx, struct si_query_buffer *buffer);
+void si_query_buffer_reset(struct si_context *sctx, struct si_query_buffer *buffer);
+bool si_query_buffer_alloc(struct si_context *sctx, struct si_query_buffer *buffer,
+ bool (*prepare_buffer)(struct si_context *, struct si_query_buffer*),
+ unsigned size);
+
+
struct si_query_hw {
struct si_query b;
struct si_query_hw_ops *ops;
/* 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 number of dwords for end_query. */
- unsigned num_cs_dw_end;
- /* Linked list of queries */
- struct list_head list;
/* For transform feedback: which stream the query is for */
unsigned stream;
/* Workaround via compute shader */
- struct r600_resource *workaround_buf;
+ struct si_resource *workaround_buf;
unsigned workaround_offset;
};
-bool si_query_hw_init(struct si_screen *sscreen,
- struct si_query_hw *query);
-void si_query_hw_destroy(struct si_screen *sscreen,
- struct si_query *rquery);
+void si_query_hw_destroy(struct si_context *sctx,
+ struct si_query *squery);
bool si_query_hw_begin(struct si_context *sctx,
- struct si_query *rquery);
+ struct si_query *squery);
bool si_query_hw_end(struct si_context *sctx,
- struct si_query *rquery);
+ struct si_query *squery);
bool si_query_hw_get_result(struct si_context *sctx,
- struct si_query *rquery,
+ struct si_query *squery,
bool wait,
union pipe_query_result *result);
+void si_query_hw_suspend(struct si_context *sctx, struct si_query *query);
+void si_query_hw_resume(struct si_context *sctx, struct si_query *query);
-/* Performance counters */
-enum {
- /* This block is part of the shader engine */
- SI_PC_BLOCK_SE = (1 << 0),
-
- /* Expose per-instance groups instead of summing all instances (within
- * an SE). */
- SI_PC_BLOCK_INSTANCE_GROUPS = (1 << 1),
-
- /* Expose per-SE groups instead of summing instances across SEs. */
- SI_PC_BLOCK_SE_GROUPS = (1 << 2),
-
- /* Shader block */
- SI_PC_BLOCK_SHADER = (1 << 3),
- /* Non-shader block with perfcounters windowed by shaders. */
- SI_PC_BLOCK_SHADER_WINDOWED = (1 << 4),
-};
-
-/* Describes a hardware block with performance counters. Multiple instances of
- * each block, possibly per-SE, may exist on the chip. Depending on the block
- * and on the user's configuration, we either
- * (a) expose every instance as a performance counter group,
- * (b) expose a single performance counter group that reports the sum over all
- * instances, or
- * (c) expose one performance counter group per instance, but summed over all
- * shader engines.
- */
-struct si_perfcounter_block {
- const char *basename;
- unsigned flags;
- unsigned num_counters;
- unsigned num_selectors;
- unsigned num_instances;
+/* Shader-based queries */
+struct pipe_query *gfx10_sh_query_create(struct si_screen *screen,
+ enum pipe_query_type query_type,
+ unsigned index);
- unsigned num_groups;
- char *group_names;
- unsigned group_name_stride;
-
- char *selector_names;
- unsigned selector_name_stride;
-
- void *data;
-};
+/* Performance counters */
struct si_perfcounters {
unsigned num_groups;
unsigned num_blocks;
- struct si_perfcounter_block *blocks;
+ struct si_pc_block *blocks;
unsigned num_stop_cs_dwords;
unsigned num_instance_cs_dwords;
- unsigned num_shader_types;
- const char * const *shader_type_suffixes;
- const unsigned *shader_type_bits;
-
- void (*emit_instance)(struct si_context *,
- int se, int instance);
- void (*emit_shaders)(struct si_context *, unsigned shaders);
- void (*emit_select)(struct si_context *,
- struct si_perfcounter_block *,
- unsigned count, unsigned *selectors);
- void (*emit_start)(struct si_context *,
- struct r600_resource *buffer, uint64_t va);
- void (*emit_stop)(struct si_context *,
- struct r600_resource *buffer, uint64_t va);
- void (*emit_read)(struct si_context *,
- struct si_perfcounter_block *,
- unsigned count, unsigned *selectors,
- struct r600_resource *buffer, uint64_t va);
-
- void (*cleanup)(struct si_screen *);
-
bool separate_se;
bool separate_instance;
};
unsigned index,
struct pipe_driver_query_group_info *info);
-bool si_perfcounters_init(struct si_perfcounters *, unsigned num_blocks);
-void si_perfcounters_add_block(struct si_screen *,
- struct si_perfcounters *,
- const char *name, unsigned flags,
- unsigned counters, unsigned selectors,
- unsigned instances, void *data);
-void si_perfcounters_do_destroy(struct si_perfcounters *);
-void si_query_hw_reset_buffers(struct si_context *sctx,
- struct si_query_hw *query);
-
struct si_qbo_state {
void *saved_compute;
struct pipe_constant_buffer saved_const0;
struct pipe_shader_buffer saved_ssbo[3];
+ unsigned saved_ssbo_writable_mask;
};
#endif /* SI_QUERY_H */