virgl: query buffer object support. (v2)

v2: don't unbind explicity since we fixed that,
use proper i64 interface (Gurchetan)

Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
macos/master
Dave Airlie 7 years ago
parent f4e22b8727
commit 3a069fc6dc
  1. 9
      src/gallium/include/pipe/p_defines.h
  2. 2
      src/virgl_hw.h
  3. 10
      src/virgl_protocol.h
  4. 3
      src/vrend_debug.c
  5. 19
      src/vrend_decode.c
  6. 63
      src/vrend_renderer.c
  7. 4
      src/vrend_renderer.h

@ -369,6 +369,7 @@ enum pipe_flush_flags {
#define PIPE_BIND_SHADER_RESOURCE (1 << 19) /* set_shader_resources */
#define PIPE_BIND_COMPUTE_RESOURCE (1 << 20) /* set_compute_resources */
#define PIPE_BIND_COMMAND_ARGS_BUFFER (1 << 21) /* pipe_draw_info.indirect */
#define PIPE_BIND_QUERY_BUFFER (1 << 22) /* get_query_result_resource */
/* The first two flags above were previously part of the amorphous
* TEXTURE_USAGE, most of which are now descriptions of the ways a
@ -772,6 +773,14 @@ union pipe_query_result
struct pipe_query_data_pipeline_statistics pipeline_statistics;
};
enum pipe_query_value_type
{
PIPE_QUERY_TYPE_I32,
PIPE_QUERY_TYPE_U32,
PIPE_QUERY_TYPE_I64,
PIPE_QUERY_TYPE_U64,
};
union pipe_color_union
{
float f[4];

@ -237,6 +237,7 @@ enum virgl_formats {
#define VIRGL_CAP_TGSI_COMPONENTS (1 << 13)
#define VIRGL_CAP_GUEST_MAY_INIT_LOG (1 << 14)
#define VIRGL_CAP_SRGB_WRITE_CONTROL (1 << 15)
#define VIRGL_CAP_QBO (1 << 16)
/* virgl bind flags - these are compatible with mesa 10.5 gallium.
* but are fixed, no other should be passed to virgl either.
@ -250,6 +251,7 @@ enum virgl_formats {
#define VIRGL_BIND_DISPLAY_TARGET (1 << 7)
#define VIRGL_BIND_STREAM_OUTPUT (1 << 11)
#define VIRGL_BIND_SHADER_BUFFER (1 << 14)
#define VIRGL_BIND_QUERY_BUFFER (1 << 15)
#define VIRGL_BIND_CURSOR (1 << 16)
#define VIRGL_BIND_CUSTOM (1 << 17)
#define VIRGL_BIND_SCANOUT (1 << 18)

@ -97,6 +97,7 @@ enum virgl_context_cmd {
VIRGL_CCMD_TEXTURE_BARRIER,
VIRGL_CCMD_SET_ATOMIC_BUFFERS,
VIRGL_CCMD_SET_DEBUG_FLAGS,
VIRGL_CCMD_GET_QUERY_RESULT_QBO,
VIRGL_MAX_COMMANDS
};
@ -563,4 +564,13 @@ enum virgl_context_cmd {
#define VIRGL_SET_DEBUG_FLAGS_MIN_SIZE 2
#define VIRGL_SET_DEBUG_FLAGSTRING_OFFSET 1
/* query buffer object */
#define VIRGL_QUERY_RESULT_QBO_SIZE 6
#define VIRGL_QUERY_RESULT_QBO_HANDLE 1
#define VIRGL_QUERY_RESULT_QBO_QBO_HANDLE 2
#define VIRGL_QUERY_RESULT_QBO_WAIT 3
#define VIRGL_QUERY_RESULT_QBO_RESULT_TYPE 4
#define VIRGL_QUERY_RESULT_QBO_OFFSET 5
#define VIRGL_QUERY_RESULT_QBO_INDEX 6
#endif

@ -70,7 +70,8 @@ static const char *command_names[VIRGL_MAX_COMMANDS] = {
"SET_FRAMEBUFFER_STATE_NO_ATTACH",
"TEXTURE_BARRIER",
"SET_ATOMIC_BUFFERS",
"SET_DEBUG_FLAGS"
"SET_DEBUG_FLAGS",
"GET_QBO_RESULT"
};
static const char *object_type_names[VIRGL_MAX_OBJECTS] = {

@ -1041,6 +1041,22 @@ static int vrend_decode_get_query_result(struct vrend_decode_ctx *ctx, int lengt
return 0;
}
static int vrend_decode_get_query_result_qbo(struct vrend_decode_ctx *ctx, int length)
{
if (length != VIRGL_QUERY_RESULT_QBO_SIZE)
return EINVAL;
uint32_t handle = get_buf_entry(ctx, VIRGL_QUERY_RESULT_QBO_HANDLE);
uint32_t qbo_handle = get_buf_entry(ctx, VIRGL_QUERY_RESULT_QBO_QBO_HANDLE);
uint32_t wait = get_buf_entry(ctx, VIRGL_QUERY_RESULT_QBO_WAIT);
uint32_t result_type = get_buf_entry(ctx, VIRGL_QUERY_RESULT_QBO_RESULT_TYPE);
uint32_t offset = get_buf_entry(ctx, VIRGL_QUERY_RESULT_QBO_OFFSET);
int32_t index = get_buf_entry(ctx, VIRGL_QUERY_RESULT_QBO_INDEX);
vrend_get_query_result_qbo(ctx->grctx, handle, qbo_handle, wait, result_type, offset, index);
return 0;
}
static int vrend_decode_set_render_condition(struct vrend_decode_ctx *ctx, int length)
{
if (length != VIRGL_RENDER_CONDITION_SIZE)
@ -1522,6 +1538,9 @@ int vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw)
case VIRGL_CCMD_SET_DEBUG_FLAGS:
ret = vrend_decode_set_debug_mask(gdctx, len);
break;
case VIRGL_CCMD_GET_QUERY_RESULT_QBO:
ret = vrend_decode_get_query_result_qbo(gdctx, len);
break;
default:
ret = EINVAL;
}

@ -120,6 +120,7 @@ enum features_id
feat_nv_conditional_render,
feat_nv_prim_restart,
feat_polygon_offset_clamp,
feat_qbo,
feat_robust_buffer_access,
feat_sample_mask,
feat_sample_shading,
@ -194,6 +195,7 @@ static const struct {
FEAT(nv_conditional_render, UNAVAIL, UNAVAIL, "GL_NV_conditional_render" ),
FEAT(nv_prim_restart, UNAVAIL, UNAVAIL, "GL_NV_primitive_restart" ),
FEAT(polygon_offset_clamp, 46, UNAVAIL, "GL_ARB_polygon_offset_clamp" ),
FEAT(qbo, 44, UNAVAIL, "GL_ARB_query_buffer_object" ),
FEAT(robust_buffer_access, 43, UNAVAIL, "GL_ARB_robust_buffer_access_behavior", "GL_KHR_robust_buffer_access_behavior" ),
FEAT(sample_mask, 32, 31, "GL_ARB_texture_multisample" ),
FEAT(sample_shading, 40, 32, "GL_ARB_sample_shading", "GL_OES_sample_shading" ),
@ -2761,6 +2763,8 @@ void vrend_memory_barrier(UNUSED struct vrend_context *ctx,
if (has_feature(feat_ssbo_barrier))
gl_barrier |= GL_SHADER_STORAGE_BARRIER_BIT;
}
if (has_feature(feat_qbo) && (flags & PIPE_BARRIER_QUERY_BUFFER))
gl_barrier |= GL_QUERY_BUFFER_BARRIER_BIT;
}
glMemoryBarrier(gl_barrier);
}
@ -5619,11 +5623,14 @@ static int check_resource_valid(struct vrend_renderer_resource_create_args *args
args->bind == VIRGL_BIND_STREAM_OUTPUT ||
args->bind == VIRGL_BIND_VERTEX_BUFFER ||
args->bind == VIRGL_BIND_CONSTANT_BUFFER ||
args->bind == VIRGL_BIND_QUERY_BUFFER ||
args->bind == VIRGL_BIND_SHADER_BUFFER) {
if (args->target != PIPE_BUFFER)
return -1;
if (args->height != 1 || args->depth != 1)
return -1;
if (args->bind == VIRGL_BIND_QUERY_BUFFER && !has_feature(feat_qbo))
return -1;
} else {
if (!((args->bind & VIRGL_BIND_SAMPLER_VIEW) ||
(args->bind & VIRGL_BIND_DEPTH_STENCIL) ||
@ -5863,6 +5870,9 @@ int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *a
} else if (args->bind == VIRGL_BIND_CONSTANT_BUFFER) {
gr->target = GL_UNIFORM_BUFFER;
vrend_create_buffer(gr, args->width);
} else if (args->bind == VIRGL_BIND_QUERY_BUFFER) {
gr->target = GL_QUERY_BUFFER;
vrend_create_buffer(gr, args->width);
} else if (args->target == PIPE_BUFFER && (args->bind == 0 || args->bind == VIRGL_BIND_SHADER_BUFFER)) {
gr->target = GL_ARRAY_BUFFER_ARB;
vrend_create_buffer(gr, args->width);
@ -6165,6 +6175,7 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx,
res->target == GL_ELEMENT_ARRAY_BUFFER_ARB ||
res->target == GL_ARRAY_BUFFER_ARB ||
res->target == GL_TEXTURE_BUFFER ||
res->target == GL_QUERY_BUFFER ||
res->target == GL_UNIFORM_BUFFER ||
res->target == GL_PIXEL_PACK_BUFFER ||
res->target == GL_PIXEL_UNPACK_BUFFER) {
@ -6675,6 +6686,7 @@ static int vrend_renderer_transfer_send_iov(struct vrend_context *ctx,
res->target == GL_TRANSFORM_FEEDBACK_BUFFER ||
res->target == GL_TEXTURE_BUFFER ||
res->target == GL_UNIFORM_BUFFER ||
res->target == GL_QUERY_BUFFER ||
res->target == GL_PIXEL_PACK_BUFFER ||
res->target == GL_PIXEL_UNPACK_BUFFER) {
uint32_t send_size = info->box->width * util_format_get_blocksize(res->base.format);
@ -7896,6 +7908,54 @@ void vrend_get_query_result(struct vrend_context *ctx, uint32_t handle,
list_addtail(&q->waiting_queries, &vrend_state.waiting_query_list);
}
#define BUFFER_OFFSET(i) ((void *)((char *)NULL + i))
void vrend_get_query_result_qbo(struct vrend_context *ctx, uint32_t handle,
uint32_t qbo_handle,
uint32_t wait, uint32_t result_type, uint32_t offset,
int32_t index)
{
struct vrend_query *q;
struct vrend_resource *res;
if (!has_feature(feat_qbo))
return;
q = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_QUERY);
if (!q)
return;
res = vrend_renderer_ctx_res_lookup(ctx, qbo_handle);
if (!res) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, qbo_handle);
return;
}
glBindBuffer(GL_QUERY_BUFFER, res->id);
GLenum qtype;
if (index == -1)
qtype = GL_QUERY_RESULT_AVAILABLE;
else
qtype = wait ? GL_QUERY_RESULT : GL_QUERY_RESULT_NO_WAIT;
switch ((enum pipe_query_value_type)result_type) {
case PIPE_QUERY_TYPE_I32:
glGetQueryObjectiv(q->id, qtype, BUFFER_OFFSET(offset));
break;
case PIPE_QUERY_TYPE_U32:
glGetQueryObjectuiv(q->id, qtype, BUFFER_OFFSET(offset));
break;
case PIPE_QUERY_TYPE_I64:
glGetQueryObjecti64v(q->id, qtype, BUFFER_OFFSET(offset));
break;
case PIPE_QUERY_TYPE_U64:
glGetQueryObjectui64v(q->id, qtype, BUFFER_OFFSET(offset));
break;
}
glBindBuffer(GL_QUERY_BUFFER, 0);
}
static void vrend_pause_render_condition(struct vrend_context *ctx, bool pause)
{
if (pause) {
@ -8461,6 +8521,7 @@ static void vrend_renderer_fill_caps_v2(int gl_ver, int gles_ver, union virgl_c
if (has_feature(feat_texture_barrier))
caps->v2.capability_bits |= VIRGL_CAP_TEXTURE_BARRIER;
/* always enable this since it doesn't require an ext to pass tests */
caps->v2.capability_bits |= VIRGL_CAP_TGSI_COMPONENTS;
@ -8475,6 +8536,8 @@ static void vrend_renderer_fill_caps_v2(int gl_ver, int gles_ver, union virgl_c
/* always enable, only indicates that the CMD is supported */
caps->v2.capability_bits |= VIRGL_CAP_GUEST_MAY_INIT_LOG;
if (has_feature(feat_qbo))
caps->v2.capability_bits |= VIRGL_CAP_QBO;
}
void vrend_renderer_fill_caps(uint32_t set, UNUSED uint32_t version,

@ -324,6 +324,10 @@ int vrend_begin_query(struct vrend_context *ctx, uint32_t handle);
int vrend_end_query(struct vrend_context *ctx, uint32_t handle);
void vrend_get_query_result(struct vrend_context *ctx, uint32_t handle,
uint32_t wait);
void vrend_get_query_result_qbo(struct vrend_context *ctx, uint32_t handle,
uint32_t qbo_handle,
uint32_t wait, uint32_t result_type, uint32_t offset,
int32_t index);
void vrend_render_condition(struct vrend_context *ctx,
uint32_t handle,
bool condtion,

Loading…
Cancel
Save