virgl: Add support for querying detailed memory info

This allows for virgl guests to expose GL_NVX_gpu_memory_info and
GL_ATI_meminfo when the extensions are supported on the host.

Signed-off-by: Rohan Garg <rohan.garg@collabora.com>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9337>
This commit is contained in:
Rohan Garg
2021-02-25 18:13:22 +01:00
parent 1e53e0d2c7
commit c6eb84ff30
5 changed files with 63 additions and 0 deletions

View File

@@ -1505,3 +1505,9 @@ void virgl_encode_end_transfers(struct virgl_cmd_buf *buf)
virgl_encoder_write_dword(buf, command);
}
}
void virgl_encode_get_memory_info(struct virgl_context *ctx, struct virgl_resource *res)
{
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_GET_MEMORY_INFO, 0, 1));
virgl_encoder_write_res(ctx, res);
}

View File

@@ -308,5 +308,7 @@ void virgl_encode_end_transfers(struct virgl_cmd_buf *buf);
int virgl_encode_tweak(struct virgl_context *ctx, enum vrend_tweak_type tweak, uint32_t value);
void virgl_encode_get_memory_info(struct virgl_context *ctx, struct virgl_resource *res);
enum virgl_formats pipe_to_virgl_format(enum pipe_format format);
#endif

View File

@@ -26,6 +26,7 @@
#include "util/u_screen.h"
#include "util/u_video.h"
#include "util/u_math.h"
#include "util/u_inlines.h"
#include "util/os_time.h"
#include "util/xmlconfig.h"
#include "pipe/p_defines.h"
@@ -38,6 +39,7 @@
#include "virgl_public.h"
#include "virgl_context.h"
#include "virtio-gpu/virgl_protocol.h"
#include "virgl_encode.h"
int virgl_debug = 0;
static const struct debug_named_value virgl_debug_options[] = {
@@ -333,6 +335,8 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
* in virgl_encode_shader_state().
*/
return 0;
case PIPE_CAP_QUERY_MEMORY_INFO:
return vscreen->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_MEMINFO;
default:
return u_pipe_screen_get_param_defaults(screen, param);
}
@@ -836,6 +840,44 @@ fixup_formats(union virgl_caps *caps, struct virgl_supported_format_mask *mask)
mask->bitmask[i] = caps->v1.sampler.bitmask[i];
}
static void virgl_query_memory_info(struct pipe_screen *screen, struct pipe_memory_info *info)
{
struct virgl_screen *vscreen = virgl_screen(screen);
struct pipe_context *ctx = screen->context_create(screen, NULL, 0);
struct virgl_context *vctx = virgl_context(ctx);
struct virgl_resource *res;
struct virgl_memory_info virgl_info = {0};
const static struct pipe_resource templ = {
.target = PIPE_BUFFER,
.format = PIPE_FORMAT_R8_UNORM,
.bind = PIPE_BIND_CUSTOM,
.width0 = sizeof(struct virgl_memory_info),
.height0 = 1,
.depth0 = 1,
.array_size = 1,
.last_level = 0,
.nr_samples = 0,
.flags = 0
};
res = (struct virgl_resource*) screen->resource_create(screen, &templ);
virgl_encode_get_memory_info(vctx, res);
ctx->flush(ctx, NULL, 0);
vscreen->vws->resource_wait(vscreen->vws, res->hw_res);
pipe_buffer_read(ctx, &res->u.b, 0, sizeof(struct virgl_memory_info), &virgl_info);
info->avail_device_memory = virgl_info.avail_device_memory;
info->avail_staging_memory = virgl_info.avail_staging_memory;
info->device_memory_evicted = virgl_info.device_memory_evicted;
info->nr_device_memory_evictions = virgl_info.nr_device_memory_evictions;
info->total_device_memory = virgl_info.total_device_memory;
info->total_staging_memory = virgl_info.total_staging_memory;
screen->resource_destroy(screen, &res->u.b);
ctx->destroy(ctx);
}
struct pipe_screen *
virgl_create_screen(struct virgl_winsys *vws, const struct pipe_screen_config *config)
{
@@ -877,6 +919,7 @@ virgl_create_screen(struct virgl_winsys *vws, const struct pipe_screen_config *c
//screen->base.fence_signalled = virgl_fence_signalled;
screen->base.fence_finish = virgl_fence_finish;
screen->base.fence_get_fd = virgl_fence_get_fd;
screen->base.query_memory_info = virgl_query_memory_info;
virgl_init_screen_resource_functions(&screen->base);

View File

@@ -440,6 +440,7 @@ enum virgl_formats {
#define VIRGL_CAP_V2_BLEND_EQUATION (1 << 0)
#define VIRGL_CAP_V2_UNTYPED_RESOURCE (1 << 1)
#define VIRGL_CAP_V2_VIDEO_MEMORY (1 << 2)
#define VIRGL_CAP_V2_MEMINFO (1 << 3)
/* virgl bind flags - these are compatible with mesa 10.5 gallium.
* but are fixed, no other should be passed to virgl either.

View File

@@ -35,6 +35,16 @@ struct virgl_host_query_state {
uint64_t result;
};
struct virgl_memory_info
{
uint32_t total_device_memory; /**< size of device memory, e.g. VRAM */
uint32_t avail_device_memory; /**< free device memory at the moment */
uint32_t total_staging_memory; /**< size of staging memory, e.g. GART */
uint32_t avail_staging_memory; /**< free staging memory at the moment */
uint32_t device_memory_evicted; /**< size of memory evicted (monotonic counter) */
uint32_t nr_device_memory_evictions; /**< # of evictions (monotonic counter) */
};
enum virgl_object_type {
VIRGL_OBJECT_NULL,
VIRGL_OBJECT_BLEND,
@@ -103,6 +113,7 @@ enum virgl_context_cmd {
VIRGL_CCMD_CLEAR_TEXTURE,
VIRGL_CCMD_PIPE_RESOURCE_CREATE,
VIRGL_CCMD_PIPE_RESOURCE_SET_TYPE,
VIRGL_CCMD_GET_MEMORY_INFO,
VIRGL_MAX_COMMANDS
};