summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp58
1 files changed, 38 insertions, 20 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index fae9abd19..41e4ece1e 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -142,37 +142,55 @@ RasterizerOpenGL::~RasterizerOpenGL() {
}
}
-static constexpr std::array<GLenum, 4> vs_attrib_types{
- GL_BYTE, // VertexAttributeFormat::BYTE
- GL_UNSIGNED_BYTE, // VertexAttributeFormat::UBYTE
- GL_SHORT, // VertexAttributeFormat::SHORT
- GL_FLOAT // VertexAttributeFormat::FLOAT
-};
-
void RasterizerOpenGL::AnalyzeVertexArray(bool is_indexed) {
const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
- const auto& vertex_attributes = regs.vertex_attrib_format;
if (is_indexed) {
UNREACHABLE();
}
- const u32 vertex_num = regs.vertex_buffer.count;
- vs_input_size = 0;
- u32 max_offset{};
- for (const auto& attrib : vertex_attributes) {
- if (max_offset >= attrib.offset) {
- continue;
- }
- max_offset = attrib.offset;
- vs_input_size = max_offset + attrib.SizeInBytes();
- }
- vs_input_size *= vertex_num;
+ // TODO(bunnei): Add support for 1+ vertex arrays
+ vs_input_size = regs.vertex_buffer.count * regs.vertex_array[0].stride;
}
void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) {
MICROPROFILE_SCOPE(OpenGL_VAO);
- UNIMPLEMENTED();
+ const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+ const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager;
+
+ state.draw.vertex_array = hw_vao.handle;
+ state.draw.vertex_buffer = stream_buffer->GetHandle();
+ state.Apply();
+
+ // TODO(bunnei): Add support for 1+ vertex arrays
+ const auto& vertex_array{regs.vertex_array[0]};
+ ASSERT_MSG(vertex_array.enable, "vertex array 0 is disabled?");
+ ASSERT_MSG(!vertex_array.divisor, "vertex array 0 divisor is unimplemented!");
+ for (unsigned index = 1; index < Maxwell::NumVertexArrays; ++index) {
+ ASSERT_MSG(!regs.vertex_array[index].enable, "vertex array %d is unimplemented!", index);
+ }
+
+ // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.
+ // Enables the first 16 vertex attributes always, as we don't know which ones are actually used
+ // until shader time. Note, Tegra technically supports 32, but we're cappinig this to 16 for now
+ // to avoid OpenGL errors.
+ for (unsigned index = 0; index < 16; ++index) {
+ auto& attrib = regs.vertex_attrib_format[index];
+ glVertexAttribPointer(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
+ GL_FALSE, vertex_array.stride,
+ reinterpret_cast<GLvoid*>(buffer_offset + attrib.offset));
+ glEnableVertexAttribArray(index);
+ hw_vao_enabled_attributes[index] = true;
+ }
+
+ // Copy vertex array data
+ const u32 data_size{vertex_array.stride * regs.vertex_buffer.count};
+ const VAddr data_addr{memory_manager->PhysicalToVirtualAddress(vertex_array.StartAddress())};
+ res_cache.FlushRegion(data_addr, data_size, nullptr);
+ std::memcpy(array_ptr, Memory::GetPointer(data_addr), data_size);
+
+ array_ptr += data_size;
+ buffer_offset += data_size;
}
void RasterizerOpenGL::SetupVertexShader(VSUniformData* ub_ptr, GLintptr buffer_offset) {