Adjust BlockType; getValue -> read;

This commit is contained in:
bjorn 2019-01-16 08:52:21 -08:00 committed by Bjorn Swenson
parent ee7544eba8
commit e6d9b82bba
6 changed files with 46 additions and 42 deletions

View File

@ -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[];

View File

@ -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);

View File

@ -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 }
};

View File

@ -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;

View File

@ -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);

View File

@ -18,7 +18,7 @@ typedef enum {
typedef enum {
BLOCK_UNIFORM,
BLOCK_STORAGE
BLOCK_COMPUTE
} BlockType;
typedef enum {