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);
|
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);
|
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);
|
enum virgl_formats pipe_to_virgl_format(enum pipe_format format);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "util/u_screen.h"
|
#include "util/u_screen.h"
|
||||||
#include "util/u_video.h"
|
#include "util/u_video.h"
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
|
#include "util/u_inlines.h"
|
||||||
#include "util/os_time.h"
|
#include "util/os_time.h"
|
||||||
#include "util/xmlconfig.h"
|
#include "util/xmlconfig.h"
|
||||||
#include "pipe/p_defines.h"
|
#include "pipe/p_defines.h"
|
||||||
@@ -38,6 +39,7 @@
|
|||||||
#include "virgl_public.h"
|
#include "virgl_public.h"
|
||||||
#include "virgl_context.h"
|
#include "virgl_context.h"
|
||||||
#include "virtio-gpu/virgl_protocol.h"
|
#include "virtio-gpu/virgl_protocol.h"
|
||||||
|
#include "virgl_encode.h"
|
||||||
|
|
||||||
int virgl_debug = 0;
|
int virgl_debug = 0;
|
||||||
static const struct debug_named_value virgl_debug_options[] = {
|
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().
|
* in virgl_encode_shader_state().
|
||||||
*/
|
*/
|
||||||
return 0;
|
return 0;
|
||||||
|
case PIPE_CAP_QUERY_MEMORY_INFO:
|
||||||
|
return vscreen->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_MEMINFO;
|
||||||
default:
|
default:
|
||||||
return u_pipe_screen_get_param_defaults(screen, param);
|
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];
|
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 *
|
struct pipe_screen *
|
||||||
virgl_create_screen(struct virgl_winsys *vws, const struct pipe_screen_config *config)
|
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_signalled = virgl_fence_signalled;
|
||||||
screen->base.fence_finish = virgl_fence_finish;
|
screen->base.fence_finish = virgl_fence_finish;
|
||||||
screen->base.fence_get_fd = virgl_fence_get_fd;
|
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);
|
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_BLEND_EQUATION (1 << 0)
|
||||||
#define VIRGL_CAP_V2_UNTYPED_RESOURCE (1 << 1)
|
#define VIRGL_CAP_V2_UNTYPED_RESOURCE (1 << 1)
|
||||||
#define VIRGL_CAP_V2_VIDEO_MEMORY (1 << 2)
|
#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.
|
/* virgl bind flags - these are compatible with mesa 10.5 gallium.
|
||||||
* but are fixed, no other should be passed to virgl either.
|
* but are fixed, no other should be passed to virgl either.
|
||||||
|
@@ -35,6 +35,16 @@ struct virgl_host_query_state {
|
|||||||
uint64_t result;
|
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 {
|
enum virgl_object_type {
|
||||||
VIRGL_OBJECT_NULL,
|
VIRGL_OBJECT_NULL,
|
||||||
VIRGL_OBJECT_BLEND,
|
VIRGL_OBJECT_BLEND,
|
||||||
@@ -103,6 +113,7 @@ enum virgl_context_cmd {
|
|||||||
VIRGL_CCMD_CLEAR_TEXTURE,
|
VIRGL_CCMD_CLEAR_TEXTURE,
|
||||||
VIRGL_CCMD_PIPE_RESOURCE_CREATE,
|
VIRGL_CCMD_PIPE_RESOURCE_CREATE,
|
||||||
VIRGL_CCMD_PIPE_RESOURCE_SET_TYPE,
|
VIRGL_CCMD_PIPE_RESOURCE_SET_TYPE,
|
||||||
|
VIRGL_CCMD_GET_MEMORY_INFO,
|
||||||
VIRGL_MAX_COMMANDS
|
VIRGL_MAX_COMMANDS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user