|
|
|
@ -2,11 +2,14 @@ |
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
#include <cstddef>
|
|
|
|
#include <glad/glad.h>
|
|
|
|
|
|
|
|
#include "common/logging/log.h"
|
|
|
|
#include "common/scope_exit.h"
|
|
|
|
#include "video_core/renderer_opengl/gl_device.h"
|
|
|
|
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
|
|
|
|
|
|
|
namespace OpenGL { |
|
|
|
|
|
|
|
@ -24,6 +27,7 @@ Device::Device() { |
|
|
|
max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS); |
|
|
|
max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS); |
|
|
|
has_variable_aoffi = TestVariableAoffi(); |
|
|
|
has_component_indexing_bug = TestComponentIndexingBug(); |
|
|
|
} |
|
|
|
|
|
|
|
Device::Device(std::nullptr_t) { |
|
|
|
@ -31,6 +35,7 @@ Device::Device(std::nullptr_t) { |
|
|
|
max_vertex_attributes = 16; |
|
|
|
max_varyings = 15; |
|
|
|
has_variable_aoffi = true; |
|
|
|
has_component_indexing_bug = false; |
|
|
|
} |
|
|
|
|
|
|
|
bool Device::TestVariableAoffi() { |
|
|
|
@ -52,4 +57,53 @@ void main() { |
|
|
|
return supported; |
|
|
|
} |
|
|
|
|
|
|
|
bool Device::TestComponentIndexingBug() { |
|
|
|
constexpr char log_message[] = "Renderer_ComponentIndexingBug: {}"; |
|
|
|
const GLchar* COMPONENT_TEST = R"(#version 430 core |
|
|
|
layout (std430, binding = 0) buffer OutputBuffer { |
|
|
|
uint output_value; |
|
|
|
}; |
|
|
|
layout (std140, binding = 0) uniform InputBuffer { |
|
|
|
uvec4 input_value[4096]; |
|
|
|
}; |
|
|
|
layout (location = 0) uniform uint idx; |
|
|
|
void main() { |
|
|
|
output_value = input_value[idx >> 2][idx & 3]; |
|
|
|
})"; |
|
|
|
const GLuint shader{glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &COMPONENT_TEST)}; |
|
|
|
SCOPE_EXIT({ glDeleteProgram(shader); }); |
|
|
|
glUseProgram(shader); |
|
|
|
|
|
|
|
OGLVertexArray vao; |
|
|
|
vao.Create(); |
|
|
|
glBindVertexArray(vao.handle); |
|
|
|
|
|
|
|
constexpr std::array<GLuint, 8> values{0, 0, 0, 0, 0x1236327, 0x985482, 0x872753, 0x2378432}; |
|
|
|
OGLBuffer ubo; |
|
|
|
ubo.Create(); |
|
|
|
glNamedBufferData(ubo.handle, sizeof(values), values.data(), GL_STATIC_DRAW); |
|
|
|
glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo.handle); |
|
|
|
|
|
|
|
OGLBuffer ssbo; |
|
|
|
ssbo.Create(); |
|
|
|
glNamedBufferStorage(ssbo.handle, sizeof(GLuint), nullptr, GL_CLIENT_STORAGE_BIT); |
|
|
|
|
|
|
|
for (GLuint index = 4; index < 8; ++index) { |
|
|
|
glInvalidateBufferData(ssbo.handle); |
|
|
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo.handle); |
|
|
|
|
|
|
|
glProgramUniform1ui(shader, 0, index); |
|
|
|
glDrawArrays(GL_POINTS, 0, 1); |
|
|
|
|
|
|
|
GLuint result; |
|
|
|
glGetNamedBufferSubData(ssbo.handle, 0, sizeof(result), &result); |
|
|
|
if (result != values.at(index)) { |
|
|
|
LOG_INFO(Render_OpenGL, log_message, true); |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
LOG_INFO(Render_OpenGL, log_message, false); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
} // namespace OpenGL
|