我正在尝试为 Linux 创建一个直接写入帧缓冲区 /dev/fb0 的应用程序。为了使其成为双缓冲,我尝试使虚拟屏幕成为屏幕大小的两倍。这是我写的程序:
struct fb_var_screeninfo screeninfo_var;
struct fb_fix_screeninfo screeninfo_fixed;
unsigned int* screenbuffer;
void gfx_init()
{
fb0 = open("/dev/fb0", O_RDWR);
if(fb0 == 0)
error("Could not open framebuffer located in /dev/fb0!");
if (ioctl(fb0, FBIOGET_FSCREENINFO, &screeninfo_fixed) == -1)
error("Could not retrive fixed screen info!");
if (ioctl(fb0, FBIOGET_VSCREENINFO, &screeninfo_var) == -1)
error("Could not retrive variable screen info!");
screeninfo_var.xres_virtual = screeninfo_var.xres;
screeninfo_var.yres_virtual = screeninfo_var.yres * 2;
screeninfo_var.width = screeninfo_var.xres;
screeninfo_var.height = screeninfo_var.yres;
screeninfo_var.xoffset = 0;
screeninfo_var.yoffset = 0;
if (ioctl(fb0, FBIOPUT_VSCREENINFO, &screeninfo_var) == …Run Code Online (Sandbox Code Playgroud) 根据我的理解,它们是不同的。Linux 帧缓冲区是一个软件对象,GPU 的内存是映射到 GPU 设备的物理内存。
我的问题如下:
1)我的理解正确吗?
2)如果是这样,以某种方式将两个东西合并成一个看起来可能会提高性能(我猜还有更多的技术细节为什么这是不可能的等等......)
3)如果没有,你能解释一下 Linux 帧缓冲区和 GPU 是如何协同工作的吗?
我想在未连接到任何物理显示器的帧缓冲区设备上测试一些文本绘制功能。有没有办法实时查看我正在绘制到 /dev/fb0 的内容?
我正在编写一个小型库来与 Linux 的帧缓冲区抽象接口。我的所有显卡都使用相同的像素格式(每个通道一个八位字节,四个通道,BGRA 排序),因此到目前为止,库仅采用这种格式。但是,如果我希望该库在任何 Linux 帧缓冲区上工作,帧缓冲区 API 提供了我必须使用的像素格式数据。你不需要知道帧缓冲区是如何工作的来回答这个问题(我希望),只需要一些我不熟悉的小技巧。这是我的标题中提供的像素格式信息:
/* Interpretation of offset for color fields: All offsets are from the right,
* inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
* can use the offset as right argument to <<). A pixel afterwards is a bit
* stream and is written to video memory as that unmodified.
*
* For pseudocolor: offset and length should be the same for all color
* components. Offset specifies the position …Run Code Online (Sandbox Code Playgroud) 一个可呈现的图像开始于VK_IMAGE_LAYOUT_UNDEFINED但VK_IMAGE_LAYOUT_PRESENT_SRC_KHR在它们被呈现一次之后。
很多例子做的过渡vkImages,以VK_IMAGE_LAYOUT_PRESENT_SRC_KHR立即创建后vkSwapchain。这允许他们使用VK_IMAGE_LAYOUT_PRESENT_SRC_KHRfor oldLayout。但是不允许在创建交换链后立即进行转换。
可呈现图像的使用必须仅在图像由 返回之后
vkAcquireNextImageKHR和由 呈现之前发生vkQueuePresentKHR。这包括转换图像布局和渲染命令。
我有哪些选项可以正确处理交换链图像布局?
我在我的应用程序中使用 Linux 帧缓冲区,并设置ioctl(tty0_fd, KDSETMODE, KD_GRAPHICS)为防止底层终端显示任何光标或文本,然后在正常程序终止时进行清理。
但是KD_GRAPHICS在异常终止时保持模式是一件坏事,因为它使系统无响应,我想知道如何解决这种情况。
注册的函数atexit()仅在正常终止时调用,因此无济于事。我可以为任何可以杀死应用程序但SIGKILL不能被捕获的信号注册我自己的处理程序。
窗口环境和其他程序如何处理这种情况?
我有一个系统,可以使用 C++ 中的 OpenGL 将不同的对象渲染成不同的 RGBA 纹理。我想将这些纹理叠加在一起,但我的问题是每个纹理都有 glClearColor 渲染到其中。
如何告诉 OpenGL 将纹理的 ClearColor 部分设为透明(0.0f alpha),以便我仍然可以看到其他图层后面的图层部分?
我正在使用 OpenCL 进行一些图像处理,并希望使用它将 RGBA 图像直接写入帧缓冲区。工作流程如下图所示:
1) 将帧缓冲区映射到用户空间。
2) 使用 clCreateBuffer 创建 OpenCL 缓冲区,标志为“CL_MEM_ALLOC_HOST_PTR”
3)使用clEnqueueMapBuffer将结果映射到framebuffer。
然而,这不起作用。屏幕上什么也没有。然后我发现帧缓冲区映射的虚拟地址与映射OpenCL的虚拟地址不同。有没有人做过从 GPU 到帧缓冲区的数据零复制移动?我应该使用什么方法来实现此目的有任何帮助吗?
一些关键代码:
if ((fd_fb = open("/dev/fb0", O_RDWR, 0)) < 0) {
printf("Unable to open /dev/fb0\n");
return -1;
}
fb0 = (unsigned char *)mmap(0, fb0_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
...
cmDevSrc4 = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, sizeof(cl_uchar) * imagesize * 4, NULL, &status);
...
fb0 = (unsigned char*)clEnqueueMapBuffer(cqCommandQueue, cmDevSrc4, CL_TRUE, CL_MAP_READ, 0, sizeof(cl_uchar) * imagesize * 4, 0, NULL, NULL, &ciErr);
Run Code Online (Sandbox Code Playgroud) 我想使用 Linux 以最有效的方式获取屏幕像素的 RGB 值。所以我决定使用 C 中的帧缓冲库(fb.h)来访问帧缓冲设备(/dev/fb0)并直接从中读取。
这是代码:
#include <stdint.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
int main() {
int fb_fd;
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
uint8_t *fb_p;
/* Open the frame buffer device */
fb_fd = open("/dev/fb0", O_RDWR);
if (fb_fd < 0) {
perror("Can't open /dev/fb0\n");
exit(EXIT_FAILURE);
}
/* Get fixed info */
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
perror("Can't get fixed info\n");
exit(EXIT_FAILURE);
} …Run Code Online (Sandbox Code Playgroud) 尝试在延迟着色之上实现抗锯齿,我尝试使用多重采样渲染缓冲区,然后使用缓冲区位块传输传递解析样本。
按照延迟着色的传统做法,我使用发出 3 个颜色输出的专用着色器来渲染场景:
然后将它们用于照明计算通道,从而产生最终的场景纹理
使用简单的着色器将场景纹理渲染到全屏四边形的屏幕上
正如您可能猜到的,渲染到屏幕时,屏幕上的 MSAA 不会应用于场景纹理的内容:为了实现抗锯齿,我因此选择在步骤 1) 中使用多重采样渲染缓冲区,并引入了额外的步骤1.1) 分辨率。当然,多重采样仅对彩色图是必要的/有用的,对其他两张图来说不是必需的/有用的。
我的问题是,显然,具有多个渲染缓冲区/颜色附件的帧缓冲区只能为相同类型的附件定义;这意味着如果一个附件经过多次采样,那么所有其他附件也必须经过多次采样。
这成为分辨率期间位置和法线缓冲区的一个问题,因为几何体和照明会因抗锯齿而受到影响。
// Create the frame buffer for deferred shading: 3 color attachments and a depth buffer
glGenFramebuffers(1, &gBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
{
// - Position color buffer
glGenRenderbuffers(1, &gPosition);
glBindRenderbuffer(GL_RENDERBUFFER, gPosition);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA16F, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, gPosition);
// - Normal color buffer
glGenRenderbuffers(1, &gNormal);
glBindRenderbuffer(GL_RENDERBUFFER, gNormal);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA16F, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, gNormal);
// …Run Code Online (Sandbox Code Playgroud) opengl multisampling framebuffer deferred-rendering deferred-shading
framebuffer ×10
linux ×6
c ×4
opengl ×2
gpu ×1
linux-kernel ×1
opencl ×1
pixelformat ×1
termination ×1
transparency ×1
vulkan ×1
zero-copy ×1