Commit f00c399b authored by Jordan Justen's avatar Jordan Justen

i965: Implement ARB_query_buffer_object for HSW+

v2:
 * Declare loop index variable at loop site (idr)
 * Make arrays of MI_MATH instructions 'static const' (idr)
 * Remove commented debug code (idr)
 * Updated comment in set_query_availability (Ken)
 * Replace switch with if/else in hsw_result_to_gpr0 (Ken)
 * Only divide GL_FRAGMENT_SHADER_INVOCATIONS_ARB by 4 on
   hsw and gen8 (Ken)
Signed-off-by: Jordan Justen's avatarJordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kenneth Graunke's avatarKenneth Graunke <kenneth@whitecape.org>
Reviewed-by: default avatarIan Romanick <ian.d.romanick@intel.com>
parent 357ff913
......@@ -227,6 +227,7 @@ i965_FILES = \
gen8_viewport_state.c \
gen8_vs_state.c \
gen8_wm_depth_stencil.c \
hsw_queryobj.c \
intel_batchbuffer.c \
intel_batchbuffer.h \
intel_blit.c \
......
......@@ -358,7 +358,9 @@ brw_init_driver_functions(struct brw_context *brw,
brwInitFragProgFuncs( functions );
brw_init_common_queryobj_functions(functions);
if (brw->gen >= 6)
if (brw->gen >= 8 || brw->is_haswell)
hsw_init_queryobj_functions(functions);
else if (brw->gen >= 6)
gen6_init_queryobj_functions(functions);
else
gen4_init_queryobj_functions(functions);
......
......@@ -1427,12 +1427,17 @@ void brw_init_common_queryobj_functions(struct dd_function_table *functions);
void gen4_init_queryobj_functions(struct dd_function_table *functions);
void brw_emit_query_begin(struct brw_context *brw);
void brw_emit_query_end(struct brw_context *brw);
void brw_query_counter(struct gl_context *ctx, struct gl_query_object *q);
bool brw_is_query_pipelined(struct brw_query_object *query);
/** gen6_queryobj.c */
void gen6_init_queryobj_functions(struct dd_function_table *functions);
void brw_write_timestamp(struct brw_context *brw, drm_intel_bo *bo, int idx);
void brw_write_depth_count(struct brw_context *brw, drm_intel_bo *bo, int idx);
/** hsw_queryobj.c */
void hsw_init_queryobj_functions(struct dd_function_table *functions);
/** brw_conditional_render.c */
void brw_init_conditional_render_functions(struct dd_function_table *functions);
bool brw_check_conditional_render(struct brw_context *brw);
......
......@@ -462,7 +462,7 @@ brw_emit_query_end(struct brw_context *brw)
* current GPU time. This is unlike GL_TIME_ELAPSED, which measures the
* time while the query is active.
*/
static void
void
brw_query_counter(struct gl_context *ctx, struct gl_query_object *q)
{
struct brw_context *brw = brw_context(ctx);
......@@ -507,12 +507,45 @@ brw_get_timestamp(struct gl_context *ctx)
return result;
}
/**
* Is this type of query written by PIPE_CONTROL?
*/
bool
brw_is_query_pipelined(struct brw_query_object *query)
{
switch (query->Base.Target) {
case GL_TIMESTAMP:
case GL_TIME_ELAPSED:
case GL_ANY_SAMPLES_PASSED:
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
case GL_SAMPLES_PASSED_ARB:
return true;
case GL_PRIMITIVES_GENERATED:
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
case GL_VERTICES_SUBMITTED_ARB:
case GL_PRIMITIVES_SUBMITTED_ARB:
case GL_VERTEX_SHADER_INVOCATIONS_ARB:
case GL_GEOMETRY_SHADER_INVOCATIONS:
case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB:
case GL_FRAGMENT_SHADER_INVOCATIONS_ARB:
case GL_CLIPPING_INPUT_PRIMITIVES_ARB:
case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB:
case GL_COMPUTE_SHADER_INVOCATIONS_ARB:
case GL_TESS_CONTROL_SHADER_PATCHES_ARB:
case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB:
return false;
default:
unreachable("Unrecognized query target in is_query_pipelined()");
}
}
/* Initialize query object functions used on all generations. */
void brw_init_common_queryobj_functions(struct dd_function_table *functions)
{
functions->NewQueryObject = brw_new_query_object;
functions->DeleteQuery = brw_delete_query;
functions->QueryCounter = brw_query_counter;
functions->GetTimestamp = brw_get_timestamp;
}
......@@ -523,4 +556,5 @@ void gen4_init_queryobj_functions(struct dd_function_table *functions)
functions->EndQuery = brw_end_query;
functions->CheckQuery = brw_check_query;
functions->WaitQuery = brw_wait_query;
functions->QueryCounter = brw_query_counter;
}
......@@ -37,8 +37,37 @@
#include "brw_defines.h"
#include "brw_state.h"
#include "intel_batchbuffer.h"
#include "intel_buffer_objects.h"
#include "intel_reg.h"
static inline void
set_query_availability(struct brw_context *brw, struct brw_query_object *query,
bool available)
{
/* For platforms that support ARB_query_buffer_object, we write the
* query availability for "pipelined" queries.
*
* Most counter snapshots are written by the command streamer, by
* doing a CS stall and then MI_STORE_REGISTER_MEM. For these
* counters, the CS stall guarantees that the results will be
* available when subsequent CS commands run. So we don't need to
* do any additional tracking.
*
* Other counters (occlusion queries and timestamp) are written by
* PIPE_CONTROL, without a CS stall. This means that we can't be
* sure whether the writes have landed yet or not. Performing a
* PIPE_CONTROL with an immediate write will synchronize with
* those earlier writes, so we write 1 when the value has landed.
*/
if (brw->ctx.Extensions.ARB_query_buffer_object &&
brw_is_query_pipelined(query)) {
brw_emit_pipe_control_write(brw,
PIPE_CONTROL_WRITE_IMMEDIATE,
query->bo, 2 * sizeof(uint64_t),
available, 0);
}
}
static void
write_primitives_generated(struct brw_context *brw,
drm_intel_bo *query_bo, int stream, int idx)
......@@ -243,6 +272,9 @@ gen6_begin_query(struct gl_context *ctx, struct gl_query_object *q)
drm_intel_bo_unreference(query->bo);
query->bo = drm_intel_bo_alloc(brw->bufmgr, "query results", 4096, 4096);
/* For ARB_query_buffer_object: The result is not available */
set_query_availability(brw, query, false);
switch (query->Base.Target) {
case GL_TIME_ELAPSED:
/* For timestamp queries, we record the starting time right away so that
......@@ -356,6 +388,9 @@ gen6_end_query(struct gl_context *ctx, struct gl_query_object *q)
* but they won't actually execute until it is flushed.
*/
query->flushed = false;
/* For ARB_query_buffer_object: The result is now available */
set_query_availability(brw, query, true);
}
/**
......@@ -425,6 +460,15 @@ static void gen6_check_query(struct gl_context *ctx, struct gl_query_object *q)
}
}
static void
gen6_query_counter(struct gl_context *ctx, struct gl_query_object *q)
{
struct brw_context *brw = brw_context(ctx);
struct brw_query_object *query = (struct brw_query_object *)q;
brw_query_counter(ctx, q);
set_query_availability(brw, query, true);
}
/* Initialize Gen6+-specific query object functions. */
void gen6_init_queryobj_functions(struct dd_function_table *functions)
{
......@@ -432,4 +476,5 @@ void gen6_init_queryobj_functions(struct dd_function_table *functions)
functions->EndQuery = gen6_end_query;
functions->CheckQuery = gen6_check_query;
functions->WaitQuery = gen6_wait_query;
functions->QueryCounter = gen6_query_counter;
}
This diff is collapsed.
......@@ -366,6 +366,10 @@ intelInitExtensions(struct gl_context *ctx)
}
}
if (brw->gen >= 8 || brw->is_haswell) {
ctx->Extensions.ARB_query_buffer_object = true;
}
if (brw->gen >= 8) {
ctx->Extensions.ARB_stencil_texturing = true;
ctx->Extensions.ARB_texture_stencil8 = true;
......
......@@ -43,6 +43,7 @@
#define MI_STORE_REGISTER_MEM (CMD_MI | (0x24 << 23))
# define MI_STORE_REGISTER_MEM_USE_GGTT (1 << 22)
# define MI_STORE_REGISTER_MEM_PREDICATE (1 << 21)
/* Load a value from memory into a register. Only available on Gen7+. */
#define GEN7_MI_LOAD_REGISTER_MEM (CMD_MI | (0x29 << 23))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment