Add a workaround for some qualcomm devices on android 4.4

This commit is contained in:
Deve 2017-07-11 00:37:31 +02:00
parent 70c481cb26
commit d44802a482
10 changed files with 90 additions and 7 deletions

View File

@ -37,5 +37,6 @@
<card contains="ATI" os="windows" version="<=3.1.8787" disable="ForceLegacyDevice"/>
<card os="android" disable="TextureFormatBGRA8888"/>
<card os="android" disable="ColorBufferFloat"/>
<card contains="Adreno" os="android" version="<=19" disable="VertexIdWorking"/>
<card contains="Android Emulator" os="android" disable="ForceLegacyDevice"/>
</graphical-restrictions>

View File

@ -14,6 +14,11 @@ layout (location = 0) in vec3 particle_position;
layout (location = 1) in float lifetime;
layout (location = 2) in vec3 particle_velocity;
layout (location = 3) in float size;
#ifdef Needs_Vertex_Id_Workaround
layout (location = 8) in int vertex_id;
#endif
#else
in vec3 particle_position_initial;
in float lifetime_initial;
@ -24,6 +29,11 @@ in vec3 particle_position;
in float lifetime;
in vec3 particle_velocity;
in float size;
#ifdef Needs_Vertex_Id_Workaround
in int vertex_id;
#endif
#endif
out vec3 new_particle_position;
@ -36,7 +46,11 @@ void main(void)
float updated_lifetime = lifetime + (float(dt)/lifetime_initial);
if (updated_lifetime > 1.)
{
#ifdef Needs_Vertex_Id_Workaround
if (vertex_id < level)
#else
if (gl_VertexID < level)
#endif
{
float dt_from_last_frame = fract(updated_lifetime) * lifetime_initial;
float coeff = dt_from_last_frame / float(dt);

View File

@ -63,6 +63,7 @@ void CentralVideoSettings::init()
m_need_rh_workaround = false;
m_need_srgb_workaround = false;
m_need_srgb_visual_workaround = false;
m_need_vertex_id_workaround = false;
// Call to glGetIntegerv should not be made if --no-graphics is used
if (!ProfileWorld::isNoGraphics())
@ -266,6 +267,11 @@ void CentralVideoSettings::init()
hasColorBufferFloat = true;
Log::info("GLDriver", "EXT Color Buffer Float Present");
}
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_VERTEX_ID_WORKING))
{
m_need_vertex_id_workaround = true;
}
#endif
}
}
@ -307,6 +313,11 @@ bool CentralVideoSettings::needsSRGBCapableVisualWorkaround() const
return m_need_srgb_visual_workaround;
}
bool CentralVideoSettings::needsVertexIdWorkaround() const
{
return m_need_vertex_id_workaround;
}
bool CentralVideoSettings::isARBGeometryShadersUsable() const
{
return hasGS;

View File

@ -54,6 +54,7 @@ private:
bool m_need_rh_workaround;
bool m_need_srgb_workaround;
bool m_need_srgb_visual_workaround;
bool m_need_vertex_id_workaround;
bool m_GI_has_artifact;
public:
void init();
@ -64,6 +65,7 @@ public:
bool needRHWorkaround() const;
bool needsRGBBindlessWorkaround() const;
bool needsSRGBCapableVisualWorkaround() const;
bool needsVertexIdWorkaround() const;
// Extension is available and safe to use
bool isARBUniformBufferObjectUsable() const;

View File

@ -145,6 +145,7 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter,
size_increase_factor = 0.;
ParticleParams = NULL;
InitialValues = NULL;
m_vertex_id_values = NULL;
m_color_from[0] = m_color_from[1] = m_color_from[2] = 1.0;
m_color_to[0] = m_color_to[1] = m_color_to[2] = 1.0;
@ -163,6 +164,8 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter,
ParticleSystemProxy::~ParticleSystemProxy()
{
delete[] m_vertex_id_values;
if (InitialValues)
free(InitialValues);
if (ParticleParams)
@ -380,6 +383,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter)
m_previous_count = m_count; // save to handle out of memory errors
m_count = emitter->getMaxParticlesPerSecond() * emitter->getMaxLifeTime() / 1000;
switch (emitter->getType())
{
case scene::EPET_POINT:
@ -394,6 +398,25 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter)
default:
assert(0 && "Wrong particle type");
}
if (CVS->needsVertexIdWorkaround())
{
if (m_count != m_previous_count)
{
delete[] m_vertex_id_values;
m_vertex_id_values = NULL;
}
if (m_vertex_id_values == NULL && m_count > 0)
{
m_vertex_id_values = new int[m_count];
for (unsigned int i = 0; i < m_count; i++)
{
m_vertex_id_values[i] = i;
}
}
}
m_texture_name = getMaterial(0).getTexture(0)->getOpenGLTextureName();
}
@ -443,7 +466,7 @@ void ParticleSystemProxy::AppendQuaternionRenderingVAO(GLuint QuaternionBuffer)
glVertexAttribDivisorARB(6, 1);
}
void ParticleSystemProxy::CommonSimulationVAO(GLuint position_vbo, GLuint initialValues_vbo)
void ParticleSystemProxy::CommonSimulationVAO(GLuint position_vbo, GLuint initialValues_vbo, GLuint vertex_id_buffer)
{
glBindBuffer(GL_ARRAY_BUFFER, position_vbo);
glEnableVertexAttribArray(0);
@ -464,6 +487,13 @@ void ParticleSystemProxy::CommonSimulationVAO(GLuint position_vbo, GLuint initia
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleSystemProxy::ParticleData), (GLvoid*)(4 * sizeof(float)));
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleSystemProxy::ParticleData), (GLvoid*)(7 * sizeof(float)));
if (CVS->needsVertexIdWorkaround())
{
glBindBuffer(GL_ARRAY_BUFFER, vertex_id_buffer);
glEnableVertexAttribArray(8);
glVertexAttribIPointer(8, 1, GL_INT, sizeof(int), (GLvoid*)0);
}
}
void ParticleSystemProxy::simulate()
@ -570,6 +600,15 @@ void ParticleSystemProxy::generateVAOs()
glBufferData(GL_ARRAY_BUFFER, m_count * sizeof(ParticleData), InitialValues, GL_STREAM_COPY);
glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]);
glBufferData(GL_ARRAY_BUFFER, m_count * sizeof(ParticleData), 0, GL_STREAM_COPY);
if (CVS->needsVertexIdWorkaround())
{
glGenBuffers(1, &vertex_id_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_id_buffer);
glBufferData(GL_ARRAY_BUFFER, m_count * sizeof(int),
m_vertex_id_values, GL_STATIC_DRAW);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenVertexArrays(1, &current_rendering_vao);
@ -577,10 +616,12 @@ void ParticleSystemProxy::generateVAOs()
glGenVertexArrays(1, &current_simulation_vao);
glGenVertexArrays(1, &non_current_simulation_vao);
// TODO: Don't execute CommonSimulationVAO twice because it unnecessarily
// initializes initial_values_buffer and vertex_id_buffer twice.
glBindVertexArray(current_simulation_vao);
CommonSimulationVAO(tfb_buffers[0], initial_values_buffer);
CommonSimulationVAO(tfb_buffers[0], initial_values_buffer, vertex_id_buffer);
glBindVertexArray(non_current_simulation_vao);
CommonSimulationVAO(tfb_buffers[1], initial_values_buffer);
CommonSimulationVAO(tfb_buffers[1], initial_values_buffer, vertex_id_buffer);
glBindVertexArray(0);
@ -612,6 +653,7 @@ void ParticleSystemProxy::generateVAOs()
if (flip)
AppendQuaternionRenderingVAO(quaternionsbuffer);
glBindVertexArray(0);
}
void ParticleSystemProxy::render() {

View File

@ -33,7 +33,8 @@ using namespace irr;
class ParticleSystemProxy : public scene::CParticleSystemSceneNode
{
protected:
GLuint tfb_buffers[2], initial_values_buffer, heighmapbuffer, heightmaptexture, quaternionsbuffer;
GLuint tfb_buffers[2], initial_values_buffer, heighmapbuffer,
heightmaptexture, quaternionsbuffer, vertex_id_buffer;
GLuint current_simulation_vao, non_current_simulation_vao;
GLuint current_rendering_vao, non_current_rendering_vao;
bool m_alpha_additive, has_height_map, flip;
@ -55,7 +56,9 @@ protected:
static void CommonRenderingVAO(GLuint PositionBuffer);
static void AppendQuaternionRenderingVAO(GLuint QuaternionBuffer);
static void CommonSimulationVAO(GLuint position_vbo, GLuint initialValues_vbo);
static void CommonSimulationVAO(GLuint position_vbo,
GLuint initialValues_vbo,
GLuint vertex_id_buffer);
void generateVAOs();
void cleanGL();
@ -80,6 +83,7 @@ protected:
private:
ParticleData *ParticleParams, *InitialValues;
int* m_vertex_id_values;
void generateParticlesFromPointEmitter(scene::IParticlePointEmitter *);
void generateParticlesFromBoxEmitter(scene::IParticleBoxEmitter *);
void generateParticlesFromSphereEmitter(scene::IParticleSphereEmitter *);

View File

@ -44,7 +44,7 @@ namespace GraphicsRestrictions
/** The list of names used in the XML file for the graphics
* restriction types. They must be in the same order as the types. */
std::array<std::string, 27> m_names_of_restrictions = {
std::array<std::string, 28> m_names_of_restrictions = {
"UniformBufferObject",
"GeometryShader",
"DrawIndirect",
@ -71,7 +71,8 @@ namespace GraphicsRestrictions
"FramebufferSRGBWorking",
"FramebufferSRGBCapable",
"GI",
"ForceLegacyDevice"
"ForceLegacyDevice",
"VertexIdWorking"
};
} // namespace Private
using namespace Private;

View File

@ -61,6 +61,7 @@ namespace GraphicsRestrictions
GR_FRAMEBUFFER_SRGB_CAPABLE,
GR_GI,
GR_FORCE_LEGACY_DEVICE,
GR_VERTEX_ID_WORKING,
GR_COUNT /** MUST be last entry. */
} ;

View File

@ -156,6 +156,11 @@ void ShaderBase::setAttribute(AttributeType type)
glBindAttribLocation(m_program, 5, "lifetime_initial");
glBindAttribLocation(m_program, 6, "particle_velocity_initial");
glBindAttribLocation(m_program, 7, "size_initial");
if (CVS->needsVertexIdWorkaround())
{
glBindAttribLocation(m_program, 8, "vertex_id");
}
break;
case PARTICLES_RENDERING:
glBindAttribLocation(m_program, 1, "lifetime");

View File

@ -164,6 +164,8 @@ GLuint ShaderFilesManager::loadShader(const std::string &file, unsigned type)
code << "#define VSLayer\n";
if (CVS->needsRGBBindlessWorkaround())
code << "#define SRGBBindlessFix\n";
if (CVS->needsVertexIdWorkaround())
code << "#define Needs_Vertex_Id_Workaround\n";
if (CVS->isDefferedEnabled())
code << "#define Advanced_Lighting_Enabled\n";