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:
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user