1 /* 2 * QEMU opengl shader helper functions 3 * 4 * Copyright (c) 2014 Red Hat 5 * 6 * Authors: 7 * Gerd Hoffmann <kraxel@redhat.com> 8 * 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: 15 * 16 * The above copyright notice and this permission notice shall be included in 17 * all copies or substantial portions of the Software. 18 * 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 25 * THE SOFTWARE. 26 */ 27 #include "qemu/osdep.h" 28 #include "qemu-common.h" 29 #include "ui/shader.h" 30 31 /* ---------------------------------------------------------------------- */ 32 33 GLuint qemu_gl_init_texture_blit(GLint texture_blit_prog) 34 { 35 static const GLfloat in_position[] = { 36 -1, -1, 37 1, -1, 38 -1, 1, 39 1, 1, 40 }; 41 GLint l_position; 42 GLuint vao, buffer; 43 44 glGenVertexArrays(1, &vao); 45 glBindVertexArray(vao); 46 47 /* this is the VBO that holds the vertex data */ 48 glGenBuffers(1, &buffer); 49 glBindBuffer(GL_ARRAY_BUFFER, buffer); 50 glBufferData(GL_ARRAY_BUFFER, sizeof(in_position), in_position, 51 GL_STATIC_DRAW); 52 53 l_position = glGetAttribLocation(texture_blit_prog, "in_position"); 54 glVertexAttribPointer(l_position, 2, GL_FLOAT, GL_FALSE, 0, 0); 55 glEnableVertexAttribArray(l_position); 56 57 glBindBuffer(GL_ARRAY_BUFFER, 0); 58 glBindVertexArray(0); 59 60 return vao; 61 } 62 63 void qemu_gl_run_texture_blit(GLint texture_blit_prog, 64 GLint texture_blit_vao) 65 { 66 glUseProgram(texture_blit_prog); 67 glBindVertexArray(texture_blit_vao); 68 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 69 } 70 71 /* ---------------------------------------------------------------------- */ 72 73 GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src) 74 { 75 GLuint shader; 76 GLint status, length; 77 char *errmsg; 78 79 shader = glCreateShader(type); 80 glShaderSource(shader, 1, &src, 0); 81 glCompileShader(shader); 82 83 glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 84 if (!status) { 85 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); 86 errmsg = g_malloc(length); 87 glGetShaderInfoLog(shader, length, &length, errmsg); 88 fprintf(stderr, "%s: compile %s error\n%s\n", __func__, 89 (type == GL_VERTEX_SHADER) ? "vertex" : "fragment", 90 errmsg); 91 g_free(errmsg); 92 return 0; 93 } 94 return shader; 95 } 96 97 GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag) 98 { 99 GLuint program; 100 GLint status, length; 101 char *errmsg; 102 103 program = glCreateProgram(); 104 glAttachShader(program, vert); 105 glAttachShader(program, frag); 106 glLinkProgram(program); 107 108 glGetProgramiv(program, GL_LINK_STATUS, &status); 109 if (!status) { 110 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); 111 errmsg = g_malloc(length); 112 glGetProgramInfoLog(program, length, &length, errmsg); 113 fprintf(stderr, "%s: link program: %s\n", __func__, errmsg); 114 g_free(errmsg); 115 return 0; 116 } 117 return program; 118 } 119 120 GLuint qemu_gl_create_compile_link_program(const GLchar *vert_src, 121 const GLchar *frag_src) 122 { 123 GLuint vert_shader, frag_shader, program; 124 125 vert_shader = qemu_gl_create_compile_shader(GL_VERTEX_SHADER, vert_src); 126 frag_shader = qemu_gl_create_compile_shader(GL_FRAGMENT_SHADER, frag_src); 127 if (!vert_shader || !frag_shader) { 128 return 0; 129 } 130 131 program = qemu_gl_create_link_program(vert_shader, frag_shader); 132 glDeleteShader(vert_shader); 133 glDeleteShader(frag_shader); 134 135 return program; 136 } 137