mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 11:55:24 +00:00
gpu/intel: add support to report finished batches
- extend gpu multiplexer to report last completed execution buffer - on client side lookup finished buffers and disable busy state issue #4233
This commit is contained in:
parent
f8953de7ac
commit
b3147050cc
@ -40,8 +40,9 @@ class Gpu::Session_client : public Genode::Rpc_client<Session>
|
||||
Info info() const override {
|
||||
return call<Rpc_info>(); }
|
||||
|
||||
void exec_buffer(Genode::Dataspace_capability cap, Genode::size_t size) override {
|
||||
call<Rpc_exec_buffer>(cap, size); }
|
||||
Gpu::Info::Execution_buffer_sequence exec_buffer(Genode::Dataspace_capability cap,
|
||||
Genode::size_t size) override {
|
||||
return call<Rpc_exec_buffer>(cap, size); }
|
||||
|
||||
void completion_sigh(Genode::Signal_context_capability sigh) override {
|
||||
call<Rpc_completion_sigh>(sigh); }
|
||||
|
@ -42,11 +42,17 @@ struct Gpu::Info
|
||||
size_t aperture_size;
|
||||
Context_id ctx_id;
|
||||
|
||||
Info(Chip_id chip_id, Features features,
|
||||
size_t aperture_size, Context_id ctx_id)
|
||||
struct Execution_buffer_sequence {
|
||||
Genode::uint64_t id;
|
||||
} last_completed;
|
||||
|
||||
|
||||
Info(Chip_id chip_id, Features features, size_t aperture_size,
|
||||
Context_id ctx_id, Execution_buffer_sequence last)
|
||||
:
|
||||
chip_id(chip_id), features(features),
|
||||
aperture_size(aperture_size), ctx_id(ctx_id)
|
||||
aperture_size(aperture_size), ctx_id(ctx_id),
|
||||
last_completed(last)
|
||||
{ }
|
||||
};
|
||||
|
||||
@ -56,8 +62,9 @@ struct Gpu::Info
|
||||
*/
|
||||
struct Gpu::Session : public Genode::Session
|
||||
{
|
||||
struct Out_of_ram : Genode::Exception { };
|
||||
struct Out_of_caps : Genode::Exception { };
|
||||
struct Out_of_ram : Genode::Exception { };
|
||||
struct Out_of_caps : Genode::Exception { };
|
||||
struct Invalid_state : Genode::Exception { };
|
||||
|
||||
enum { REQUIRED_QUOTA = 1024 * 1024, CAP_QUOTA = 8, };
|
||||
|
||||
@ -79,8 +86,12 @@ struct Gpu::Session : public Genode::Session
|
||||
*
|
||||
* \param cap capability to buffer object containing the exec buffer
|
||||
* \param size size of the batch buffer in bytes
|
||||
*
|
||||
* \return execution buffer sequence number for complete checks
|
||||
*
|
||||
* \throw Invalid_state is thrown if the provided buffer is not valid, e.g not mapped
|
||||
*/
|
||||
virtual void exec_buffer(Genode::Dataspace_capability cap, Genode::size_t size) = 0;
|
||||
virtual Gpu::Info::Execution_buffer_sequence exec_buffer(Genode::Dataspace_capability cap, Genode::size_t size) = 0;
|
||||
|
||||
/**
|
||||
* Register completion signal handler
|
||||
@ -153,8 +164,9 @@ struct Gpu::Session : public Genode::Session
|
||||
*******************/
|
||||
|
||||
GENODE_RPC(Rpc_info, Info, info);
|
||||
GENODE_RPC(Rpc_exec_buffer, void, exec_buffer, Genode::Dataspace_capability,
|
||||
Genode::size_t);
|
||||
GENODE_RPC_THROW(Rpc_exec_buffer, Gpu::Info::Execution_buffer_sequence, exec_buffer,
|
||||
GENODE_TYPE_LIST(Invalid_state),
|
||||
Genode::Dataspace_capability, Genode::size_t);
|
||||
GENODE_RPC(Rpc_completion_sigh, void, completion_sigh,
|
||||
Genode::Signal_context_capability);
|
||||
GENODE_RPC_THROW(Rpc_alloc_buffer, Genode::Dataspace_capability, alloc_buffer,
|
||||
|
@ -1366,15 +1366,16 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
|
||||
struct Buffer
|
||||
{
|
||||
Genode::Dataspace_capability cap;
|
||||
Gpu::addr_t ppgtt_va;
|
||||
|
||||
enum { INVALID_FENCE = 0xff, };
|
||||
Genode::uint32_t fenced;
|
||||
Gpu::addr_t ppgtt_va { };
|
||||
bool ppgtt_va_valid { false };
|
||||
|
||||
enum { INVALID_FENCE = 0xff };
|
||||
Genode::uint32_t fenced { INVALID_FENCE };
|
||||
|
||||
Igd::Ggtt::Mapping map { };
|
||||
|
||||
Buffer(Genode::Dataspace_capability cap)
|
||||
: cap(cap), ppgtt_va(0), fenced(INVALID_FENCE) { }
|
||||
Buffer(Genode::Dataspace_capability cap) : cap(cap) { }
|
||||
|
||||
virtual ~Buffer() { }
|
||||
};
|
||||
@ -1457,31 +1458,37 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
|
||||
Info info() const override
|
||||
{
|
||||
Genode::size_t const aperture_size = Igd::Device::Vgpu::APERTURE_SIZE;
|
||||
return Info(_device.id(), _device.features(), aperture_size, _vgpu.id());
|
||||
return Info(_device.id(), _device.features(), aperture_size,
|
||||
_vgpu.id(), { .id = _vgpu.complete_seqno() });
|
||||
}
|
||||
|
||||
void exec_buffer(Genode::Dataspace_capability cap, Genode::size_t) override
|
||||
Gpu::Info::Execution_buffer_sequence exec_buffer(Genode::Dataspace_capability cap,
|
||||
Genode::size_t) override
|
||||
{
|
||||
Igd::addr_t ppgtt_va = 0;
|
||||
bool found = false;
|
||||
|
||||
auto lookup = [&] (Buffer &buffer) {
|
||||
_buffer_registry.for_each([&] (Buffer &buffer) {
|
||||
if (!(buffer.cap == cap)) { return; }
|
||||
ppgtt_va = buffer.ppgtt_va;
|
||||
};
|
||||
_buffer_registry.for_each(lookup);
|
||||
|
||||
if (!ppgtt_va) {
|
||||
Genode::error("Invalid execbuffer");
|
||||
Genode::Signal_transmitter(_vgpu.completion_sigh()).submit();
|
||||
return;
|
||||
}
|
||||
if (!buffer.ppgtt_va_valid) {
|
||||
Genode::error("Invalid execbuffer");
|
||||
Genode::Signal_transmitter(_vgpu.completion_sigh()).submit();
|
||||
throw Gpu::Session::Invalid_state();
|
||||
}
|
||||
|
||||
_vgpu.setup_ring_buffer(ppgtt_va, _device._ggtt->scratch_page());
|
||||
_vgpu.setup_ring_buffer(buffer.ppgtt_va, _device._ggtt->scratch_page());
|
||||
found = true;
|
||||
});
|
||||
|
||||
if (!found)
|
||||
throw Gpu::Session::Invalid_state();
|
||||
|
||||
try {
|
||||
_device.vgpu_enqueue(_vgpu);
|
||||
return { .id = _vgpu.current_seqno() };
|
||||
} catch (Igd::Device::Already_scheduled &e) {
|
||||
Genode::error("vGPU already scheduled");
|
||||
return { .id = _vgpu.current_seqno() }; /* XXX */
|
||||
}
|
||||
}
|
||||
|
||||
@ -1604,7 +1611,7 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
|
||||
auto lookup_and_map = [&] (Buffer &buffer) {
|
||||
if (!(buffer.cap == cap)) { return; }
|
||||
|
||||
if (buffer.ppgtt_va != 0) {
|
||||
if (buffer.ppgtt_va_valid) {
|
||||
Genode::error("buffer already mapped");
|
||||
return;
|
||||
}
|
||||
@ -1616,6 +1623,7 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
|
||||
Genode::addr_t const phys_addr = buf.phys_addr();
|
||||
_vgpu.rcs_map_ppgtt(va, phys_addr, actual_size);
|
||||
buffer.ppgtt_va = va;
|
||||
buffer.ppgtt_va_valid = true;
|
||||
result = true;
|
||||
} catch (Igd::Device::Could_not_map_buffer) {
|
||||
/* FIXME do not result in Out_of_ram */
|
||||
@ -1643,7 +1651,7 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
|
||||
auto lookup_and_unmap = [&] (Buffer &buffer) {
|
||||
if (!(buffer.cap == cap)) { return; }
|
||||
|
||||
if (buffer.ppgtt_va == 0) {
|
||||
if (!buffer.ppgtt_va_valid) {
|
||||
Genode::error("buffer not mapped");
|
||||
return;
|
||||
}
|
||||
@ -1656,7 +1664,7 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
|
||||
Genode::Dataspace_client buf(cap);
|
||||
Genode::size_t const actual_size = buf.size();
|
||||
_vgpu.rcs_unmap_ppgtt(va, actual_size);
|
||||
buffer.ppgtt_va = 0;
|
||||
buffer.ppgtt_va_valid = false;
|
||||
};
|
||||
_buffer_registry.for_each(lookup_and_unmap);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user