gl_rasterizer: Implement SetupVertexArray.

This commit is contained in:
bunnei 2018-03-24 21:29:47 -04:00
parent cd8bb6ea9b
commit c2dbdefedf

View File

@ -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) { void RasterizerOpenGL::AnalyzeVertexArray(bool is_indexed) {
const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
const auto& vertex_attributes = regs.vertex_attrib_format;
if (is_indexed) { if (is_indexed) {
UNREACHABLE(); UNREACHABLE();
} }
const u32 vertex_num = regs.vertex_buffer.count;
vs_input_size = 0; // TODO(bunnei): Add support for 1+ vertex arrays
u32 max_offset{}; vs_input_size = regs.vertex_buffer.count * regs.vertex_array[0].stride;
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;
} }
void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) {
MICROPROFILE_SCOPE(OpenGL_VAO); 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) { void RasterizerOpenGL::SetupVertexShader(VSUniformData* ub_ptr, GLintptr buffer_offset) {