pc_intel_fb: configure max framebuffer memory

This commit introduces the means to configure the framebuffer memory
used by the driver for sizing its buffers.

Originally the avail memory was derived from the avail ram in the PD
session, which roughly corresponds to configured RAM quota.
However, since it is only used in a virtual capacity, we can decouple
it from the actual memory and set to a value that accommodates larger
framebuffer resolutions like 3840x2160. If the configured RAM quota
is not enough to satisfy an allocation request the client will issue
a resource request.

Issue #5174.
This commit is contained in:
Josef Söntgen 2024-04-12 14:21:56 +02:00 committed by Christian Helmuth
parent b086996438
commit 5dce61563e
3 changed files with 57 additions and 1 deletions

View File

@ -49,6 +49,16 @@ The virtual resolution can be enforced by:
! <config force_width="1024" force_height="768">
! </config>
The amount of memory used by the driver for the accounting of its available
buffer space is set by:
! <config max_framebuffer_memory="64M">
! </config>
The default and minimal value is '64M' and suffices for resolutions of at
least '3840x2160'. How much actual memory is used depends on the configured
resolution.
To present all available connectors and their possible resolutions to the user,
the driver is able to deliver a corresponding report, which can be enabled
in the configuration as follows:

View File

@ -17,6 +17,8 @@
/* local includes */
#include "lx_emul.h"
extern unsigned long long driver_max_framebuffer_memory(void);
unsigned short emul_intel_gmch_control_reg()
{
@ -39,5 +41,5 @@ unsigned short emul_intel_gmch_control_reg()
unsigned long long emul_avail_ram()
{
return Lx_kit::env().env.pd().avail_ram().value;
return driver_max_framebuffer_memory();
}

View File

@ -164,6 +164,43 @@ struct Framebuffer::Driver
if (force_width && force_height)
fn(force_width, force_height);
}
unsigned long long max_framebuffer_memory()
{
/*
* The max framebuffer memory is virtual in nature and denotes how
* the driver sizes its buffer space. When actual memory is used and
* the available RAM quota is not enough the component will issue a
* resource request.
*
* As the available memory is used during the initialization of the
* driver and is not queried afterwards it is safe to acquired it
* only once. Since it is used to size the GEM buffer pool set the amount
* of memory so that it includes the currently anticipated resolutions
* (e.g. 3840x2160) and is in line with the default value of the Intel GPU
* multiplexer.
*/
static unsigned long long _framebuffer_memory = 0;
if (_framebuffer_memory)
return _framebuffer_memory;
enum : unsigned { DEFAULT_FB_MEMORY = 64u << 20, };
auto framebuffer_memory = Number_of_bytes(DEFAULT_FB_MEMORY);
if (config.valid())
framebuffer_memory =
config.xml().attribute_value("max_framebuffer_memory",
framebuffer_memory);
if (framebuffer_memory < DEFAULT_FB_MEMORY) {
warning("configured framebuffer memory too small, use default of ",
Number_of_bytes(DEFAULT_FB_MEMORY));
framebuffer_memory = Number_of_bytes(DEFAULT_FB_MEMORY);
}
_framebuffer_memory = framebuffer_memory;
return _framebuffer_memory;
}
};
@ -267,6 +304,13 @@ void Framebuffer::Driver::lookup_config(char const * const name,
}
unsigned long long driver_max_framebuffer_memory(void)
{
Genode::Env &env = Lx_kit::env().env;
return driver(env).max_framebuffer_memory();
}
/**
* Can be called already as side-effect of `lx_emul_start_kernel`,
* that's why the Driver object needs to be constructed already here.