2 * QEMU opengl shader helper functions
4 * Copyright (c) 2014 Red Hat
7 * Gerd Hoffmann <kraxel@redhat.com>
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 #include "qemu/osdep.h"
28 #include "qemu-common.h"
29 #include "ui/shader.h"
31 #include "shader/texture-blit-vert.h"
32 #include "shader/texture-blit-flip-vert.h"
33 #include "shader/texture-blit-frag.h"
36 GLint texture_blit_prog
;
37 GLint texture_blit_flip_prog
;
38 GLint texture_blit_vao
;
41 /* ---------------------------------------------------------------------- */
43 static GLuint
qemu_gl_init_texture_blit(GLint texture_blit_prog
)
45 static const GLfloat in_position
[] = {
54 glGenVertexArrays(1, &vao
);
55 glBindVertexArray(vao
);
57 /* this is the VBO that holds the vertex data */
58 glGenBuffers(1, &buffer
);
59 glBindBuffer(GL_ARRAY_BUFFER
, buffer
);
60 glBufferData(GL_ARRAY_BUFFER
, sizeof(in_position
), in_position
,
63 l_position
= glGetAttribLocation(texture_blit_prog
, "in_position");
64 glVertexAttribPointer(l_position
, 2, GL_FLOAT
, GL_FALSE
, 0, 0);
65 glEnableVertexAttribArray(l_position
);
67 glBindBuffer(GL_ARRAY_BUFFER
, 0);
73 void qemu_gl_run_texture_blit(QemuGLShader
*gls
, bool flip
)
76 ? gls
->texture_blit_flip_prog
77 : gls
->texture_blit_prog
);
78 glBindVertexArray(gls
->texture_blit_vao
);
79 glDrawArrays(GL_TRIANGLE_STRIP
, 0, 4);
82 /* ---------------------------------------------------------------------- */
84 static GLuint
qemu_gl_create_compile_shader(GLenum type
, const GLchar
*src
)
90 shader
= glCreateShader(type
);
91 glShaderSource(shader
, 1, &src
, 0);
92 glCompileShader(shader
);
94 glGetShaderiv(shader
, GL_COMPILE_STATUS
, &status
);
96 glGetShaderiv(shader
, GL_INFO_LOG_LENGTH
, &length
);
97 errmsg
= g_malloc(length
);
98 glGetShaderInfoLog(shader
, length
, &length
, errmsg
);
99 fprintf(stderr
, "%s: compile %s error\n%s\n", __func__
,
100 (type
== GL_VERTEX_SHADER
) ? "vertex" : "fragment",
108 static GLuint
qemu_gl_create_link_program(GLuint vert
, GLuint frag
)
111 GLint status
, length
;
114 program
= glCreateProgram();
115 glAttachShader(program
, vert
);
116 glAttachShader(program
, frag
);
117 glLinkProgram(program
);
119 glGetProgramiv(program
, GL_LINK_STATUS
, &status
);
121 glGetProgramiv(program
, GL_INFO_LOG_LENGTH
, &length
);
122 errmsg
= g_malloc(length
);
123 glGetProgramInfoLog(program
, length
, &length
, errmsg
);
124 fprintf(stderr
, "%s: link program: %s\n", __func__
, errmsg
);
131 static GLuint
qemu_gl_create_compile_link_program(const GLchar
*vert_src
,
132 const GLchar
*frag_src
)
134 GLuint vert_shader
, frag_shader
, program
;
136 vert_shader
= qemu_gl_create_compile_shader(GL_VERTEX_SHADER
, vert_src
);
137 frag_shader
= qemu_gl_create_compile_shader(GL_FRAGMENT_SHADER
, frag_src
);
138 if (!vert_shader
|| !frag_shader
) {
142 program
= qemu_gl_create_link_program(vert_shader
, frag_shader
);
143 glDeleteShader(vert_shader
);
144 glDeleteShader(frag_shader
);
149 /* ---------------------------------------------------------------------- */
151 QemuGLShader
*qemu_gl_init_shader(void)
153 QemuGLShader
*gls
= g_new0(QemuGLShader
, 1);
155 gls
->texture_blit_prog
= qemu_gl_create_compile_link_program
156 (texture_blit_vert_src
, texture_blit_frag_src
);
157 gls
->texture_blit_flip_prog
= qemu_gl_create_compile_link_program
158 (texture_blit_flip_vert_src
, texture_blit_frag_src
);
159 if (!gls
->texture_blit_prog
|| !gls
->texture_blit_flip_prog
) {
163 gls
->texture_blit_vao
=
164 qemu_gl_init_texture_blit(gls
->texture_blit_prog
);
169 void qemu_gl_fini_shader(QemuGLShader
*gls
)