Oh, I see now...Brendan wrote: By different versions of the OpenGL library, I mean "Each version of the shared library would be tailored to a specific driver, so the interface between the userspace library and the driver would be implementor-defined.".
My plan was actually to provide some abstraction with the buffer. The fact that the rendering is done to a buffer rather than directly to a portion of the screen would not be exposed to the application itself; the application code would be written as normal. The window manager is responsible for compositing these buffers to form the full desktop. Only the window manager would have to deal with different versions of the library, and it could just communicate with several driver-like processes, one for each card.Brendan wrote: The job of a device driver is to provide an abstraction layer; so that other software doesn't need to care about underlying hardware details. For example, you wouldn't force applications to care about "cylinder, head, sector" for file IO would you?
For example, Application A might be rendering exclusively with Graphics Card A, and App B is using Card B, but the window manager can put App A on Card B's desktop and vice versa because neither application directly draws to the screen. The system would automatically assign each application to a card when it started and would try to keep the load balanced between cards.
It might not be the best solution, but it seems like it would be just fine for a compositing WM, which most modern OSes are using anyway. Of course, just splitting the draw calls could also work, but the downside is that for complex scenes, each card would have to process the same geometry, which might, depending on the scene, be less efficient than just passing a buffer, and some graphical effects (like deforming windows) would be difficult to implement in the window manager.
On a different note, I'm trying to work out why the firmware isn't giving me a memory map. Here's the code I'm using:
Code: Select all
//Get memory map
UINTN mapSize = 0;
EFI_MEMORY_DESCRIPTOR *memMap;
UINTN mapKey, descriptorSize;
UINT32 descriptorVersion;
//Places the correct size into mapSize
status = uefi_call_wrapper(bootServices->GetMemoryMap, 5, &mapSize, NULL, &mapKey, &descriptorSize, &descriptorVersion);
status = uefi_call_wrapper(bootServices->AllocatePages, 4, AllocateAnyPages, EfiLoaderData, (mapSize / 4096) + 1, &memMap);
if(status != EFI_SUCCESS) {
print(L"Error: unable to allocate memory map buffer\r\n");
return status;
}
//Actually get the memory map.
status = uefi_call_wrapper(bootServices->GetMemoryMap, 5, &mapSize, memMap, &mapKey, &descriptorSize, &descriptorVersion);
if(status != EFI_SUCCESS) {
print(L"Error: unable to obtain memory map\r\n");
if(status == EFI_BUFFER_TOO_SMALL) {
print(L"Buffer too small\r\n");
}
return status;
}
Is there a function to format a number as a string, or will I have to write that myself if I want to print a debug value?
I'm also having a tough time getting the EFI_LOAD_FILE_INTERFACE that I think is what I need to call LoadFile(). I'm trying this code, which is based on efilib:
Code: Select all
EFI_LOAD_FILE_INTERFACE *filesystem;
status = LibLocateProtocol(&LoadFileProtocol, &filesystem);
if(status != EFI_SUCCESS) {
print(L"Error getting EFI_LOAD_FILE_INTERFACE\r\n");
return status;
}
Man, I'm sure asking a lot of questions...and this topic is even in the wrong section of the forums. I must look like a complete newbie.
Anyway, thanks for your help so far!