Merge branch '12.0-development' into metal

This commit is contained in:
Alex Szpakowski
2020-07-29 18:21:19 -03:00
57 changed files with 6870 additions and 4915 deletions
+49 -36
View File
@@ -107,6 +107,7 @@ love::graphics::Graphics *createInstance()
Graphics::Graphics()
: windowHasStencil(false)
, mainVAO(0)
, defaultBuffers()
, supportedFormats()
{
gl = OpenGL();
@@ -162,9 +163,9 @@ love::graphics::Shader *Graphics::newShaderInternal(love::graphics::ShaderStage
return new Shader(vertex, pixel);
}
love::graphics::Buffer *Graphics::newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags)
love::graphics::Buffer *Graphics::newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength)
{
return new Buffer(size, data, type, usage, mapflags);
return new Buffer(this, settings, format, data, size, arraylength);
}
void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight)
@@ -255,11 +256,32 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
{
// Initial sizes that should be good enough for most cases. It will
// resize to fit if needed, later.
batchedDrawState.vb[0] = CreateStreamBuffer(BUFFER_VERTEX, 1024 * 1024 * 1);
batchedDrawState.vb[1] = CreateStreamBuffer(BUFFER_VERTEX, 256 * 1024 * 1);
batchedDrawState.indexBuffer = CreateStreamBuffer(BUFFER_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
batchedDrawState.vb[0] = CreateStreamBuffer(BUFFERTYPE_VERTEX, 1024 * 1024 * 1);
batchedDrawState.vb[1] = CreateStreamBuffer(BUFFERTYPE_VERTEX, 256 * 1024 * 1);
batchedDrawState.indexBuffer = CreateStreamBuffer(BUFFERTYPE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
}
if (capabilities.features[FEATURE_TEXEL_BUFFER] && defaultBuffers[BUFFERTYPE_TEXEL].get() == nullptr)
{
Buffer::Settings settings(Buffer::TYPEFLAG_TEXEL, 0, BUFFERUSAGE_STATIC);
std::vector<Buffer::DataDeclaration> format = {{"", DATAFORMAT_FLOAT_VEC4, 0}};
const float texel[] = {0.0f, 0.0f, 0.0f, 1.0f};
love::graphics::Buffer *buffer = newBuffer(settings, format, texel, sizeof(texel), 1);
defaultBuffers[BUFFERTYPE_TEXEL].set(buffer, Acquire::NORETAIN);
}
// Load default resources before other Volatile.
for (int i = 0; i < BUFFERTYPE_MAX_ENUM; i++)
{
if (defaultBuffers[i].get())
((Buffer *) defaultBuffers[i].get())->loadVolatile();
}
if (defaultBuffers[BUFFERTYPE_TEXEL].get())
gl.setDefaultTexelBuffer((GLuint) defaultBuffers[BUFFERTYPE_TEXEL]->getTexelBufferHandle());
// Reload all volatile objects.
if (!Volatile::loadAll())
::printf("Could not reload all volatile objects.\n");
@@ -269,12 +291,11 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
// Restore the graphics state.
restoreState(states.back());
int gammacorrect = isGammaCorrect() ? 1 : 0;
Shader::Language target = getShaderLanguageTarget();
// We always need a default shader.
for (int i = 0; i < Shader::STANDARD_MAX_ENUM; i++)
{
auto stype = (Shader::StandardShader) i;
if (i == Shader::STANDARD_ARRAY && !capabilities.textureTypes[TEXTURE_2D_ARRAY])
continue;
@@ -284,8 +305,10 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
{
if (!Shader::standardShaders[i])
{
const auto &code = defaultShaderCode[i][target][gammacorrect];
Shader::standardShaders[i] = love::graphics::Graphics::newShader(code.source[ShaderStage::STAGE_VERTEX], code.source[ShaderStage::STAGE_PIXEL]);
std::vector<std::string> stages;
stages.push_back(Shader::getDefaultCode(stype, ShaderStage::STAGE_VERTEX));
stages.push_back(Shader::getDefaultCode(stype, ShaderStage::STAGE_PIXEL));
Shader::standardShaders[i] = newShader(stages);
}
}
catch (love::Exception &)
@@ -376,7 +399,7 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
GLenum glprimitivetype = OpenGL::getGLPrimitiveType(cmd.primitiveType);
GLenum gldatatype = OpenGL::getGLIndexDataType(cmd.indexType);
gl.bindBuffer(BUFFER_INDEX, cmd.indexBuffer->getHandle());
gl.bindBuffer(BUFFERTYPE_INDEX, cmd.indexBuffer->getHandle());
if (cmd.instanceCount > 1)
glDrawElementsInstanced(glprimitivetype, cmd.indexCount, gldatatype, gloffset, cmd.instanceCount);
@@ -386,13 +409,13 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
++drawCalls;
}
static inline void advanceVertexOffsets(const vertex::Attributes &attributes, vertex::BufferBindings &buffers, int vertexcount)
static inline void advanceVertexOffsets(const VertexAttributes &attributes, BufferBindings &buffers, int vertexcount)
{
// TODO: Figure out a better way to avoid touching the same buffer multiple
// times, if multiple attributes share the buffer.
uint32 touchedbuffers = 0;
for (unsigned int i = 0; i < vertex::Attributes::MAX; i++)
for (unsigned int i = 0; i < VertexAttributes::MAX; i++)
{
if (!attributes.isEnabled(i))
continue;
@@ -409,7 +432,7 @@ static inline void advanceVertexOffsets(const vertex::Attributes &attributes, ve
}
}
void Graphics::drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::BufferBindings &buffers, love::graphics::Texture *texture)
void Graphics::drawQuads(int start, int count, const VertexAttributes &attributes, const BufferBindings &buffers, love::graphics::Texture *texture)
{
const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX;
const int MAX_QUADS_PER_DRAW = MAX_VERTICES_PER_DRAW / 4;
@@ -418,7 +441,7 @@ void Graphics::drawQuads(int start, int count, const vertex::Attributes &attribu
gl.bindTextureToUnit(texture, 0, false);
gl.setCullMode(CULL_NONE);
gl.bindBuffer(BUFFER_INDEX, quadIndexBuffer->getHandle());
gl.bindBuffer(BUFFERTYPE_INDEX, quadIndexBuffer->getHandle());
if (gl.isBaseVertexSupported())
{
@@ -438,7 +461,7 @@ void Graphics::drawQuads(int start, int count, const vertex::Attributes &attribu
}
else
{
vertex::BufferBindings bufferscopy = buffers;
BufferBindings bufferscopy = buffers;
if (start > 0)
advanceVertexOffsets(attributes, bufferscopy, start * 4);
@@ -525,7 +548,7 @@ void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int w, int h,
endPass();
bool iswindow = rts.getFirstTarget().texture == nullptr;
vertex::Winding vertexwinding = state.winding;
Winding vertexwinding = state.winding;
if (iswindow)
{
@@ -543,10 +566,10 @@ void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int w, int h,
// Flip front face winding when rendering to a texture, since our
// projection matrix is flipped.
vertexwinding = vertexwinding == vertex::WINDING_CW ? vertex::WINDING_CCW : vertex::WINDING_CW;
vertexwinding = vertexwinding == WINDING_CW ? WINDING_CCW : WINDING_CW;
}
glFrontFace(vertexwinding == vertex::WINDING_CW ? GL_CW : GL_CCW);
glFrontFace(vertexwinding == WINDING_CW ? GL_CW : GL_CCW);
gl.setViewport({0, 0, pixelw, pixelh});
@@ -1246,7 +1269,7 @@ void Graphics::setDepthMode(CompareMode compare, bool write)
}
}
void Graphics::setFrontFaceWinding(vertex::Winding winding)
void Graphics::setFrontFaceWinding(Winding winding)
{
DisplayState &state = states.back();
@@ -1256,9 +1279,9 @@ void Graphics::setFrontFaceWinding(vertex::Winding winding)
state.winding = winding;
if (isRenderTargetActive())
winding = winding == vertex::WINDING_CW ? vertex::WINDING_CCW : vertex::WINDING_CW;
winding = winding == WINDING_CW ? WINDING_CCW : WINDING_CW;
glFrontFace(winding == vertex::WINDING_CW ? GL_CW : GL_CCW);
glFrontFace(winding == WINDING_CW ? GL_CW : GL_CCW);
}
void Graphics::setColor(Colorf c)
@@ -1388,17 +1411,19 @@ void Graphics::initCapabilities()
capabilities.features[FEATURE_GLSL3] = GLAD_ES_VERSION_3_0 || gl.isCoreProfile();
capabilities.features[FEATURE_GLSL4] = GLAD_ES_VERSION_3_1 || (gl.isCoreProfile() && GLAD_VERSION_4_3);
capabilities.features[FEATURE_INSTANCING] = gl.isInstancingSupported();
static_assert(FEATURE_MAX_ENUM == 10, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
capabilities.features[FEATURE_TEXEL_BUFFER] = gl.areTexelBuffersSupported();
static_assert(FEATURE_MAX_ENUM == 11, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
capabilities.limits[LIMIT_POINT_SIZE] = gl.getMaxPointSize();
capabilities.limits[LIMIT_TEXTURE_SIZE] = gl.getMax2DTextureSize();
capabilities.limits[LIMIT_TEXTURE_LAYERS] = gl.getMaxTextureLayers();
capabilities.limits[LIMIT_VOLUME_TEXTURE_SIZE] = gl.getMax3DTextureSize();
capabilities.limits[LIMIT_CUBE_TEXTURE_SIZE] = gl.getMaxCubeTextureSize();
capabilities.limits[LIMIT_TEXEL_BUFFER_SIZE] = gl.getMaxTexelBufferSize();
capabilities.limits[LIMIT_RENDER_TARGETS] = gl.getMaxRenderTargets();
capabilities.limits[LIMIT_TEXTURE_MSAA] = gl.getMaxSamples();
capabilities.limits[LIMIT_ANISOTROPY] = gl.getMaxAnisotropy();
static_assert(LIMIT_MAX_ENUM == 8, "Graphics::initCapabilities must be updated when adding a new system limit!");
static_assert(LIMIT_MAX_ENUM == 9, "Graphics::initCapabilities must be updated when adding a new system limit!");
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
capabilities.textureTypes[i] = gl.isTextureTypeSupported((TextureType) i);
@@ -1524,18 +1549,6 @@ bool Graphics::isPixelFormatSupported(PixelFormat format, bool rendertarget, boo
return supported.value;
}
Shader::Language Graphics::getShaderLanguageTarget() const
{
if (gl.isCoreProfile())
return Shader::LANGUAGE_GLSL3;
else if (GLAD_ES_VERSION_3_0)
return Shader::LANGUAGE_ESSL3;
else if (GLAD_ES_VERSION_2_0)
return Shader::LANGUAGE_ESSL1;
else
return Shader::LANGUAGE_GLSL1;
}
} // opengl
} // graphics
} // love