gpt4 book ai didi

c - glPopMatrix() 大喊 "unsupported texture format in setup_hardware_state"

转载 作者:IT王子 更新时间:2023-10-29 00:53:52 25 4
gpt4 key购买 nike

我正尝试在 Linux 专用视频播放器中进行一些优化以提高性能,因为播放 MP4 文件对 CPU 占用很大,因为视频帧是用 YV12 编码的 并且 OpenGL 不提供显示此格式的 native 方式。现在有一个代码在 CPU 上运行,在将图像发送到 GPU 进行显示之前将 YV12 转换为 RGB,这会占用 100% 的 CPU 处理。

我目前正在研究如何解码 YV12 帧而无需编写着色器来执行 YV12 -> RGB 转换。据我所知,一种方法是通过 GL_MESA_ycbcr_texture,我的系统显然支持它(由 glxinfo 报告)。

在这个 Fedora Box 中,我有一个 ATI Technologies Inc RV610 视频设备 [Radeon HD 2400 PRO],这是一个不错的视频卡。然后,我下载了 yuvrect测试并进行一些更改以替换 GL_TEXTURE_RECTANGLE_NV 以获取此卡支持的纹理:GL_TEXTURE_RECTANGLE_ARB

但是,当我执行这个修改后的应用程序时,它会输出:

The MESA driver reports *unsupported texture format in setup_hardware_state*

我注意到当从 Display() 回调执行 glPopMatrix(); 时会出现此错误。现在,这看起来不像是我的应用程序中的错误,因为我在另一个 Fedora 机器(相同系统)上运行了完全相同的代码,它具有不同的视频卡:Intel Corporation Sandy Bridge Integrated图形 Controller (修订版 09),它工作得很好。

这两个二进制文件之间唯一可见的区别是它们所链接的库。在(有问题的)ATI 卡 ldd 报告中:

linux-gate.so.1 =>  (0x00da3000)
libGL.so.1 => /usr/lib/libGL.so.1 (0x077bd000)
libGLU.so.1 => /usr/lib/libGLU.so.1 (0x0783b000)
libglut.so.3 => /usr/lib/libglut.so.3 (0x005a9000)
libGLEW.so.1.5 => /usr/lib/libGLEW.so.1.5 (0x00aa3000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x057e2000)
libm.so.6 => /lib/libm.so.6 (0x004e4000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x0053f000)
libc.so.6 => /lib/libc.so.6 (0x00358000)
libX11.so.6 => /usr/lib/libX11.so.6 (0x0071b000)
libXext.so.6 => /usr/lib/libXext.so.6 (0x009c5000)
libXdamage.so.1 => /usr/lib/libXdamage.so.1 (0x00af7000)
libXfixes.so.3 => /usr/lib/libXfixes.so.3 (0x00b76000)
libXxf86vm.so.1 => /usr/lib/libXxf86vm.so.1 (0x0014e000)
libdrm.so.2 => /usr/lib/libdrm.so.2 (0x00101000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00510000)
libdl.so.2 => /lib/libdl.so.2 (0x0052d000)
libXi.so.6 => /usr/lib/libXi.so.6 (0x00110000)
/lib/ld-linux.so.2 (0x00337000)
libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00859000)
librt.so.1 => /lib/librt.so.1 (0x00534000)
libXau.so.6 => /usr/lib/libXau.so.6 (0x00854000)

与此同时,在 Intel 卡上您可以看到它与 libv4l 和其他一些库链接,而 ATI 则没有!我想知道这是否与我面临的问题有关:

linux-gate.so.1 =>  (0x008d6000)
/usr/lib/libv4l/v4l1compat.so (0x00345000)
libGL.so.1 => /usr/lib/libGL.so.1 (0x4fb85000)
libGLU.so.1 => /usr/lib/libGLU.so.1 (0x4fc10000)
libglut.so.3 => /usr/lib/libglut.so.3 (0x005a9000)
libGLEW.so.1.5 => /usr/lib/libGLEW.so.1.5 (0x4fc82000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x42ca7000)
libm.so.6 => /lib/libm.so.6 (0x41fbc000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x42017000)
libc.so.6 => /lib/libc.so.6 (0x41e30000)
libv4l1.so.0 => /usr/lib/libv4l1.so.0 (0x00110000)
libX11.so.6 => /usr/lib/libX11.so.6 (0x421f8000)
libXext.so.6 => /usr/lib/libXext.so.6 (0x424c0000)
libXdamage.so.1 => /usr/lib/libXdamage.so.1 (0x42c0e000)
libXfixes.so.3 => /usr/lib/libXfixes.so.3 (0x42d98000)
libXxf86vm.so.1 => /usr/lib/libXxf86vm.so.1 (0x432a2000)
libdrm.so.2 => /usr/lib/libdrm.so.2 (0x4247b000)
libpthread.so.0 => /lib/libpthread.so.0 (0x41fe8000)
libdl.so.2 => /lib/libdl.so.2 (0x42005000)
libXi.so.6 => /usr/lib/libXi.so.6 (0x42748000)
/lib/ld-linux.so.2 (0x41e0f000)
libv4l2.so.0 => /usr/lib/libv4l2.so.0 (0x4217c000)
libxcb.so.1 => /usr/lib/libxcb.so.1 (0x42337000)
librt.so.1 => /lib/librt.so.1 (0x4200c000)
libv4lconvert.so.0 => /usr/lib/libv4lconvert.so.0 (0x42357000)
libXau.so.6 => /usr/lib/libXau.so.6 (0x421f3000)
libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0x43317000)

如果你想运行下面的例子,你需要 readtex.c , readtex.hgirl.rgb ,并用以下命令编译:g++ yuvrect.cpp -o yuvrect -lGL -lGLU -lglut -lGLEW

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/glut.h>

#include "readtex.c" /* I know, this is a hack. */

#define TEXTURE_FILE "girl.rgb"

static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
static GLint ImgWidth, ImgHeight;
static GLushort *ImageYUV = NULL;


static void DrawObject(void)
{
glBegin(GL_QUADS);

glTexCoord2f(0, 0);
glVertex2f(-1.0, -1.0);

glTexCoord2f(ImgWidth, 0);
glVertex2f(1.0, -1.0);

glTexCoord2f(ImgWidth, ImgHeight);
glVertex2f(1.0, 1.0);

glTexCoord2f(0, ImgHeight);
glVertex2f(-1.0, 1.0);

glEnd();
}


static void Display( void )
{
glClear( GL_COLOR_BUFFER_BIT );

glPushMatrix();
glRotatef(Xrot, 1.0, 0.0, 0.0);
glRotatef(Yrot, 0.0, 1.0, 0.0);
glRotatef(Zrot, 0.0, 0.0, 1.0);
DrawObject();
glPopMatrix(); // <--- error message comes from this call

glutSwapBuffers();
}


static void Reshape( int width, int height )
{
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0.0, 0.0, -15.0 );
}


static void Key( unsigned char key, int x, int y )
{
(void) x;
(void) y;
switch (key) {
case 27:
exit(0);
break;
}
glutPostRedisplay();
}


static void SpecialKey( int key, int x, int y )
{
float step = 3.0;
(void) x;
(void) y;

switch (key) {
case GLUT_KEY_UP:
Xrot += step;
break;
case GLUT_KEY_DOWN:
Xrot -= step;
break;
case GLUT_KEY_LEFT:
Yrot += step;
break;
case GLUT_KEY_RIGHT:
Yrot -= step;
break;
}
glutPostRedisplay();
}

static void Init( int argc, char *argv[] )
{
GLuint texObj = 100;
const char *file;

printf("Checking GL_ARB_texture_rectangle\n");
if (!glutExtensionSupported("GL_ARB_texture_rectangle")) {
printf("Sorry, GL_NV_texture_rectangle is required\n");
exit(0);
}

printf("Checking GL_MESA_ycbcr_texture\n");
if (!glutExtensionSupported("GL_MESA_ycbcr_texture")) {
printf("Sorry, GL_MESA_ycbcr_texture is required\n");
exit(0);
}

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texObj);
#ifdef LINEAR_FILTER
/* linear filtering looks much nicer but is much slower for Mesa */
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#else
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
#endif

if (argc > 1)
file = argv[1];
else
file = TEXTURE_FILE;

ImageYUV = LoadYUVImage(file, &ImgWidth, &ImgHeight);
if (!ImageYUV) {
printf("Couldn't read %s\n", TEXTURE_FILE);
exit(0);
}

printf("Image: %dx%d\n", ImgWidth, ImgHeight);

printf("Calling glTexImage2D\n");
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
GL_YCBCR_MESA, ImgWidth, ImgHeight, 0,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, ImageYUV);
printf("Called glTexImage2D\n");
assert(glGetError() == GL_NO_ERROR);
printf("* Assert #1\n");

glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
0, 0, ImgWidth, ImgHeight,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, ImageYUV);

assert(glGetError() == GL_NO_ERROR);
printf("* Assert #2\n");

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glEnable(GL_TEXTURE_RECTANGLE_ARB);

glShadeModel(GL_FLAT);
glClearColor(0.3, 0.3, 0.4, 1.0);

if (argc > 1 && strcmp(argv[1], "-info")==0) {
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
}
}


int main( int argc, char *argv[] )
{
glutInit( &argc, argv );
glutInitWindowSize( 300, 300 );
glutInitWindowPosition( 0, 0 );
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
glutCreateWindow(argv[0] );
glewInit();

Init( argc, argv );

glutReshapeFunc( Reshape );
glutKeyboardFunc( Key );
glutSpecialFunc( SpecialKey );
glutDisplayFunc( Display );

glutMainLoop();
return 0;
}

伙计们,有什么解决这个问题的技巧吗?

最佳答案

这很可能是驱动程序错误或其他原因造成的。我不会帮你的。然而,回避着色器是不值得的。使用着色器,您可以忘记 GL_MESA_ycbcr_texture 并使您的应用程序更兼容。

我们将使用普通的旧 GL_LUMINANCE_ALPHA 格式,因此图像加载变为:

glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
GL_LUMINANCE_ALPHA, ImgWidth, ImgHeight, 0,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, ImageYUV);

glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
0, 0, ImgWidth, ImgHeight,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, ImageYUV);

然后关于着色器:

static const char *p_s_vertex_shader =
"varying vec2 t;"
"void main()"
"{"
" t = gl_MultiTexCoord0.xy;"
" gl_Position = ftransform();"
"}";
static const char *p_s_fragment_shader =
"#extension GL_ARB_texture_rectangle : enable\n"
"varying vec2 t;"
"uniform sampler2DRect tex;"
"void main()"
"{"
" vec2 tcEven = vec2(floor(t.x * .5) * 2.0, t.y);"
" vec2 tcOdd = vec2(tcEven.x + 1.0, t.y);"
" float Cb = texture2DRect(tex, tcEven).x - .5;"
" float Cr = texture2DRect(tex, tcOdd).x - .5;"
" float y = texture2DRect(tex, t).w;" // redundant texture read optimized away by texture cache
" float r = y + 1.28033 * Cr;"
" float g = y - .21482 * Cb - .38059 * Cr;"
" float b = y + 2.12798 * Cb;"
" gl_FragColor = vec4(r, g, b, 1.0);"
"}";
int v = glCreateShader(GL_VERTEX_SHADER);
int f = glCreateShader(GL_FRAGMENT_SHADER);
int p = glCreateProgram();
glShaderSource(v, 1, &p_s_vertex_shader, 0);
glShaderSource(f, 1, &p_s_fragment_shader, 0);
glCompileShader(v);
//CheckShader(v);
glCompileShader(f);
//CheckShader(f);
glAttachShader(p, v);
glAttachShader(p, f);
glLinkProgram(p);
glUseProgram(p);
glUniform1i(glGetUniformLocation(p, "tex"), 0);

这是在纹理之后,在 Init() 末尾的某个地方。就是这样,就像一个魅力。对于调试,最好也包含 CheckShader()(它会报告着色器中的编译错误):

bool CheckShader(int n_shader_object)
{
int n_tmp;
glGetShaderiv(n_shader_object, GL_COMPILE_STATUS, &n_tmp);
bool b_compiled = n_tmp == GL_TRUE;
int n_log_length;
glGetShaderiv(n_shader_object, GL_INFO_LOG_LENGTH, &n_log_length);
// query status ...

if(n_log_length > 1) {
char *p_s_temp_info_log;
if(!(p_s_temp_info_log = (char*)malloc(n_log_length)))
return false;
int n_tmp;
glGetShaderInfoLog(n_shader_object, n_log_length, &n_tmp,
p_s_temp_info_log);
assert(n_tmp <= n_log_length);

fprintf(stderr, "%s\n", p_s_temp_info_log);
free(p_s_temp_info_log);
}
// get/concat info-log

return b_compiled;
}

着色器版本可能会比硬件优化版本慢一点,但我想说这没什么好担心的。

如果您决定尝试一下代码,并且遇到任何问题,请告诉我...

编辑:在 ATi 上运行这个实际上是有问题的,最后证明是传递可变变量“t”时出错,换句话说这是行不通的:

static const char *p_s_vertex_shader =
"varying vec2 t;"
"void main()"
"{"
" t = gl_MultiTexCoord0.xy;"
" gl_Position = ftransform();"
"}";
static const char *p_s_fragment_shader =
"#extension GL_ARB_texture_rectangle : enable\n"
"varying vec2 t;"
"uniform sampler2DRect tex;"
"void main()"
"{"
" gl_FragColor = texture2DRect(tex, t);"
"}";

要轻松解决此问题,只需移除顶点着色器并让固定管线写入纹理坐标即可。所以这也适用于 ATi:

static const char *p_s_vertex_shader = null; // no vertex shader
static const char *p_s_fragment_shader =
"#extension GL_ARB_texture_rectangle : enable\n"
"uniform sampler2DRect tex;"
"void main()"
"{"
" vec2 t = gl_TexCoord[0];" // use fixed pipeline output
" gl_FragColor = texture2DRect(tex, t);"
"}";

关于c - glPopMatrix() 大喊 "unsupported texture format in setup_hardware_state",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8927546/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com