mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-27 18:51:41 +02:00
API for Uniform Block Objects
This commit is contained in:
63
kitty/gl.h
63
kitty/gl.h
@@ -425,6 +425,16 @@ GetUniformLocation(PyObject UNUSED *self, PyObject *args) {
|
|||||||
return PyLong_FromLong((long) ans);
|
return PyLong_FromLong((long) ans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
GetUniformBlockIndex(PyObject UNUSED *self, PyObject *args) {
|
||||||
|
char *name;
|
||||||
|
unsigned int program_id;
|
||||||
|
if(!PyArg_ParseTuple(args, "Is", &program_id, &name)) return NULL;
|
||||||
|
GLuint ans = glGetUniformBlockIndex(program_id, name);
|
||||||
|
if (ans == GL_INVALID_INDEX) { PyErr_SetString(PyExc_ValueError, "No such uniform block is active"); return NULL; }
|
||||||
|
return PyLong_FromUnsignedLong((unsigned long) ans);
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
GetAttribLocation(PyObject UNUSED *self, PyObject *args) {
|
GetAttribLocation(PyObject UNUSED *self, PyObject *args) {
|
||||||
char *name;
|
char *name;
|
||||||
@@ -435,6 +445,44 @@ GetAttribLocation(PyObject UNUSED *self, PyObject *args) {
|
|||||||
return PyLong_FromLong((long) ans);
|
return PyLong_FromLong((long) ans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
get_uniform_block_size(PyObject UNUSED *self, PyObject *args) {
|
||||||
|
unsigned int program_id, block_index;
|
||||||
|
if(!PyArg_ParseTuple(args, "II", &program_id, &block_index)) return NULL;
|
||||||
|
GLint ans;
|
||||||
|
glGetActiveUniformBlockiv(program_id, block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ans);
|
||||||
|
CHECK_ERROR;
|
||||||
|
return PyLong_FromLong((long) ans);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
get_uniform_block_offsets(PyObject UNUSED *self, PyObject *args) {
|
||||||
|
unsigned int program_id;
|
||||||
|
PyObject *pynames;
|
||||||
|
if(!PyArg_ParseTuple(args, "IO", &program_id, &pynames)) return NULL;
|
||||||
|
if (!PySequence_Check(pynames)) { PyErr_SetString(PyExc_TypeError, "names must be a sequence"); return NULL; }
|
||||||
|
GLsizei count = PySequence_Size(pynames);
|
||||||
|
char **names = PyMem_Calloc(count, sizeof(char*));
|
||||||
|
GLuint *indices = PyMem_Calloc(count, sizeof(GLuint));
|
||||||
|
GLint *offsets = PyMem_Calloc(count, sizeof(GLint));
|
||||||
|
PyObject *ans = PyTuple_New(count);
|
||||||
|
if (ans == NULL || indices == NULL || names == NULL) return PyErr_NoMemory();
|
||||||
|
for (GLsizei i = 0; i < count; i++) {
|
||||||
|
PyObject *t = PySequence_ITEM(pynames, i);
|
||||||
|
names[i] = PyUnicode_AsUTF8(t);
|
||||||
|
Py_CLEAR(t);
|
||||||
|
}
|
||||||
|
glGetUniformIndices(program_id, count, (const GLchar * const*)names, indices);
|
||||||
|
glGetActiveUniformsiv(program_id, count, indices, GL_UNIFORM_OFFSET, offsets);
|
||||||
|
for (GLsizei i = 0; i < count; i++) PyTuple_SET_ITEM(ans, i, PyLong_FromLong(offsets[i]));
|
||||||
|
PyMem_Free(names); PyMem_Free(indices); PyMem_Free(offsets);
|
||||||
|
if (_enable_error_checking) {
|
||||||
|
SET_GL_ERR;
|
||||||
|
if (PyErr_Occurred()) { Py_CLEAR(ans); return NULL; }
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
UseProgram(PyObject UNUSED *self, PyObject *val) {
|
UseProgram(PyObject UNUSED *self, PyObject *val) {
|
||||||
unsigned long program_id = PyLong_AsUnsignedLong(val);
|
unsigned long program_id = PyLong_AsUnsignedLong(val);
|
||||||
@@ -620,6 +668,15 @@ BindBuffer(PyObject UNUSED *self, PyObject *args) {
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
BindBufferBase(PyObject UNUSED *self, PyObject *args) {
|
||||||
|
int tgt; unsigned int index, buf_id;
|
||||||
|
if (!PyArg_ParseTuple(args, "iII", &tgt, &index, &buf_id)) return NULL;
|
||||||
|
glBindBufferBase(tgt, index, buf_id);
|
||||||
|
CHECK_ERROR;
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
TexBuffer(PyObject UNUSED *self, PyObject *args) {
|
TexBuffer(PyObject UNUSED *self, PyObject *args) {
|
||||||
int tgt, fmt; unsigned int buf_id;
|
int tgt, fmt; unsigned int buf_id;
|
||||||
@@ -777,7 +834,7 @@ int add_module_gl_constants(PyObject *module) {
|
|||||||
GLC(GL_R8); GLC(GL_RED); GLC(GL_UNSIGNED_BYTE); GLC(GL_R32UI); GLC(GL_RGB32UI); GLC(GL_RGBA);
|
GLC(GL_R8); GLC(GL_RED); GLC(GL_UNSIGNED_BYTE); GLC(GL_R32UI); GLC(GL_RGB32UI); GLC(GL_RGBA);
|
||||||
GLC(GL_TEXTURE_BUFFER); GLC(GL_STATIC_DRAW); GLC(GL_STREAM_DRAW);
|
GLC(GL_TEXTURE_BUFFER); GLC(GL_STATIC_DRAW); GLC(GL_STREAM_DRAW);
|
||||||
GLC(GL_SRC_ALPHA); GLC(GL_ONE_MINUS_SRC_ALPHA);
|
GLC(GL_SRC_ALPHA); GLC(GL_ONE_MINUS_SRC_ALPHA);
|
||||||
GLC(GL_BLEND); GLC(GL_FLOAT); GLC(GL_UNSIGNED_INT); GLC(GL_ARRAY_BUFFER);
|
GLC(GL_BLEND); GLC(GL_FLOAT); GLC(GL_UNSIGNED_INT); GLC(GL_ARRAY_BUFFER); GLC(GL_UNIFORM_BUFFER);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,6 +845,8 @@ int add_module_gl_constants(PyObject *module) {
|
|||||||
{"replace_or_create_buffer", (PyCFunction)replace_or_create_buffer, METH_VARARGS, NULL}, \
|
{"replace_or_create_buffer", (PyCFunction)replace_or_create_buffer, METH_VARARGS, NULL}, \
|
||||||
{"glewInit", (PyCFunction)_glewInit, METH_NOARGS, NULL}, \
|
{"glewInit", (PyCFunction)_glewInit, METH_NOARGS, NULL}, \
|
||||||
{"check_for_extensions", (PyCFunction)check_for_extensions, METH_NOARGS, NULL}, \
|
{"check_for_extensions", (PyCFunction)check_for_extensions, METH_NOARGS, NULL}, \
|
||||||
|
{"get_uniform_block_size", (PyCFunction)get_uniform_block_size, METH_VARARGS, NULL}, \
|
||||||
|
{"get_uniform_block_offsets", (PyCFunction)get_uniform_block_offsets, METH_VARARGS, NULL}, \
|
||||||
METH(Viewport, METH_VARARGS) \
|
METH(Viewport, METH_VARARGS) \
|
||||||
METH(CheckError, METH_NOARGS) \
|
METH(CheckError, METH_NOARGS) \
|
||||||
METH(ClearColor, METH_VARARGS) \
|
METH(ClearColor, METH_VARARGS) \
|
||||||
@@ -802,6 +861,7 @@ int add_module_gl_constants(PyObject *module) {
|
|||||||
METH(Uniform4f, METH_VARARGS) \
|
METH(Uniform4f, METH_VARARGS) \
|
||||||
METH(Uniform3fv, METH_VARARGS) \
|
METH(Uniform3fv, METH_VARARGS) \
|
||||||
METH(GetUniformLocation, METH_VARARGS) \
|
METH(GetUniformLocation, METH_VARARGS) \
|
||||||
|
METH(GetUniformBlockIndex, METH_VARARGS) \
|
||||||
METH(GetAttribLocation, METH_VARARGS) \
|
METH(GetAttribLocation, METH_VARARGS) \
|
||||||
METH(ShaderSource, METH_VARARGS) \
|
METH(ShaderSource, METH_VARARGS) \
|
||||||
METH(CompileShader, METH_O) \
|
METH(CompileShader, METH_O) \
|
||||||
@@ -837,6 +897,7 @@ int add_module_gl_constants(PyObject *module) {
|
|||||||
METH(TexParameteri, METH_VARARGS) \
|
METH(TexParameteri, METH_VARARGS) \
|
||||||
METH(PixelStorei, METH_VARARGS) \
|
METH(PixelStorei, METH_VARARGS) \
|
||||||
METH(BindBuffer, METH_VARARGS) \
|
METH(BindBuffer, METH_VARARGS) \
|
||||||
|
METH(BindBufferBase, METH_VARARGS) \
|
||||||
METH(TexBuffer, METH_VARARGS) \
|
METH(TexBuffer, METH_VARARGS) \
|
||||||
METH(TexStorage3D, METH_VARARGS) \
|
METH(TexStorage3D, METH_VARARGS) \
|
||||||
METH(CopyImageSubData, METH_VARARGS) \
|
METH(CopyImageSubData, METH_VARARGS) \
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from collections import namedtuple
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from ctypes import addressof, sizeof
|
from ctypes import addressof, sizeof
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
@@ -15,17 +16,19 @@ from .fast_data_types import (
|
|||||||
GL_MAX_TEXTURE_SIZE, GL_NEAREST, GL_R8, GL_RED, GL_STREAM_DRAW,
|
GL_MAX_TEXTURE_SIZE, GL_NEAREST, GL_R8, GL_RED, GL_STREAM_DRAW,
|
||||||
GL_TEXTURE0, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,
|
GL_TEXTURE0, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,
|
||||||
GL_TEXTURE_MIN_FILTER, GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, GL_TRUE,
|
GL_TEXTURE_MIN_FILTER, GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, GL_TRUE,
|
||||||
GL_UNPACK_ALIGNMENT, GL_UNSIGNED_BYTE, GL_VERTEX_SHADER, ITALIC, SpriteMap,
|
GL_UNIFORM_BUFFER, GL_UNPACK_ALIGNMENT, GL_UNSIGNED_BYTE, GL_VERTEX_SHADER,
|
||||||
copy_image_sub_data, glActiveTexture, glAttachShader, glBindBuffer,
|
ITALIC, SpriteMap, copy_image_sub_data, get_uniform_block_offsets,
|
||||||
glBindTexture, glBindVertexArray, glCompileShader, glCopyImageSubData,
|
get_uniform_block_size, glActiveTexture, glAttachShader, glBindBuffer,
|
||||||
glCreateProgram, glCreateShader, glDeleteBuffer, glDeleteProgram,
|
glBindBufferBase, glBindTexture, glBindVertexArray, glCompileShader,
|
||||||
glDeleteShader, glDeleteTexture, glDeleteVertexArray,
|
glCopyImageSubData, glCreateProgram, glCreateShader, glDeleteBuffer,
|
||||||
|
glDeleteProgram, glDeleteShader, glDeleteTexture, glDeleteVertexArray,
|
||||||
glEnableVertexAttribArray, glGenBuffers, glGenTextures, glGenVertexArrays,
|
glEnableVertexAttribArray, glGenBuffers, glGenTextures, glGenVertexArrays,
|
||||||
glGetAttribLocation, glGetBufferSubData, glGetIntegerv,
|
glGetAttribLocation, glGetBufferSubData, glGetIntegerv,
|
||||||
glGetProgramInfoLog, glGetProgramiv, glGetShaderInfoLog, glGetShaderiv,
|
glGetProgramInfoLog, glGetProgramiv, glGetShaderInfoLog, glGetShaderiv,
|
||||||
glGetUniformLocation, glLinkProgram, glPixelStorei, glShaderSource,
|
glGetUniformBlockIndex, glGetUniformLocation, glLinkProgram, glPixelStorei,
|
||||||
glTexParameteri, glTexStorage3D, glTexSubImage3D, glUseProgram,
|
glShaderSource, glTexParameteri, glTexStorage3D, glTexSubImage3D,
|
||||||
glVertexAttribDivisor, glVertexAttribPointer, replace_or_create_buffer
|
glUseProgram, glVertexAttribDivisor, glVertexAttribPointer,
|
||||||
|
replace_or_create_buffer
|
||||||
)
|
)
|
||||||
from .fonts.render import render_cell
|
from .fonts.render import render_cell
|
||||||
from .utils import safe_print
|
from .utils import safe_print
|
||||||
@@ -34,6 +37,7 @@ GL_VERSION = (3, 3)
|
|||||||
VERSION = GL_VERSION[0] * 100 + GL_VERSION[1] * 10
|
VERSION = GL_VERSION[0] * 100 + GL_VERSION[1] * 10
|
||||||
ITALIC_MASK = 1 << ITALIC
|
ITALIC_MASK = 1 << ITALIC
|
||||||
BOLD_MASK = 1 << BOLD
|
BOLD_MASK = 1 << BOLD
|
||||||
|
UBO = namedtuple('UBO', 'size index offsets buf_id')
|
||||||
BASE = os.path.dirname(os.path.abspath(__file__))
|
BASE = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
|
||||||
@@ -327,6 +331,30 @@ class ShaderProgram: # {{{
|
|||||||
' Return the id for the uniform variable `name` or -1 if not found. '
|
' Return the id for the uniform variable `name` or -1 if not found. '
|
||||||
return glGetUniformLocation(self.program_id, name)
|
return glGetUniformLocation(self.program_id, name)
|
||||||
|
|
||||||
|
@lru_cache(maxsize=2**6)
|
||||||
|
def uniform_block_index(self, name: str) -> int:
|
||||||
|
' Return the block index for the specified uniform block raises ValueError if not found. '
|
||||||
|
return glGetUniformBlockIndex(self.program_id, name)
|
||||||
|
|
||||||
|
def uniform_block_size(self, block_index):
|
||||||
|
return get_uniform_block_size(self.program_id, block_index)
|
||||||
|
|
||||||
|
def init_uniform_block(self, name, *variables):
|
||||||
|
idx = self.uniform_block_index(name)
|
||||||
|
size = self.uniform_block_size(idx)
|
||||||
|
offsets = get_uniform_block_offsets(self.program_id, variables)
|
||||||
|
offsets = dict(zip(variables, offsets))
|
||||||
|
buf_id = buffer_manager.create(GL_UNIFORM_BUFFER)
|
||||||
|
return UBO(size=size, index=idx, offsets=offsets, buf_id=buf_id)
|
||||||
|
|
||||||
|
def send_uniform_buffer_data(self, ubo, data, usage=GL_STREAM_DRAW):
|
||||||
|
buffer_manager.set_data(ubo.buf_id, data, usage=usage)
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def bound_uniform_buffer(self, ubo):
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, ubo.index, ubo.buf_id)
|
||||||
|
yield
|
||||||
|
|
||||||
@lru_cache(maxsize=2**6)
|
@lru_cache(maxsize=2**6)
|
||||||
def attribute_location(self, name: str) -> int:
|
def attribute_location(self, name: str) -> int:
|
||||||
' Return the id for the attribute variable `name` or -1 if not found. '
|
' Return the id for the attribute variable `name` or -1 if not found. '
|
||||||
|
|||||||
Reference in New Issue
Block a user