diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/README b/repos/pc/src/drivers/framebuffer/intel/pc/README index bb951c161a..9154856e12 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/README +++ b/repos/pc/src/drivers/framebuffer/intel/pc/README @@ -49,6 +49,16 @@ The virtual resolution can be enforced by: ! ! +The amount of memory used by the driver for the accounting of its available +buffer space is set by: + +! +! + +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: diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc b/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc index 429e5c9500..55c718b869 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc +++ b/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc @@ -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(); } diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/main.cc b/repos/pc/src/drivers/framebuffer/intel/pc/main.cc index f8a57f2d01..fe5690ce43 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/main.cc +++ b/repos/pc/src/drivers/framebuffer/intel/pc/main.cc @@ -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.