mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
Move default texel and shader storage buffers to high level code.
This commit is contained in:
@@ -589,6 +589,55 @@ Texture *Graphics::getDefaultTexture(TextureType type, DataBaseType dataType)
|
||||
return tex;
|
||||
}
|
||||
|
||||
Buffer *Graphics::getDefaultTexelBuffer(DataBaseType dataType)
|
||||
{
|
||||
Buffer *buffer = defaultTexelBuffers[dataType];
|
||||
if (buffer != nullptr)
|
||||
return buffer;
|
||||
|
||||
Buffer::Settings settings(BUFFERUSAGEFLAG_TEXEL, BUFFERDATAUSAGE_STATIC);
|
||||
settings.zeroInitialize = true;
|
||||
settings.debugName = "default_texelbuffer_";
|
||||
|
||||
DataFormat format = DATAFORMAT_FLOAT;
|
||||
switch (dataType)
|
||||
{
|
||||
case DATA_BASETYPE_FLOAT:
|
||||
default:
|
||||
format = DATAFORMAT_FLOAT;
|
||||
settings.debugName += "float";
|
||||
break;
|
||||
case DATA_BASETYPE_INT:
|
||||
format = DATAFORMAT_INT32;
|
||||
settings.debugName += "int";
|
||||
break;
|
||||
case DATA_BASETYPE_UINT:
|
||||
format = DATAFORMAT_UINT32;
|
||||
settings.debugName += "uint";
|
||||
break;
|
||||
}
|
||||
|
||||
buffer = newBuffer(settings, format, nullptr, sizeof(float), 1);
|
||||
|
||||
defaultTexelBuffers[dataType] = buffer;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
Buffer *Graphics::getDefaultStorageBuffer()
|
||||
{
|
||||
if (defaultStorageBuffer != nullptr)
|
||||
return defaultStorageBuffer;
|
||||
|
||||
Buffer::Settings settings(BUFFERUSAGEFLAG_SHADER_STORAGE, BUFFERDATAUSAGE_STATIC);
|
||||
settings.zeroInitialize = true;
|
||||
settings.debugName = "default_storagebuffer";
|
||||
|
||||
defaultStorageBuffer = newBuffer(settings, DATAFORMAT_FLOAT, nullptr, Buffer::SHADER_STORAGE_BUFFER_MAX_STRIDE, 0);
|
||||
|
||||
return defaultStorageBuffer;
|
||||
}
|
||||
|
||||
void Graphics::releaseDefaultResources()
|
||||
{
|
||||
for (int type = 0; type < TEXTURE_MAX_ENUM; type++)
|
||||
@@ -600,6 +649,17 @@ void Graphics::releaseDefaultResources()
|
||||
defaultTextures[type][dataType] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (int dataType = 0; dataType < DATA_BASETYPE_MAX_ENUM; dataType++)
|
||||
{
|
||||
if (defaultTexelBuffers[dataType])
|
||||
defaultTexelBuffers[dataType]->release();
|
||||
defaultTexelBuffers[dataType] = nullptr;
|
||||
}
|
||||
|
||||
if (defaultStorageBuffer)
|
||||
defaultStorageBuffer->release();
|
||||
defaultStorageBuffer = nullptr;
|
||||
}
|
||||
|
||||
Texture *Graphics::getTextureOrDefaultForActiveShader(Texture *tex)
|
||||
|
||||
@@ -488,6 +488,8 @@ public:
|
||||
bool validateShader(bool gles, const std::vector<std::string> &stages, const Shader::CompileOptions &options, std::string &err);
|
||||
|
||||
Texture *getDefaultTexture(TextureType type, DataBaseType dataType);
|
||||
Buffer *getDefaultTexelBuffer(DataBaseType dataType);
|
||||
Buffer *getDefaultStorageBuffer();
|
||||
Texture *getTextureOrDefaultForActiveShader(Texture *tex);
|
||||
|
||||
/**
|
||||
@@ -1111,6 +1113,8 @@ private:
|
||||
int calculateEllipsePoints(float rx, float ry) const;
|
||||
|
||||
Texture *defaultTextures[TEXTURE_MAX_ENUM][DATA_BASETYPE_MAX_ENUM];
|
||||
Buffer *defaultTexelBuffers[DATA_BASETYPE_MAX_ENUM];
|
||||
Buffer *defaultStorageBuffer;
|
||||
|
||||
std::vector<uint8> scratchBuffer;
|
||||
|
||||
|
||||
@@ -112,7 +112,6 @@ Graphics::Graphics()
|
||||
, requestedBackbufferMSAA(0)
|
||||
, bufferMapMemory(nullptr)
|
||||
, bufferMapMemorySize(2 * 1024 * 1024)
|
||||
, defaultBuffers()
|
||||
, pixelFormatUsage()
|
||||
{
|
||||
gl = OpenGL();
|
||||
@@ -384,43 +383,6 @@ bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth,
|
||||
batchedDrawState.indexBuffer = CreateStreamBuffer(BUFFERUSAGE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
|
||||
}
|
||||
|
||||
// TODO: one buffer each for float, int, uint
|
||||
if (capabilities.features[FEATURE_TEXEL_BUFFER] && defaultBuffers[BUFFERUSAGE_TEXEL].get() == nullptr)
|
||||
{
|
||||
Buffer::Settings settings(BUFFERUSAGEFLAG_TEXEL, BUFFERDATAUSAGE_STATIC);
|
||||
std::vector<Buffer::DataDeclaration> format = {{"", DATAFORMAT_FLOAT_VEC4, 0}};
|
||||
|
||||
const float texel[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
auto buffer = newBuffer(settings, format, texel, sizeof(texel), 1);
|
||||
defaultBuffers[BUFFERUSAGE_TEXEL].set(buffer, Acquire::NORETAIN);
|
||||
}
|
||||
|
||||
if (capabilities.features[FEATURE_GLSL4] && defaultBuffers[BUFFERUSAGE_SHADER_STORAGE].get() == nullptr)
|
||||
{
|
||||
Buffer::Settings settings(BUFFERUSAGEFLAG_SHADER_STORAGE, BUFFERDATAUSAGE_STATIC);
|
||||
std::vector<Buffer::DataDeclaration> format = {{"", DATAFORMAT_FLOAT, 0}};
|
||||
|
||||
std::vector<float> data;
|
||||
data.resize(Buffer::SHADER_STORAGE_BUFFER_MAX_STRIDE / 4);
|
||||
|
||||
auto buffer = newBuffer(settings, format, data.data(), data.size() * sizeof(float), data.size());
|
||||
defaultBuffers[BUFFERUSAGE_SHADER_STORAGE].set(buffer, Acquire::NORETAIN);
|
||||
}
|
||||
|
||||
// Load default resources before other Volatile.
|
||||
for (int i = 0; i < BUFFERUSAGE_MAX_ENUM; i++)
|
||||
{
|
||||
if (defaultBuffers[i].get())
|
||||
((Buffer *) defaultBuffers[i].get())->loadVolatile();
|
||||
}
|
||||
|
||||
if (defaultBuffers[BUFFERUSAGE_TEXEL].get())
|
||||
gl.setDefaultTexelBuffer((GLuint) defaultBuffers[BUFFERUSAGE_TEXEL]->getTexelBufferHandle());
|
||||
|
||||
if (defaultBuffers[BUFFERUSAGE_SHADER_STORAGE].get())
|
||||
gl.setDefaultStorageBuffer((GLuint) defaultBuffers[BUFFERUSAGE_SHADER_STORAGE]->getHandle());
|
||||
|
||||
// Reload all volatile objects.
|
||||
if (!Volatile::loadAll())
|
||||
::printf("Could not reload all volatile objects.\n");
|
||||
|
||||
@@ -173,9 +173,6 @@ private:
|
||||
char *bufferMapMemory;
|
||||
size_t bufferMapMemorySize;
|
||||
|
||||
// Only needed for buffer types that can be bound to shaders.
|
||||
StrongRef<love::graphics::Buffer> defaultBuffers[BUFFERUSAGE_MAX_ENUM];
|
||||
|
||||
// [non-readable, readable]
|
||||
uint32 pixelFormatUsage[PIXELFORMAT_MAX_ENUM][2];
|
||||
|
||||
|
||||
@@ -330,15 +330,6 @@ public:
|
||||
**/
|
||||
GLuint getDefaultFBO() const;
|
||||
|
||||
/**
|
||||
* Gets the texture ID for love's default texel buffer.
|
||||
**/
|
||||
GLuint getDefaultTexelBuffer() const { return state.defaultTexelBuffer; }
|
||||
void setDefaultTexelBuffer(GLuint tex) { state.defaultTexelBuffer = tex; }
|
||||
|
||||
GLuint getDefaultStorageBuffer() const { return state.defaultStorageBuffer; }
|
||||
void setDefaultStorageBuffer(GLuint buf) { state.defaultStorageBuffer = buf; }
|
||||
|
||||
/**
|
||||
* Helper for setting the active texture unit.
|
||||
*
|
||||
@@ -544,9 +535,6 @@ private:
|
||||
|
||||
GLuint boundFramebuffers[2];
|
||||
|
||||
GLuint defaultTexelBuffer;
|
||||
GLuint defaultStorageBuffer;
|
||||
|
||||
} state;
|
||||
|
||||
}; // OpenGL
|
||||
|
||||
@@ -149,17 +149,8 @@ void Shader::mapActiveUniforms()
|
||||
TextureUnit unit;
|
||||
unit.type = u.textureType;
|
||||
unit.active = true;
|
||||
|
||||
if (u.baseType == UNIFORM_TEXELBUFFER)
|
||||
{
|
||||
unit.isTexelBuffer = true;
|
||||
unit.texture = gl.getDefaultTexelBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
unit.isTexelBuffer = false;
|
||||
unit.texture = 0; // Handled below.
|
||||
}
|
||||
unit.texture = 0; // Handled below.
|
||||
unit.isTexelBuffer = u.baseType == UNIFORM_TEXELBUFFER;
|
||||
|
||||
for (int i = 0; i < u.count; i++)
|
||||
textureUnits.push_back(unit);
|
||||
@@ -414,7 +405,7 @@ void Shader::mapActiveUniforms()
|
||||
|
||||
BufferBinding binding;
|
||||
binding.bindingindex = u.ints[0];
|
||||
binding.buffer = gl.getDefaultStorageBuffer();
|
||||
binding.buffer = 0;
|
||||
|
||||
if (binding.bindingindex >= 0)
|
||||
{
|
||||
@@ -867,13 +858,23 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
love::graphics::Buffer *buffer = buffers[i];
|
||||
bool isdefault = buffer != nullptr;
|
||||
|
||||
if (buffer != nullptr)
|
||||
{
|
||||
if (!validateBuffer(info, buffer, internalUpdate))
|
||||
continue;
|
||||
buffer->retain();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
|
||||
if (texelbinding)
|
||||
buffer = gfx->getDefaultTexelBuffer(info->dataBaseType);
|
||||
else
|
||||
buffer = gfx->getDefaultStorageBuffer();
|
||||
}
|
||||
|
||||
buffer->retain();
|
||||
|
||||
if (info->buffers[i] != nullptr)
|
||||
info->buffers[i]->release();
|
||||
@@ -882,12 +883,7 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
|
||||
|
||||
if (texelbinding)
|
||||
{
|
||||
GLuint gltex = 0;
|
||||
if (buffer != nullptr)
|
||||
gltex = (GLuint) buffer->getTexelBufferHandle();
|
||||
else
|
||||
gltex = gl.getDefaultTexelBuffer();
|
||||
|
||||
GLuint gltex = (GLuint) buffer->getTexelBufferHandle();
|
||||
int texunit = info->ints[i];
|
||||
|
||||
if (shaderactive)
|
||||
@@ -898,14 +894,9 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
|
||||
}
|
||||
else if (storagebinding)
|
||||
{
|
||||
GLuint glbuffer = (GLuint)buffer->getHandle();
|
||||
int bindingindex = info->ints[i];
|
||||
|
||||
GLuint glbuffer = 0;
|
||||
if (buffer != nullptr)
|
||||
glbuffer = (GLuint) buffer->getHandle();
|
||||
else
|
||||
glbuffer = gl.getDefaultStorageBuffer();
|
||||
|
||||
if (shaderactive)
|
||||
gl.bindIndexedBuffer(glbuffer, BUFFERUSAGE_SHADER_STORAGE, bindingindex);
|
||||
|
||||
@@ -915,7 +906,7 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
|
||||
activeStorageBufferBindings[activeindex.first].buffer = glbuffer;
|
||||
|
||||
if (activeindex.second >= 0)
|
||||
activeWritableStorageBuffers[activeindex.second] = buffer;
|
||||
activeWritableStorageBuffers[activeindex.second] = isdefault ? nullptr : buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user