mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
libdrm/iris: import GPU buffers lazy optimization
Do not import a freshly allocated buffer to all contexts eagerly. Instead check buffer list in context's 'exec_buffer' call and import only buffers needed and not present before GPU execution. This leads to improved performance for applications that use many OpenGL contexts (e.g., VirtualBox 6). issue #4380
This commit is contained in:
parent
3c97fdbc0e
commit
4cb8c91b08
@ -283,7 +283,9 @@ struct Drm::Context
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Gpu::Connection &_gpu;
|
Gpu::Connection &_gpu;
|
||||||
|
Gpu::Connection &_gpu_master;
|
||||||
|
Genode::Allocator &_alloc;
|
||||||
|
|
||||||
Gpu::Info_intel const &_gpu_info {
|
Gpu::Info_intel const &_gpu_info {
|
||||||
*_gpu.attached_info<Gpu::Info_intel>() };
|
*_gpu.attached_info<Gpu::Info_intel>() };
|
||||||
@ -367,9 +369,12 @@ struct Drm::Context
|
|||||||
buffer.gpu_vaddr_valid = false;
|
buffer.gpu_vaddr_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context(Gpu::Connection &gpu, int fd, Genode::Id_space<Context> &space)
|
Context(Gpu::Connection &gpu, Gpu::Connection &gpu_master,
|
||||||
|
Genode::Allocator &alloc, int fd,
|
||||||
|
Genode::Id_space<Context> &space)
|
||||||
:
|
:
|
||||||
_gpu(gpu), _fd(fd), _elem (*this, space) { }
|
_gpu(gpu), _gpu_master(gpu_master), _alloc(alloc), _fd(fd),
|
||||||
|
_elem (*this, space) { }
|
||||||
|
|
||||||
unsigned long id() const
|
unsigned long id() const
|
||||||
{
|
{
|
||||||
@ -383,8 +388,7 @@ struct Drm::Context
|
|||||||
|
|
||||||
int fd() const { return _fd; }
|
int fd() const { return _fd; }
|
||||||
|
|
||||||
void import_buffer(Genode::Allocator &alloc,
|
void import_buffer(Gpu::Buffer_capability buffer_cap,
|
||||||
Gpu::Buffer_capability buffer_cap,
|
|
||||||
Gpu::Buffer_id id)
|
Gpu::Buffer_id id)
|
||||||
{
|
{
|
||||||
Genode::retry<Gpu::Session::Out_of_ram>(
|
Genode::retry<Gpu::Session::Out_of_ram>(
|
||||||
@ -392,7 +396,7 @@ struct Drm::Context
|
|||||||
Genode::retry<Gpu::Session::Out_of_caps>(
|
Genode::retry<Gpu::Session::Out_of_caps>(
|
||||||
[&] () {
|
[&] () {
|
||||||
_gpu.import_buffer(buffer_cap, id);
|
_gpu.import_buffer(buffer_cap, id);
|
||||||
new (alloc) Buffer(_buffer_space, id);
|
new (_alloc) Buffer(_buffer_space, id);
|
||||||
},
|
},
|
||||||
[&] () {
|
[&] () {
|
||||||
_gpu.upgrade_caps(2);
|
_gpu.upgrade_caps(2);
|
||||||
@ -403,23 +407,23 @@ struct Drm::Context
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_buffer(Genode::Allocator &alloc, Gpu::Buffer_id id)
|
void free_buffer(Gpu::Buffer_id id)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
_buffer_space.apply<Buffer>(Buffer::Id_space::Id { .value = id.value },
|
_buffer_space.apply<Buffer>(Buffer::Id_space::Id { .value = id.value },
|
||||||
[&] (Buffer &buffer) {
|
[&] (Buffer &buffer) {
|
||||||
destroy(alloc, &buffer);
|
destroy(_alloc, &buffer);
|
||||||
});
|
});
|
||||||
} catch (Buffer::Id_space::Unknown_id) { return; }
|
} catch (Buffer::Id_space::Unknown_id) { return; }
|
||||||
|
|
||||||
_gpu.free_buffer(id);
|
_gpu.free_buffer(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_buffers(Genode::Allocator &alloc)
|
void free_buffers()
|
||||||
{
|
{
|
||||||
while (_buffer_space.apply_any<Buffer>([&] (Buffer &buffer) {
|
while (_buffer_space.apply_any<Buffer>([&] (Buffer &buffer) {
|
||||||
Gpu::Buffer_id id = buffer.buffer_id();
|
Gpu::Buffer_id id = buffer.buffer_id();
|
||||||
destroy(alloc, &buffer);
|
destroy(_alloc, &buffer);
|
||||||
_gpu.free_buffer(id);
|
_gpu.free_buffer(id);
|
||||||
})) { }
|
})) { }
|
||||||
}
|
}
|
||||||
@ -484,7 +488,13 @@ struct Drm::Context
|
|||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
});
|
});
|
||||||
} catch (Buffer::Id_space::Unknown_id) { }
|
} catch (Buffer::Id_space::Unknown_id) {
|
||||||
|
Gpu::Buffer_id buffer_id { .value = id.value };
|
||||||
|
Gpu::Buffer_capability buffer_cap = _gpu_master.export_buffer(buffer_id);
|
||||||
|
import_buffer(buffer_cap, buffer_id);
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
Genode::error("handle: ", obj[i].handle, " invalid, ret=", ret);
|
Genode::error("handle: ", obj[i].handle, " invalid, ret=", ret);
|
||||||
@ -854,13 +864,6 @@ class Drm_call
|
|||||||
|
|
||||||
if (buffer)
|
if (buffer)
|
||||||
fn(*buffer);
|
fn(*buffer);
|
||||||
|
|
||||||
Gpu::Buffer_capability buffer_cap = _gpu_session.export_buffer(buffer->id());
|
|
||||||
_context_space.for_each<Drm::Context>([&](Drm::Context &context) {
|
|
||||||
try {
|
|
||||||
context.import_buffer(_heap, buffer_cap, buffer->id());
|
|
||||||
} catch (...) { }
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _free_buffer(Gpu::Buffer_id const id)
|
int _free_buffer(Gpu::Buffer_id const id)
|
||||||
@ -874,7 +877,7 @@ class Drm_call
|
|||||||
_resources.free_buffer(b.size);
|
_resources.free_buffer(b.size);
|
||||||
|
|
||||||
_context_space.for_each<Drm::Context>([&] (Drm::Context &context) {
|
_context_space.for_each<Drm::Context>([&] (Drm::Context &context) {
|
||||||
context.free_buffer(_heap, b.id()); });
|
context.free_buffer(b.id()); });
|
||||||
Genode::destroy(&_heap, &b);
|
Genode::destroy(&_heap, &b);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1105,19 +1108,11 @@ class Drm_call
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Drm::Context *context = new (_heap) Drm::Context(*gpu, fd, _context_space);
|
Drm::Context *context = new (_heap) Drm::Context(*gpu, _gpu_session, _heap,
|
||||||
|
fd, _context_space);
|
||||||
|
|
||||||
p->ctx_id = context->id();
|
p->ctx_id = context->id();
|
||||||
|
|
||||||
/* import all current buffers */
|
|
||||||
_buffer_space.for_each<Buffer>([&](Buffer &b) {
|
|
||||||
Gpu::Buffer_capability buffer_cap = _gpu_session.export_buffer(b.id());
|
|
||||||
try {
|
|
||||||
context->import_buffer(_heap, buffer_cap, b.id());
|
|
||||||
} catch (...) { }
|
|
||||||
});
|
|
||||||
|
|
||||||
Genode::error("CREATE Context: ", p->ctx_id, " gpu: ", gpu);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1125,11 +1120,10 @@ class Drm_call
|
|||||||
{
|
{
|
||||||
unsigned long ctx_id = reinterpret_cast<drm_i915_gem_context_destroy *>(arg)->ctx_id;
|
unsigned long ctx_id = reinterpret_cast<drm_i915_gem_context_destroy *>(arg)->ctx_id;
|
||||||
Context_id const id = Drm::Context::id(ctx_id);
|
Context_id const id = Drm::Context::id(ctx_id);
|
||||||
Genode::error("DESTROY Context: ", ctx_id);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_context_space.apply<Drm::Context>(id, [&] (Drm::Context &context) {
|
_context_space.apply<Drm::Context>(id, [&] (Drm::Context &context) {
|
||||||
context.free_buffers(_heap);
|
context.free_buffers();
|
||||||
Libc::close(context.fd());
|
Libc::close(context.fd());
|
||||||
destroy(_heap, &context);
|
destroy(_heap, &context);
|
||||||
});
|
});
|
||||||
@ -1465,7 +1459,8 @@ class Drm_call
|
|||||||
prime_handle = id;
|
prime_handle = id;
|
||||||
|
|
||||||
if (prime_handle.value != id.value) {
|
if (prime_handle.value != id.value) {
|
||||||
Genode::warning("prime handle changed: ", id.value);
|
if (verbose_ioctl)
|
||||||
|
Genode::warning("prime handle changed: ", id.value);
|
||||||
prime_handle = id;
|
prime_handle = id;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user