diff options
author | Stephan Unverwerth <s.unverwerth@serenityos.org> | 2022-12-22 15:12:12 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-12-26 09:39:20 +0100 |
commit | 2658351fa639e002eff2d0e04c2f1bc3d39ff3d2 (patch) | |
tree | db303793ce409117c640baac9fa6fd9fe56e3d56 | |
parent | 1ec791fcd0f42b5e47ebded8b37ce1ed3a7f3eac (diff) | |
download | serenity-2658351fa639e002eff2d0e04c2f1bc3d39ff3d2.zip |
LibVirtGPU: Adopt rendering code from VirGLDemo
-rw-r--r-- | Userland/Libraries/LibVirtGPU/Device.cpp | 113 | ||||
-rw-r--r-- | Userland/Libraries/LibVirtGPU/Device.h | 5 |
2 files changed, 109 insertions, 9 deletions
diff --git a/Userland/Libraries/LibVirtGPU/Device.cpp b/Userland/Libraries/LibVirtGPU/Device.cpp index 37e58f6bd9..f8bb98341a 100644 --- a/Userland/Libraries/LibVirtGPU/Device.cpp +++ b/Userland/Libraries/LibVirtGPU/Device.cpp @@ -182,9 +182,87 @@ GPU::DeviceInfo Device::info() const }; } -void Device::draw_primitives(GPU::PrimitiveType, FloatMatrix4x4 const&, FloatMatrix4x4 const&, Vector<GPU::Vertex>&) -{ - dbgln("VirtGPU::Device::draw_primitives(): unimplemented"); +void Device::encode_constant_buffer(Gfx::FloatMatrix4x4 const& matrix, Vector<float>& buffer) +{ + buffer.clear_with_capacity(); + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + buffer.append(matrix.elements()[i][j]); + } + } +} + +void Device::draw_primitives(GPU::PrimitiveType primitive_type, FloatMatrix4x4 const& modelview_matrix, FloatMatrix4x4 const& projection_matrix, Vector<GPU::Vertex>& vertices) +{ + // Transform incoming vertices to our own format. + m_vertices.clear_with_capacity(); + for (auto& vertex : vertices) { + m_vertices.append({ + vertex.tex_coords[0].x(), + vertex.tex_coords[0].y(), + vertex.tex_coords[0].z(), + vertex.position.x(), + vertex.position.y(), + vertex.position.z(), + }); + } + + // Compute combined transform matrix + // Flip the y axis. This is done because OpenGLs coordinate space has a Y-axis of + // Opposite direction to that of LibGfx + auto combined_matrix = (Gfx::scale_matrix(FloatVector3 { 1, -1, 1 }) * projection_matrix * modelview_matrix).transpose(); + encode_constant_buffer(combined_matrix, m_constant_buffer_data); + + // Create command buffer + CommandBufferBuilder builder; + + // Set the constant buffer to the combined transformation matrix + builder.append_set_constant_buffer(m_constant_buffer_data); + + // Transfer data from vertices array to kernel virgl transfer region + VirGLTransferDescriptor descriptor { + .data = m_vertices.data(), + .offset_in_region = 0, + .num_bytes = sizeof(VertexData) * m_vertices.size(), + .direction = VIRGL_DATA_DIR_GUEST_TO_HOST, + }; + MUST(Core::System::ioctl(m_gpu_file->fd(), VIRGL_IOCTL_TRANSFER_DATA, &descriptor)); + + // Transfer data from kernel virgl transfer region to host resource + builder.append_transfer3d(m_vbo_resource_id, sizeof(VertexData) * m_vertices.size(), 1, 1, VIRGL_DATA_DIR_GUEST_TO_HOST); + builder.append_end_transfers_3d(); + + // Set the constant buffer to the identity matrix + builder.append_set_constant_buffer(m_constant_buffer_data); + + constexpr auto map_primitive_type = [](GPU::PrimitiveType type) constexpr { + switch (type) { + case GPU::PrimitiveType::Lines: + return Protocol::PipePrimitiveTypes::LINES; + case GPU::PrimitiveType::LineLoop: + return Protocol::PipePrimitiveTypes::LINE_LOOP; + case GPU::PrimitiveType::LineStrip: + return Protocol::PipePrimitiveTypes::LINE_STRIP; + case GPU::PrimitiveType::Points: + return Protocol::PipePrimitiveTypes::POINTS; + case GPU::PrimitiveType::TriangleFan: + return Protocol::PipePrimitiveTypes::TRIANGLE_FAN; + case GPU::PrimitiveType::Triangles: + return Protocol::PipePrimitiveTypes::TRIANGLES; + case GPU::PrimitiveType::TriangleStrip: + return Protocol::PipePrimitiveTypes::TRIANGLE_STRIP; + case GPU::PrimitiveType::Quads: + return Protocol::PipePrimitiveTypes::QUADS; + default: + VERIFY_NOT_REACHED(); + } + }; + + // Draw the vbo + builder.append_draw_vbo(map_primitive_type(primitive_type), m_vertices.size()); + + // Upload the buffer + MUST(upload_command_buffer(builder.build())); } void Device::resize(Gfx::IntSize) @@ -192,14 +270,18 @@ void Device::resize(Gfx::IntSize) dbgln("VirtGPU::Device::resize(): unimplemented"); } -void Device::clear_color(FloatVector4 const&) +void Device::clear_color(FloatVector4 const& color) { - dbgln("VirtGPU::Device::clear_color(): unimplemented"); + CommandBufferBuilder builder; + builder.append_clear(color.x(), color.y(), color.z(), color.w()); + MUST(upload_command_buffer(builder.build())); } -void Device::clear_depth(GPU::DepthType) +void Device::clear_depth(GPU::DepthType depth) { - dbgln("VirtGPU::Device::clear_depth(): unimplemented"); + CommandBufferBuilder builder; + builder.append_clear(depth); + MUST(upload_command_buffer(builder.build())); } void Device::clear_stencil(GPU::StencilType) @@ -207,9 +289,22 @@ void Device::clear_stencil(GPU::StencilType) dbgln("VirtGPU::Device::clear_stencil(): unimplemented"); } -void Device::blit_from_color_buffer(Gfx::Bitmap&) +void Device::blit_from_color_buffer(Gfx::Bitmap& front_buffer) { - dbgln("VirtGPU::Device::blit_from_color_buffer(): unimplemented"); + // Transfer data back from hypervisor to kernel transfer region + CommandBufferBuilder builder; + builder.append_transfer3d(m_drawtarget, front_buffer.size().width(), front_buffer.size().height(), 1, VIRGL_DATA_DIR_HOST_TO_GUEST); + builder.append_end_transfers_3d(); + MUST(upload_command_buffer(builder.build())); + + // Copy from kernel transfer region to userspace + VirGLTransferDescriptor descriptor { + .data = front_buffer.scanline_u8(0), + .offset_in_region = 0, + .num_bytes = front_buffer.size().width() * front_buffer.size().height() * sizeof(u32), + .direction = VIRGL_DATA_DIR_HOST_TO_GUEST, + }; + MUST(Core::System::ioctl(m_gpu_file->fd(), VIRGL_IOCTL_TRANSFER_DATA, &descriptor)); } void Device::blit_from_color_buffer(NonnullRefPtr<GPU::Image>, u32, Vector2<u32>, Vector2<i32>, Vector3<i32>) diff --git a/Userland/Libraries/LibVirtGPU/Device.h b/Userland/Libraries/LibVirtGPU/Device.h index ec2e207d51..ac53b89a65 100644 --- a/Userland/Libraries/LibVirtGPU/Device.h +++ b/Userland/Libraries/LibVirtGPU/Device.h @@ -61,6 +61,7 @@ public: virtual void bind_fragment_shader(RefPtr<GPU::Shader>) override; private: + void encode_constant_buffer(Gfx::FloatMatrix4x4 const&, Vector<float>&); Protocol::ObjectHandle allocate_handle(); ErrorOr<Protocol::ResourceID> create_virgl_resource(VirGL3DResourceSpec&); ErrorOr<void> upload_command_buffer(Vector<u32> const&); @@ -88,6 +89,10 @@ private: float y; float z; }; + + Vector<VertexData> m_vertices; + + Vector<float> m_constant_buffer_data; }; } |