mirror of https://github.com/bjornbytes/lovr.git
Adjust BlockType; getValue -> read;
This commit is contained in:
parent
ee7544eba8
commit
e6d9b82bba
|
@ -61,6 +61,7 @@ extern const char* ArcModes[];
|
|||
extern const char* AttributeTypes[];
|
||||
extern const char* BlendAlphaModes[];
|
||||
extern const char* BlendModes[];
|
||||
extern const char* BlockTypes[];
|
||||
extern const char* BufferUsages[];
|
||||
extern const char* CompareModes[];
|
||||
extern const char* ControllerAxes[];
|
||||
|
|
|
@ -49,6 +49,12 @@ const char* BlendModes[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
const char* BlockTypes[] = {
|
||||
[BLOCK_UNIFORM] = "uniform",
|
||||
[BLOCK_COMPUTE] = "compute",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* BufferUsages[] = {
|
||||
[USAGE_STATIC] = "static",
|
||||
[USAGE_DYNAMIC] = "dynamic",
|
||||
|
@ -341,8 +347,8 @@ static int l_lovrGraphicsGetDimensions(lua_State* L) {
|
|||
static int l_lovrGraphicsGetSupported(lua_State* L) {
|
||||
const GpuFeatures* features = lovrGraphicsGetSupported();
|
||||
lua_newtable(L);
|
||||
lua_pushboolean(L, features->computeShaders);
|
||||
lua_setfield(L, -2, "computeshaders");
|
||||
lua_pushboolean(L, features->compute);
|
||||
lua_setfield(L, -2, "compute");
|
||||
lua_pushboolean(L, features->singlepass);
|
||||
lua_setfield(L, -2, "singlepass");
|
||||
return 1;
|
||||
|
@ -904,9 +910,11 @@ static int l_lovrGraphicsNewShaderBlock(lua_State* L) {
|
|||
vec_uniform_t uniforms;
|
||||
vec_init(&uniforms);
|
||||
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
BlockType type = luaL_checkoption(L, 1, NULL, BlockTypes);
|
||||
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1) != 0) {
|
||||
while (lua_next(L, 2) != 0) {
|
||||
Uniform uniform;
|
||||
|
||||
// Name
|
||||
|
@ -934,27 +942,22 @@ static int l_lovrGraphicsNewShaderBlock(lua_State* L) {
|
|||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
BlockType type = BLOCK_UNIFORM;
|
||||
BufferUsage usage = USAGE_DYNAMIC;
|
||||
bool readable = false;
|
||||
|
||||
if (lua_istable(L, 2)) {
|
||||
lua_getfield(L, 2, "usage");
|
||||
if (lua_istable(L, 3)) {
|
||||
lua_getfield(L, 3, "usage");
|
||||
usage = luaL_checkoption(L, -1, "dynamic", BufferUsages);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 2, "writable");
|
||||
type = lua_toboolean(L, -1) ? BLOCK_STORAGE : BLOCK_UNIFORM;
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 2, "readable");
|
||||
lua_getfield(L, 3, "readable");
|
||||
readable = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
lovrAssert(type != BLOCK_STORAGE || lovrGraphicsGetSupported()->computeShaders, "Writable ShaderBlocks are not supported on this system");
|
||||
lovrAssert(type == BLOCK_UNIFORM || lovrGraphicsGetSupported()->compute, "Compute blocks are not supported on this system");
|
||||
size_t size = lovrShaderComputeUniformLayout(&uniforms);
|
||||
Buffer* buffer = lovrBufferCreate(size, NULL, type == BLOCK_STORAGE ? BUFFER_SHADER_STORAGE : BUFFER_UNIFORM, usage, readable);
|
||||
Buffer* buffer = lovrBufferCreate(size, NULL, type == BLOCK_COMPUTE ? BUFFER_SHADER_STORAGE : BUFFER_UNIFORM, usage, readable);
|
||||
ShaderBlock* block = lovrShaderBlockCreate(type, buffer, &uniforms);
|
||||
luax_pushobject(L, block);
|
||||
vec_deinit(&uniforms);
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#include "api/graphics.h"
|
||||
#include "graphics/shader.h"
|
||||
|
||||
int l_lovrShaderBlockIsWritable(lua_State* L) {
|
||||
int l_lovrShaderBlockGetType(lua_State* L) {
|
||||
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
|
||||
lua_pushboolean(L, lovrShaderBlockGetType(block) == BLOCK_STORAGE);
|
||||
lua_pushstring(L, BlockTypes[lovrShaderBlockGetType(block)]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -47,13 +47,13 @@ int l_lovrShaderBlockSend(lua_State* L) {
|
|||
}
|
||||
}
|
||||
|
||||
int l_lovrShaderBlockGetValue(lua_State* L) {
|
||||
int l_lovrShaderBlockRead(lua_State* L) {
|
||||
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
|
||||
const char* name = luaL_checkstring(L, 2);
|
||||
const Uniform* uniform = lovrShaderBlockGetUniform(block, name);
|
||||
lovrAssert(uniform, "Unknown uniform for ShaderBlock '%s'", name);
|
||||
Buffer* buffer = lovrShaderBlockGetBuffer(block);
|
||||
lovrAssert(lovrBufferIsReadable(buffer), "ShaderBlock:getValue requires the ShaderBlock to be created with the readable flag");
|
||||
lovrAssert(lovrBufferIsReadable(buffer), "ShaderBlock:read requires the ShaderBlock to be created with the readable flag");
|
||||
union { float* floats; int* ints; } data = { .floats = lovrBufferMap(buffer, uniform->offset) };
|
||||
int components = uniform->components;
|
||||
|
||||
|
@ -107,11 +107,11 @@ int l_lovrShaderBlockGetShaderCode(lua_State* L) {
|
|||
}
|
||||
|
||||
const luaL_Reg lovrShaderBlock[] = {
|
||||
{ "isWritable", l_lovrShaderBlockIsWritable },
|
||||
{ "getType", l_lovrShaderBlockGetType },
|
||||
{ "getSize", l_lovrShaderBlockGetSize },
|
||||
{ "getOffset", l_lovrShaderBlockGetOffset },
|
||||
{ "read", l_lovrShaderBlockRead },
|
||||
{ "send", l_lovrShaderBlockSend },
|
||||
{ "getValue", l_lovrShaderBlockGetValue },
|
||||
{ "getShaderCode", l_lovrShaderBlockGetShaderCode },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
|
@ -276,7 +276,7 @@ void lovrGraphicsFill(Texture* texture, float u, float v, float w, float h);
|
|||
// GPU
|
||||
|
||||
typedef struct {
|
||||
bool computeShaders;
|
||||
bool compute;
|
||||
bool singlepass;
|
||||
} GpuFeatures;
|
||||
|
||||
|
|
|
@ -403,7 +403,7 @@ static void lovrGpuBindBuffer(BufferType type, uint32_t buffer, bool force) {
|
|||
static void lovrGpuBindBlockBuffer(BlockType type, uint32_t buffer, int slot, size_t offset, size_t size) {
|
||||
lovrAssert(offset % state.limits.blockAlign == 0, "Block buffer offset must be aligned to %d", state.limits.blockAlign);
|
||||
#ifdef EMSCRIPTEN
|
||||
lovrAssert(type == BLOCK_UNIFORM, "Writable blocks are not supported on this system");
|
||||
lovrAssert(type == BLOCK_UNIFORM, "Compute blocks are not supported on this system");
|
||||
GLenum target = GL_UNIFORM_BUFFER;
|
||||
#else
|
||||
GLenum target = type == BLOCK_UNIFORM ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER;
|
||||
|
@ -774,7 +774,7 @@ static void lovrGpuBindShader(Shader* shader) {
|
|||
// Figure out if we need to wait for pending writes on resources to complete
|
||||
#ifndef EMSCRIPTEN
|
||||
uint8_t flags = 0;
|
||||
vec_foreach_ptr(&shader->blocks[BLOCK_STORAGE], block, i) {
|
||||
vec_foreach_ptr(&shader->blocks[BLOCK_COMPUTE], block, i) {
|
||||
if (block->source && (block->source->incoherent >> BARRIER_BLOCK) & 1) {
|
||||
flags |= 1 << BARRIER_BLOCK;
|
||||
break;
|
||||
|
@ -876,10 +876,10 @@ static void lovrGpuBindShader(Shader* shader) {
|
|||
}
|
||||
|
||||
// Bind uniform blocks
|
||||
for (BlockType type = BLOCK_UNIFORM; type <= BLOCK_STORAGE; type++) {
|
||||
for (BlockType type = BLOCK_UNIFORM; type <= BLOCK_COMPUTE; type++) {
|
||||
vec_foreach_ptr(&shader->blocks[type], block, i) {
|
||||
if (block->source) {
|
||||
if (type == BLOCK_STORAGE && block->access != ACCESS_READ) {
|
||||
if (type == BLOCK_COMPUTE && block->access != ACCESS_READ) {
|
||||
block->source->incoherent |= (1 << BARRIER_BLOCK);
|
||||
vec_push(&state.incoherents[BARRIER_BLOCK], block->source);
|
||||
}
|
||||
|
@ -913,7 +913,7 @@ static void lovrGpuSetViewports(float* viewport, uint32_t count) {
|
|||
void lovrGpuInit(bool srgb, getProcAddressProc getProcAddress) {
|
||||
#ifndef EMSCRIPTEN
|
||||
gladLoadGLLoader((GLADloadproc) getProcAddress);
|
||||
state.features.computeShaders = GLAD_GL_ARB_compute_shader;
|
||||
state.features.compute = GLAD_GL_ARB_compute_shader;
|
||||
state.features.singlepass = GLAD_GL_ARB_viewport_array && GLAD_GL_AMD_vertex_shader_viewport_index && GLAD_GL_ARB_fragment_layer_viewport;
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
|
@ -1633,7 +1633,7 @@ static void lovrShaderSetupUniforms(Shader* shader) {
|
|||
// Uniform blocks
|
||||
int32_t blockCount;
|
||||
glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &blockCount);
|
||||
lovrAssert(blockCount <= MAX_BLOCK_BUFFERS, "Shader has too many read-only blocks (%d) the max is %d", blockCount, MAX_BLOCK_BUFFERS);
|
||||
lovrAssert(blockCount <= MAX_BLOCK_BUFFERS, "Shader has too many uniform blocks (%d) the max is %d", blockCount, MAX_BLOCK_BUFFERS);
|
||||
map_init(&shader->blockMap);
|
||||
vec_block_t* uniformBlocks = &shader->blocks[BLOCK_UNIFORM];
|
||||
vec_init(uniformBlocks);
|
||||
|
@ -1651,26 +1651,26 @@ static void lovrShaderSetupUniforms(Shader* shader) {
|
|||
}
|
||||
|
||||
// Shader storage buffers and their buffer variables
|
||||
vec_block_t* storageBlocks = &shader->blocks[BLOCK_STORAGE];
|
||||
vec_init(storageBlocks);
|
||||
vec_block_t* computeBlocks = &shader->blocks[BLOCK_COMPUTE];
|
||||
vec_init(computeBlocks);
|
||||
#ifndef EMSCRIPTEN
|
||||
if (GLAD_GL_ARB_shader_storage_buffer_object && GLAD_GL_ARB_program_interface_query) {
|
||||
|
||||
// Iterate over storage blocks, setting their binding and pushing them onto the block vector
|
||||
int storageCount;
|
||||
glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &storageCount);
|
||||
lovrAssert(storageCount <= MAX_BLOCK_BUFFERS, "Shader has too many writable blocks (%d) the max is %d", storageCount, MAX_BLOCK_BUFFERS);
|
||||
vec_reserve(storageBlocks, storageCount);
|
||||
for (int i = 0; i < storageCount; i++) {
|
||||
// Iterate over compute blocks, setting their binding and pushing them onto the block vector
|
||||
int computeBlockCount;
|
||||
glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &computeBlockCount);
|
||||
lovrAssert(computeBlockCount <= MAX_BLOCK_BUFFERS, "Shader has too many compute blocks (%d) the max is %d", computeBlockCount, MAX_BLOCK_BUFFERS);
|
||||
vec_reserve(computeBlocks, computeBlockCount);
|
||||
for (int i = 0; i < computeBlockCount; i++) {
|
||||
UniformBlock block = { .slot = i, .source = NULL };
|
||||
glShaderStorageBlockBinding(program, i, block.slot);
|
||||
vec_init(&block.uniforms);
|
||||
|
||||
char name[LOVR_MAX_UNIFORM_LENGTH];
|
||||
glGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, i, LOVR_MAX_UNIFORM_LENGTH, NULL, name);
|
||||
int blockId = (i << 1) + BLOCK_STORAGE;
|
||||
int blockId = (i << 1) + BLOCK_COMPUTE;
|
||||
map_set(&shader->blockMap, name, blockId);
|
||||
vec_push(storageBlocks, block);
|
||||
vec_push(computeBlocks, block);
|
||||
}
|
||||
|
||||
// Iterate over buffer variables, pushing them onto the uniform list of the correct block
|
||||
|
@ -1694,7 +1694,7 @@ static void lovrShaderSetupUniforms(Shader* shader) {
|
|||
} else {
|
||||
uniform.size = 4 * (uniform.components == 3 ? 4 : uniform.components);
|
||||
}
|
||||
vec_push(&storageBlocks->data[values[blockIndex]].uniforms, uniform);
|
||||
vec_push(&computeBlocks->data[values[blockIndex]].uniforms, uniform);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1818,7 +1818,7 @@ Shader* lovrShaderInitGraphics(Shader* shader, const char* vertexSource, const c
|
|||
const char* vertexHeader = "#version 300 es\nprecision mediump float;\nprecision mediump int;\n";
|
||||
const char* fragmentHeader = vertexHeader;
|
||||
#else
|
||||
const char* vertexHeader = state.features.computeShaders ? "#version 430\n" : "#version 150\n";
|
||||
const char* vertexHeader = state.features.compute ? "#version 430\n" : "#version 150\n";
|
||||
const char* fragmentHeader = "#version 150\nin vec4 gl_FragCoord;\n";
|
||||
#endif
|
||||
|
||||
|
@ -1913,7 +1913,7 @@ void lovrShaderDestroy(void* ref) {
|
|||
for (int i = 0; i < shader->uniforms.length; i++) {
|
||||
free(shader->uniforms.data[i].value.data);
|
||||
}
|
||||
for (BlockType type = BLOCK_UNIFORM; type <= BLOCK_STORAGE; type++) {
|
||||
for (BlockType type = BLOCK_UNIFORM; type <= BLOCK_COMPUTE; type++) {
|
||||
UniformBlock* block; int i;
|
||||
vec_foreach_ptr(&shader->blocks[type], block, i) {
|
||||
lovrRelease(block->source);
|
||||
|
@ -1921,7 +1921,7 @@ void lovrShaderDestroy(void* ref) {
|
|||
}
|
||||
vec_deinit(&shader->uniforms);
|
||||
vec_deinit(&shader->blocks[BLOCK_UNIFORM]);
|
||||
vec_deinit(&shader->blocks[BLOCK_STORAGE]);
|
||||
vec_deinit(&shader->blocks[BLOCK_COMPUTE]);
|
||||
map_deinit(&shader->attributes);
|
||||
map_deinit(&shader->uniformMap);
|
||||
map_deinit(&shader->blockMap);
|
||||
|
|
|
@ -18,7 +18,7 @@ typedef enum {
|
|||
|
||||
typedef enum {
|
||||
BLOCK_UNIFORM,
|
||||
BLOCK_STORAGE
|
||||
BLOCK_COMPUTE
|
||||
} BlockType;
|
||||
|
||||
typedef enum {
|
||||
|
|
Loading…
Reference in New Issue