diff --git a/Userland/Demos/CMakeLists.txt b/Userland/Demos/CMakeLists.txt index a00daa57410..6112a529947 100644 --- a/Userland/Demos/CMakeLists.txt +++ b/Userland/Demos/CMakeLists.txt @@ -10,5 +10,4 @@ add_subdirectory(Mouse) add_subdirectory(Screensaver) add_subdirectory(Starfield) add_subdirectory(Tubes) -add_subdirectory(VirGLDemo) add_subdirectory(WidgetGallery) diff --git a/Userland/Demos/VirGLDemo/CMakeLists.txt b/Userland/Demos/VirGLDemo/CMakeLists.txt deleted file mode 100644 index c8839eec1ff..00000000000 --- a/Userland/Demos/VirGLDemo/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -serenity_component( - VirGLDemo - TARGETS VirGLDemo -) - -set(SOURCES - CommandBufferBuilder.cpp - VirGLDemo.cpp - Widget.cpp -) - -serenity_app(VirGLDemo ICON app-cube) -target_link_libraries(VirGLDemo PRIVATE LibCore LibMain LibGfx LibGUI) diff --git a/Userland/Demos/VirGLDemo/CommandBufferBuilder.cpp b/Userland/Demos/VirGLDemo/CommandBufferBuilder.cpp deleted file mode 100644 index 8f47c7cd8a4..00000000000 --- a/Userland/Demos/VirGLDemo/CommandBufferBuilder.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (c) 2022, Sahan Fernando - * Copyright (c) 2022, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include - -#include "CommandBufferBuilder.h" -#include "VirGLProtocol.h" -#include "Widget.h" - -static u32 encode_command(u32 length, u32 mid, Protocol::VirGLCommand command) -{ - u32 command_value = to_underlying(command); - return (length << 16) | ((mid & 0xff) << 8) | (command_value & 0xff); -}; - -class CommandBuilder { -public: - CommandBuilder() = delete; - CommandBuilder(Vector& buffer, Protocol::VirGLCommand command, u32 mid) - : m_buffer(buffer) - , m_start_offset(buffer.size()) - , m_command(command) - , m_command_mid(mid) - { - m_buffer.append(0); - } - void appendu32(u32 value) - { - VERIFY(!m_finalized); - m_buffer.append(value); - } - void appendf32(float value) - { - VERIFY(!m_finalized); - m_buffer.append(bit_cast(value)); - } - void appendf64(double value) - { - VERIFY(!m_finalized); - m_buffer.append(0); - m_buffer.append(0); - auto* depth = (u64*)(&m_buffer[m_buffer.size() - 2]); - *depth = bit_cast(value); - } - void append_string_null_padded(StringView string) - { - VERIFY(!m_finalized); - // Remember to have at least one null terminator byte - auto length = string.length() + 1; - auto num_required_words = (length + sizeof(u32) - 1) / sizeof(u32); - m_buffer.resize(m_buffer.size() + num_required_words); - char* dest = (char*)&m_buffer[m_buffer.size() - num_required_words]; - memcpy(dest, string.characters_without_null_termination(), string.length()); - // Pad end with null bytes - memset(&dest[string.length()], 0, 4 * num_required_words - string.length()); - } - void finalize() - { - if (!m_finalized) { - m_finalized = true; - size_t num_elems = m_buffer.size() - m_start_offset - 1; - m_buffer[m_start_offset] = encode_command(num_elems, m_command_mid, m_command); - } - } - ~CommandBuilder() - { - if (!m_finalized) - finalize(); - } - -private: - Vector& m_buffer; - size_t m_start_offset; - Protocol::VirGLCommand m_command; - u32 m_command_mid; - bool m_finalized { false }; -}; - -void CommandBufferBuilder::append_set_tweaks(u32 id, u32 value) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::SET_TWEAKS, 0); - builder.appendu32(id); - builder.appendu32(value); -} - -void CommandBufferBuilder::append_transfer3d(ResourceID resource, size_t width, size_t height, size_t depth, size_t direction) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::TRANSFER3D, 0); - builder.appendu32(resource.value()); // res_handle - builder.appendu32(0); // level - builder.appendu32(242); // usage - builder.appendu32(0); // stride - builder.appendu32(0); // layer_stride - builder.appendu32(0); // x - builder.appendu32(0); // y - builder.appendu32(0); // z - builder.appendu32(width); // width - builder.appendu32(height); // height - builder.appendu32(depth); // depth - builder.appendu32(0); // data_offset - builder.appendu32(direction); // direction -} - -void CommandBufferBuilder::append_end_transfers_3d() -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::END_TRANSFERS, 0); -} - -void CommandBufferBuilder::append_draw_vbo(u32 count) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::DRAW_VBO, 0); - builder.appendu32(0); // start - builder.appendu32(count); // count - builder.appendu32(to_underlying(Protocol::PipePrimitiveTypes::TRIANGLES)); // mode - builder.appendu32(0); // indexed - builder.appendu32(1); // instance_count - builder.appendu32(0); // index_bias - builder.appendu32(0); // start_instance - builder.appendu32(0); // primitive_restart - builder.appendu32(0); // restart_index - builder.appendu32(0); // min_index - builder.appendu32(0xffffffff); // max_index - builder.appendu32(0); // cso -} - -void CommandBufferBuilder::append_gl_clear(float r, float g, float b) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::CLEAR, 0); - Protocol::ClearType clear_flags {}; - clear_flags.flags.depth = 1; - clear_flags.flags.color0 = 1; - builder.appendu32(clear_flags.value); - builder.appendf32(r); - builder.appendf32(g); - builder.appendf32(b); - builder.appendf32(1.0f); // Alpha - builder.appendf64(1.0); // Depth - builder.appendu32(0); // Stencil -} - -void CommandBufferBuilder::append_set_vertex_buffers(u32 stride, u32 offset, ResourceID resource) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::SET_VERTEX_BUFFERS, 0); - builder.appendu32(stride); - builder.appendu32(offset); - builder.appendu32(resource.value()); -} - -void CommandBufferBuilder::append_create_blend(ObjectHandle handle) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::CREATE_OBJECT, to_underlying(Protocol::ObjectType::BLEND)); - builder.appendu32(handle.value()); - builder.appendu32(4); // Enable dither flag, and nothing else - builder.appendu32(0); - builder.appendu32(0x78000000); // Enable all bits of color mask for color buffer 0, and nothing else - for (size_t i = 1; i < 8; ++i) { - builder.appendu32(0); // Explicitly disable all flags for other color buffers - } -} - -void CommandBufferBuilder::append_bind_blend(ObjectHandle handle) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::BIND_OBJECT, to_underlying(Protocol::ObjectType::BLEND)); - builder.appendu32(handle.value()); // VIRGL_OBJ_BIND_HANDLE -} - -void CommandBufferBuilder::append_create_vertex_elements(ObjectHandle handle) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::CREATE_OBJECT, to_underlying(Protocol::ObjectType::VERTEX_ELEMENTS)); - builder.appendu32(handle.value()); - builder.appendu32(12); // src_offset_0 - builder.appendu32(0); // instance_divisor_0 - builder.appendu32(0); // vertex_buffer_index_0 - builder.appendu32(30); // src_format_0 (PIPE_FORMAT_R32G32B32_FLOAT = 30) - builder.appendu32(0); // src_offset_1 - builder.appendu32(0); // instance_divisor_1 - builder.appendu32(0); // vertex_buffer_index_1 - builder.appendu32(30); // src_format_1 (PIPE_FORMAT_R32G32B32_FLOAT = 30) -} - -void CommandBufferBuilder::append_bind_vertex_elements(ObjectHandle handle) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::BIND_OBJECT, to_underlying(Protocol::ObjectType::VERTEX_ELEMENTS)); - builder.appendu32(handle.value()); // VIRGL_OBJ_BIND_HANDLE -} - -void CommandBufferBuilder::append_create_surface(ResourceID drawtarget_resource, ObjectHandle drawtarget_handle, Protocol::TextureFormat format) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::CREATE_OBJECT, to_underlying(Protocol::ObjectType::SURFACE)); - builder.appendu32(drawtarget_handle.value()); - builder.appendu32(drawtarget_resource.value()); - builder.appendu32(to_underlying(format)); - builder.appendu32(0); // First element / Texture Level - builder.appendu32(0); // Last element / Texture Element -} - -void CommandBufferBuilder::append_set_framebuffer_state(ObjectHandle drawtarget, ObjectHandle depthbuffer) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::SET_FRAMEBUFFER_STATE, 0); - builder.appendu32(1); // nr_cbufs - builder.appendu32(depthbuffer.value()); // zsurf_handle - builder.appendu32(drawtarget.value()); // surf_handle -} - -void CommandBufferBuilder::append_gl_viewport() -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::SET_VIEWPORT_STATE, 0); - builder.appendu32(0); - builder.appendf32(DRAWTARGET_WIDTH / 2); // scale_x - builder.appendf32((DRAWTARGET_HEIGHT / 2)); // scale_y (flipped, due to VirGL being different from our coordinate space) - builder.appendf32(0.5f); // scale_z - builder.appendf32(DRAWTARGET_WIDTH / 2); // translate_x - builder.appendf32(DRAWTARGET_HEIGHT / 2); // translate_y - builder.appendf32(0.5f); // translate_z -} - -void CommandBufferBuilder::append_set_framebuffer_state_no_attach() -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::SET_FRAMEBUFFER_STATE_NO_ATTACH, 0); - builder.appendu32((DRAWTARGET_HEIGHT << 16) | DRAWTARGET_WIDTH); // (height << 16) | width - builder.appendu32(0); // (samples << 16) | layers -} - -void CommandBufferBuilder::append_set_constant_buffer(Vector const& constant_buffer) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::SET_CONSTANT_BUFFER, 0); - builder.appendu32(to_underlying(Gallium::ShaderType::SHADER_VERTEX)); - builder.appendu32(0); // index (currently unused according to virglrenderer source code) - for (auto v : constant_buffer) { - builder.appendf32(v); - } -} - -void CommandBufferBuilder::append_create_shader(ObjectHandle handle, Gallium::ShaderType shader_type, StringView shader_data) -{ - size_t shader_len = shader_data.length() + 1; // Need to remember to copy null terminator as well if needed - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::CREATE_OBJECT, to_underlying(Protocol::ObjectType::SHADER)); - builder.appendu32(handle.value()); // VIRGL_OBJ_CREATE_HANDLE - builder.appendu32(to_underlying(shader_type)); - builder.appendu32(0); // VIRGL_OBJ_SHADER_OFFSET - builder.appendu32(shader_len); - builder.appendu32(0); // VIRGL_OBJ_SHADER_NUM_TOKENS - builder.append_string_null_padded(shader_data); -} - -void CommandBufferBuilder::append_bind_shader(ObjectHandle handle, Gallium::ShaderType shader_type) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::BIND_SHADER, 0); - builder.appendu32(handle.value()); // VIRGL_OBJ_BIND_HANDLE - builder.appendu32(to_underlying(shader_type)); -} - -void CommandBufferBuilder::append_create_rasterizer(ObjectHandle handle) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::CREATE_OBJECT, to_underlying(Protocol::ObjectType::RASTERIZER)); - builder.appendu32(handle.value()); // Handle - builder.appendu32(0x00000002); // S0 (bitfield of state bits) - builder.appendf32(1.0); // Point size - builder.appendu32(0); // Sprite coord enable - builder.appendu32(0x00000000); // S3 (bitfield of state bits) - builder.appendf32(0.1); // Line width - builder.appendf32(0.0); // Offset units - builder.appendf32(0.0); // offset scale - builder.appendf32(0.0); // Offset clamp -} - -void CommandBufferBuilder::append_bind_rasterizer(ObjectHandle handle) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::BIND_OBJECT, to_underlying(Protocol::ObjectType::RASTERIZER)); - builder.appendu32(handle.value()); // VIRGL_OBJ_BIND_HANDLE -} - -void CommandBufferBuilder::append_create_dsa(ObjectHandle handle) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::CREATE_OBJECT, to_underlying(Protocol::ObjectType::DSA)); - builder.appendu32(handle.value()); // Handle - builder.appendu32(0x00000007); // S0 (bitset: (v >> 0) & 1 = depth.enabled, (v >> 1) & 1 = depth.writemask, (v >> 2) & 7 = depth.func) - builder.appendu32(0x00000000); // S1 (bitset for 1st stencil buffer) - builder.appendu32(0x00000000); // S2 (bitset for 2nd stencil buffer) - builder.appendf32(1.0); // Alpha Ref -} - -void CommandBufferBuilder::append_bind_dsa(ObjectHandle handle) -{ - CommandBuilder builder(m_buffer, Protocol::VirGLCommand::BIND_OBJECT, to_underlying(Protocol::ObjectType::DSA)); - builder.appendu32(handle.value()); // VIRGL_OBJ_BIND_HANDLE -} diff --git a/Userland/Demos/VirGLDemo/CommandBufferBuilder.h b/Userland/Demos/VirGLDemo/CommandBufferBuilder.h deleted file mode 100644 index 34250d7f5b4..00000000000 --- a/Userland/Demos/VirGLDemo/CommandBufferBuilder.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2022, Sahan Fernando - * Copyright (c) 2022, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include - -#include "VirGLProtocol.h" - -class CommandBufferBuilder { -public: - void append_set_tweaks(u32 id, u32 value); - void append_transfer3d(ResourceID resource, size_t width, size_t height = 1, size_t depth = 1, size_t direction = VIRGL_DATA_DIR_GUEST_TO_HOST); - void append_end_transfers_3d(); - void append_draw_vbo(u32 count); - void append_gl_clear(float r, float g, float b); - void append_set_vertex_buffers(u32 stride, u32 offset, ResourceID resource); - void append_create_blend(ObjectHandle handle); - void append_bind_blend(ObjectHandle handle); - void append_create_surface(ResourceID drawtarget_resource, ObjectHandle drawtarget_handle, Protocol::TextureFormat format); - void append_set_framebuffer_state(ObjectHandle drawtarget, ObjectHandle depthbuffer = 0); - void append_create_vertex_elements(ObjectHandle handle); - void append_bind_vertex_elements(ObjectHandle handle); - void append_gl_viewport(); - void append_set_framebuffer_state_no_attach(); - void append_set_constant_buffer(Vector const& constant_buffer); - void append_create_shader(ObjectHandle handle, Gallium::ShaderType shader_type, StringView shader_data); - void append_bind_shader(ObjectHandle handle, Gallium::ShaderType shader_type); - void append_create_rasterizer(ObjectHandle handle); - void append_bind_rasterizer(ObjectHandle handle); - void append_create_dsa(ObjectHandle handle); - void append_bind_dsa(ObjectHandle handle); - Vector const& build() { return m_buffer; } - -private: - Vector m_buffer; -}; diff --git a/Userland/Demos/VirGLDemo/VirGLDemo.cpp b/Userland/Demos/VirGLDemo/VirGLDemo.cpp deleted file mode 100644 index 76f8295ecb1..00000000000 --- a/Userland/Demos/VirGLDemo/VirGLDemo.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2022, Sahan Fernando - * Copyright (c) 2022, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "CommandBufferBuilder.h" -#include "VirGLProtocol.h" -#include "Widget.h" - -static constexpr auto frag_shader = "FRAG\n" - "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n" - "DCL IN[0], COLOR, COLOR\n" - "DCL OUT[0], COLOR\n" - " 0: MOV OUT[0], IN[0]\n" - " 1: END\n"sv; - -static constexpr auto vert_shader = "VERT\n" - "DCL IN[0]\n" - "DCL IN[1]\n" - "DCL OUT[0], POSITION\n" - "DCL OUT[1], COLOR\n" - "DCL CONST[0..3]\n" - "DCL TEMP[0..1]\n" - " 0: MUL TEMP[0], IN[0].xxxx, CONST[0]\n" - " 1: MAD TEMP[1], IN[0].yyyy, CONST[1], TEMP[0]\n" - " 2: MAD TEMP[0], IN[0].zzzz, CONST[2], TEMP[1]\n" - " 3: MAD OUT[0], IN[0].wwww, CONST[3], TEMP[0]\n" - " 4: MOV_SAT OUT[1], IN[1]\n" - " 5: END\n"sv; - -struct VertexData { - float r; - float g; - float b; - float x; - float y; - float z; -}; - -int gpu_fd; -ResourceID vbo_resource_id; -ResourceID drawtarget; -ResourceID depthbuffer_surface; -ObjectHandle blend_handle; -ObjectHandle drawtarget_surface_handle; -ObjectHandle depthbuffer_surface_handle; -ObjectHandle ve_handle; -ObjectHandle frag_shader_handle; -ObjectHandle vert_shader_handle; -ObjectHandle rasterizer_handle; -ObjectHandle dsa_handle; -Vector g_vertices; - -static ObjectHandle allocate_handle() -{ - static u32 last_allocated_handle = 0; - return { ++last_allocated_handle }; -} - -static void upload_command_buffer(Vector const& command_buffer) -{ - VERIFY(command_buffer.size() <= NumericLimits::max()); - VirGLCommandBuffer command_buffer_descriptor { - .data = command_buffer.data(), - .num_elems = (u32)command_buffer.size(), - }; - VERIFY(ioctl(gpu_fd, VIRGL_IOCTL_SUBMIT_CMD, &command_buffer_descriptor) >= 0); -} - -static ResourceID create_virgl_resource(VirGL3DResourceSpec& spec) -{ - VERIFY(ioctl(gpu_fd, VIRGL_IOCTL_CREATE_RESOURCE, &spec) >= 0); - return spec.created_resource_id; -} - -static Vector gen_vertex_data() -{ - Vector data; - static constexpr Array vertices = { - VertexData { .r = 0, .g = 0, .b = 0, .x = -0.5, .y = -0.5, .z = -0.5 }, - VertexData { .r = 0, .g = 0, .b = 0, .x = 0.5, .y = -0.5, .z = -0.5 }, - VertexData { .r = 0, .g = 0, .b = 0, .x = -0.5, .y = 0.5, .z = -0.5 }, - VertexData { .r = 0, .g = 0, .b = 0, .x = 0.5, .y = 0.5, .z = -0.5 }, - VertexData { .r = 0, .g = 0, .b = 0, .x = -0.5, .y = -0.5, .z = 0.5 }, - VertexData { .r = 0, .g = 0, .b = 0, .x = 0.5, .y = -0.5, .z = 0.5 }, - VertexData { .r = 0, .g = 0, .b = 0, .x = -0.5, .y = 0.5, .z = 0.5 }, - VertexData { .r = 0, .g = 0, .b = 0, .x = 0.5, .y = 0.5, .z = 0.5 }, - }; - static constexpr Array tris = { - 0, 1, 2, 1, 3, 2, // Top - 4, 0, 6, 0, 2, 6, // Left - 4, 5, 0, 5, 1, 0, // Up - 1, 5, 3, 5, 7, 3, // Right - 2, 3, 6, 3, 7, 6, // Down - 5, 4, 7, 4, 6, 7, // Bottom - }; - for (auto index : tris) { - data.append(vertices[index]); - } - // Choose random colors for each face of the cube - for (auto i = 0; i < 6; ++i) { - float red = (rand() % 256) / 255.f; - float green = (rand() % 256) / 255.f; - float blue = (rand() % 256) / 255.f; - for (auto j = 0; j < 6; ++j) { - auto& vertex = data[i * 6 + j]; - vertex.r = red; - vertex.g = green; - vertex.b = blue; - } - } - return data; -} - -static void init() -{ - // Open the device - gpu_fd = open("/dev/gpu/render0", O_RDWR); - VERIFY(gpu_fd >= 0); - // Create a virgl context for this file descriptor - VERIFY(ioctl(gpu_fd, VIRGL_IOCTL_CREATE_CONTEXT) >= 0); - // Create a VertexElements resource - VirGL3DResourceSpec vbo_spec { - .target = to_underlying(Gallium::PipeTextureTarget::BUFFER), // pipe_texture_target - .format = 45, // pipe_to_virgl_format - .bind = VIRGL_BIND_VERTEX_BUFFER, - .width = PAGE_SIZE, - .height = 1, - .depth = 1, - .array_size = 1, - .last_level = 0, - .nr_samples = 0, - .flags = 0, - .created_resource_id = 0, - }; - vbo_resource_id = create_virgl_resource(vbo_spec); - // Create a texture to draw to - VirGL3DResourceSpec drawtarget_spec { - .target = to_underlying(Gallium::PipeTextureTarget::TEXTURE_RECT), // pipe_texture_target - .format = to_underlying(Protocol::TextureFormat::VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM), // pipe_to_virgl_format - .bind = VIRGL_BIND_RENDER_TARGET, - .width = DRAWTARGET_WIDTH, - .height = DRAWTARGET_HEIGHT, - .depth = 1, - .array_size = 1, - .last_level = 0, - .nr_samples = 0, - .flags = 0, - .created_resource_id = 0, - }; - drawtarget = create_virgl_resource(drawtarget_spec); - // Create a depthbuffer surface - VirGL3DResourceSpec depthbuffer_surface_spec { - .target = to_underlying(Gallium::PipeTextureTarget::TEXTURE_RECT), // pipe_texture_target - .format = to_underlying(Protocol::TextureFormat::VIRTIO_GPU_FORMAT_Z32_FLOAT), // pipe_to_virgl_format - .bind = VIRGL_BIND_RENDER_TARGET | VIRGL_BIND_DEPTH_STENCIL, - .width = DRAWTARGET_WIDTH, - .height = DRAWTARGET_HEIGHT, - .depth = 1, - .array_size = 1, - .last_level = 0, - .nr_samples = 0, - .flags = 0, - .created_resource_id = 0, - }; - depthbuffer_surface = create_virgl_resource(depthbuffer_surface_spec); - - // Initialize all required state - CommandBufferBuilder builder; - // Create and set the blend, to control the color mask - blend_handle = allocate_handle(); - builder.append_create_blend(blend_handle); - builder.append_bind_blend(blend_handle); - // Create drawtarget surface - drawtarget_surface_handle = allocate_handle(); - builder.append_create_surface(drawtarget, drawtarget_surface_handle, Protocol::TextureFormat::VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM); - // Create depthbuffer surface - depthbuffer_surface_handle = allocate_handle(); - builder.append_create_surface(depthbuffer_surface, depthbuffer_surface_handle, Protocol::TextureFormat::VIRTIO_GPU_FORMAT_Z32_FLOAT); - // Set some framebuffer state (attached handle, framebuffer size, etc) - builder.append_set_framebuffer_state(drawtarget_surface_handle, depthbuffer_surface_handle); - builder.append_set_framebuffer_state_no_attach(); - // Set the vertex buffer - builder.append_set_vertex_buffers(sizeof(VertexData), 0, vbo_resource_id); - // Create and bind fragment shader - frag_shader_handle = allocate_handle(); - builder.append_create_shader(frag_shader_handle, Gallium::ShaderType::SHADER_FRAGMENT, frag_shader); - builder.append_bind_shader(frag_shader_handle, Gallium::ShaderType::SHADER_FRAGMENT); - // Create and bind vertex shader - vert_shader_handle = allocate_handle(); - builder.append_create_shader(vert_shader_handle, Gallium::ShaderType::SHADER_VERTEX, vert_shader); - builder.append_bind_shader(vert_shader_handle, Gallium::ShaderType::SHADER_VERTEX); - // Create a VertexElements object (used to specify layout of vertex data) - ve_handle = allocate_handle(); - builder.append_create_vertex_elements(ve_handle); - builder.append_bind_vertex_elements(ve_handle); - // Create a DepthStencilAlpha (DSA) object - dsa_handle = allocate_handle(); - builder.append_create_dsa(dsa_handle); - builder.append_bind_dsa(dsa_handle); - // Create a Rasterizer object - rasterizer_handle = allocate_handle(); - builder.append_create_rasterizer(rasterizer_handle); - builder.append_bind_rasterizer(rasterizer_handle); - // Set the Viewport - builder.append_gl_viewport(); - // Upload buffer - upload_command_buffer(builder.build()); - - // Setup the vertex data - g_vertices = gen_vertex_data(); -} - -static Gfx::FloatMatrix4x4 get_transform_matrix(unsigned step_num) -{ - auto mat = Gfx::FloatMatrix4x4::identity(); - float angle = step_num * 0.02; - mat = mat * Gfx::rotation_matrix(FloatVector3(1, 0, 0), angle * 1.17356641f); - mat = mat * Gfx::rotation_matrix(FloatVector3(0, 1, 0), angle * 0.90533273f); - mat = mat * Gfx::rotation_matrix(FloatVector3(0, 0, 1), angle); - return mat; -} - -static Vector encode_constant_buffer(Gfx::FloatMatrix4x4 const& mat) -{ - // Flip the y axis. This is done because OpenGLs coordinate space has a Y-axis of - // Opposite direction to that of LibGfx - Gfx::FloatMatrix4x4 flip_y = Gfx::FloatMatrix4x4::identity(); - flip_y.elements()[1][1] = -1; - auto real_mat = mat * flip_y; - Vector values; - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 4; ++j) { - values.append(real_mat.elements()[i][j]); - } - } - return values; -} - -static void draw_frame(unsigned step_num) -{ - // Get model matrix - auto model_matrix = get_transform_matrix(step_num); - VirGLTransferDescriptor descriptor { - .data = (void*)g_vertices.data(), - .offset_in_region = 0, - .num_bytes = sizeof(VertexData) * g_vertices.size(), - .direction = VIRGL_DATA_DIR_GUEST_TO_HOST, - }; - // Transfer data from vertices array to kernel virgl transfer region - VERIFY(ioctl(gpu_fd, VIRGL_IOCTL_TRANSFER_DATA, &descriptor) >= 0); - // Create command buffer - CommandBufferBuilder builder; - // Transfer data from kernel virgl transfer region to host resource - builder.append_transfer3d(vbo_resource_id, sizeof(VertexData) * g_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(encode_constant_buffer(model_matrix)); - // Clear the framebuffer - builder.append_gl_clear(0, 0, 0); - // Draw the vbo - builder.append_draw_vbo(g_vertices.size()); - // Upload the buffer - upload_command_buffer(builder.build()); -} - -void update_frame(RefPtr target, unsigned num_cycles) -{ - VERIFY(target->width() == DRAWTARGET_WIDTH); - VERIFY(target->height() == DRAWTARGET_HEIGHT); - // Run logic to draw the frame - draw_frame(num_cycles); - // Transfer data back from hypervisor to kernel transfer region - CommandBufferBuilder builder; - builder.append_transfer3d(drawtarget, DRAWTARGET_WIDTH, DRAWTARGET_HEIGHT, 1, VIRGL_DATA_DIR_HOST_TO_GUEST); - builder.append_end_transfers_3d(); - upload_command_buffer(builder.build()); - // Copy from kernel transfer region to userspace - VirGLTransferDescriptor descriptor { - .data = (void*)target->scanline_u8(0), - .offset_in_region = 0, - .num_bytes = DRAWTARGET_WIDTH * DRAWTARGET_HEIGHT * sizeof(u32), - .direction = VIRGL_DATA_DIR_HOST_TO_GUEST, - }; - VERIFY(ioctl(gpu_fd, VIRGL_IOCTL_TRANSFER_DATA, &descriptor) >= 0); -} - -ErrorOr serenity_main(Main::Arguments arguments) -{ - auto app = TRY(GUI::Application::try_create(arguments)); - - auto window = TRY(GUI::Window::try_create()); - window->set_double_buffering_enabled(true); - window->set_title("VirGLDemo"); - window->set_resizable(false); - window->resize(DRAWTARGET_WIDTH, DRAWTARGET_HEIGHT); - window->set_has_alpha_channel(false); - window->set_alpha_hit_threshold(1); - - auto demo = TRY(Demo::create()); - window->set_main_widget(demo); - - auto app_icon = GUI::Icon::default_icon("app-cube"sv); - window->set_icon(app_icon.bitmap_for_size(16)); - - init(); - window->show(); - - return app->exec(); -} diff --git a/Userland/Demos/VirGLDemo/VirGLProtocol.h b/Userland/Demos/VirGLDemo/VirGLProtocol.h deleted file mode 100644 index 15d4afa5831..00000000000 --- a/Userland/Demos/VirGLDemo/VirGLProtocol.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2022, Sahan Fernando - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include - -AK_TYPEDEF_DISTINCT_ORDERED_ID(u32, ObjectHandle); -AK_TYPEDEF_DISTINCT_ORDERED_ID(u32, ResourceID); - -#define VIRGL_BIND_DEPTH_STENCIL (1 << 0) -#define VIRGL_BIND_RENDER_TARGET (1 << 1) -#define VIRGL_BIND_SAMPLER_VIEW (1 << 3) -#define VIRGL_BIND_VERTEX_BUFFER (1 << 4) -#define VIRGL_BIND_INDEX_BUFFER (1 << 5) -#define VIRGL_BIND_CONSTANT_BUFFER (1 << 6) -#define VIRGL_BIND_DISPLAY_TARGET (1 << 7) -#define VIRGL_BIND_COMMAND_ARGS (1 << 8) -#define VIRGL_BIND_STREAM_OUTPUT (1 << 11) -#define VIRGL_BIND_SHADER_BUFFER (1 << 14) -#define VIRGL_BIND_QUERY_BUFFER (1 << 15) -#define VIRGL_BIND_CURSOR (1 << 16) -#define VIRGL_BIND_CUSTOM (1 << 17) -#define VIRGL_BIND_SCANOUT (1 << 18) -#define VIRGL_BIND_STAGING (1 << 19) -#define VIRGL_BIND_SHARED (1 << 20) - -namespace Protocol { - -enum class TextureFormat : u32 { - // RGBA Formats - VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM = 1, - VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM = 2, - VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM = 3, - VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM = 4, - - VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM = 67, - VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM = 68, - - VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM = 121, - VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM = 134, - - // Stencil-Depth Formats - VIRTIO_GPU_FORMAT_Z16_UNORM = 16, - VIRTIO_GPU_FORMAT_Z32_UNORM = 17, - VIRTIO_GPU_FORMAT_Z32_FLOAT = 18, - VIRTIO_GPU_FORMAT_Z24_UNORM_S8_UINT = 19, - VIRTIO_GPU_FORMAT_S8_UINT_Z24_UNORM = 20, - VIRTIO_GPU_FORMAT_Z24X8_UNORM = 21, - VIRTIO_GPU_FORMAT_X8Z24_UNORM = 22, - VIRTIO_GPU_FORMAT_S8_UINT = 23, - VIRTIO_GPU_FORMAT_Z32_FLOAT_S8X24_UINT = 128, - VIRTIO_GPU_FORMAT_X24S8_UINT = 136, - VIRTIO_GPU_FORMAT_S8X24_UINT = 137, - VIRTIO_GPU_FORMAT_X32_S8X24_UINT = 138, - -}; - -enum class VirGLCommand : u32 { - NOP = 0, - CREATE_OBJECT = 1, - BIND_OBJECT, - DESTROY_OBJECT, - SET_VIEWPORT_STATE, - SET_FRAMEBUFFER_STATE, - SET_VERTEX_BUFFERS, - CLEAR, - DRAW_VBO, - RESOURCE_INLINE_WRITE, - SET_SAMPLER_VIEWS, - SET_INDEX_BUFFER, - SET_CONSTANT_BUFFER, - SET_STENCIL_REF, - SET_BLEND_COLOR, - SET_SCISSOR_STATE, - BLIT, - RESOURCE_COPY_REGION, - BIND_SAMPLER_STATES, - BEGIN_QUERY, - END_QUERY, - GET_QUERY_RESULT, - SET_POLYGON_STIPPLE, - SET_CLIP_STATE, - SET_SAMPLE_MASK, - SET_STREAMOUT_TARGETS, - SET_RENDER_CONDITION, - SET_UNIFORM_BUFFER, - - SET_SUB_CTX, - CREATE_SUB_CTX, - DESTROY_SUB_CTX, - BIND_SHADER, - SET_TESS_STATE, - SET_MIN_SAMPLES, - SET_SHADER_BUFFERS, - SET_SHADER_IMAGES, - MEMORY_BARRIER, - LAUNCH_GRID, - SET_FRAMEBUFFER_STATE_NO_ATTACH, - TEXTURE_BARRIER, - SET_ATOMIC_BUFFERS, - SET_DBG_FLAGS, - GET_QUERY_RESULT_QBO, - TRANSFER3D, - END_TRANSFERS, - COPY_TRANSFER3D, - SET_TWEAKS, - CLEAR_TEXTURE, - PIPE_RESOURCE_CREATE, - PIPE_RESOURCE_SET_TYPE, - GET_MEMORY_INFO, - SEND_STRING_MARKER, - MAX_COMMANDS -}; - -union ClearType { - struct { - u32 depth : 1; - u32 stencil : 1; - u32 color0 : 1; - u32 color1 : 1; - u32 color2 : 1; - u32 color3 : 1; - u32 color4 : 1; - u32 color5 : 1; - u32 color6 : 1; - u32 color7 : 1; - } flags; - u32 value; -}; - -enum class ObjectType : u32 { - NONE, - BLEND, - RASTERIZER, - DSA, - SHADER, - VERTEX_ELEMENTS, - SAMPLER_VIEW, - SAMPLER_STATE, - SURFACE, - QUERY, - STREAMOUT_TARGET, - MSAA_SURFACE, - MAX_OBJECTS, -}; - -enum class PipeTextureTarget : u32 { - BUFFER = 0, - TEXTURE_1D, - TEXTURE_2D, - TEXTURE_3D, - TEXTURE_CUBE, - TEXTURE_RECT, - TEXTURE_1D_ARRAY, - TEXTURE_2D_ARRAY, - TEXTURE_CUBE_ARRAY, - MAX -}; - -enum class PipePrimitiveTypes : u32 { - POINTS = 0, - LINES, - LINE_LOOP, - LINE_STRIP, - TRIANGLES, - TRIANGLE_STRIP, - TRIANGLE_FAN, - QUADS, - QUAD_STRIP, - POLYGON, - LINES_ADJACENCY, - LINE_STRIP_ADJACENCY, - TRIANGLES_ADJACENCY, - TRIANGLE_STRIP_ADJACENCY, - PATCHES, - MAX -}; - -} - -namespace Gallium { - -enum class PipeTextureTarget : u32 { - BUFFER, - TEXTURE_1D, - TEXTURE_2D, - TEXTURE_3D, - TEXTURE_CUBE, - TEXTURE_RECT, - TEXTURE_1D_ARRAY, - TEXTURE_2D_ARRAY, - TEXTURE_CUBE_ARRAY, - MAX_TEXTURE_TYPES, -}; - -enum class ShaderType : u32 { - SHADER_VERTEX = 0, - SHADER_FRAGMENT, - SHADER_GEOMETRY, - SHADER_TESS_CTRL, - SHADER_TESS_EVAL, - SHADER_COMPUTE, - SHADER_TYPES -}; - -} diff --git a/Userland/Demos/VirGLDemo/Widget.cpp b/Userland/Demos/VirGLDemo/Widget.cpp deleted file mode 100644 index 5498cd35bac..00000000000 --- a/Userland/Demos/VirGLDemo/Widget.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2022, Sahan Fernando - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include - -#include "Widget.h" - -ErrorOr> Demo::create() -{ - auto demo = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) Demo)); - - demo->m_bitmap = TRY(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRx8888, { DRAWTARGET_WIDTH, DRAWTARGET_HEIGHT })); - demo->m_bitmap->fill(Gfx::Color::Black); - - return demo; -} - -Demo::Demo() -{ - m_cycles = 0; - - stop_timer(); - start_timer(16); -} - -Demo::~Demo() { } - -void Demo::paint_event(GUI::PaintEvent& event) -{ - GUI::Painter painter(*this); - painter.add_clip_rect(event.rect()); - painter.draw_scaled_bitmap(rect(), *m_bitmap, m_bitmap->rect()); -} - -void Demo::timer_event(Core::TimerEvent&) -{ - m_cycles += 1; - update_frame(m_bitmap, m_cycles); - update(); -} diff --git a/Userland/Demos/VirGLDemo/Widget.h b/Userland/Demos/VirGLDemo/Widget.h deleted file mode 100644 index bd16715625e..00000000000 --- a/Userland/Demos/VirGLDemo/Widget.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2022, Sahan Fernando - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include - -void update_frame(RefPtr, unsigned num_cycles); - -constexpr size_t DRAWTARGET_WIDTH = 500; -constexpr size_t DRAWTARGET_HEIGHT = 500; - -class Demo final : public GUI::Widget { - C_OBJECT(Demo) -public: - static ErrorOr> create(); - virtual ~Demo() override; - bool show_window_frame() const { return m_show_window_frame; } - - Function on_context_menu_request; - -protected: - virtual void context_menu_event(GUI::ContextMenuEvent& event) override - { - if (on_context_menu_request) - on_context_menu_request(event); - } - -private: - Demo(); - - RefPtr m_bitmap; - - virtual void paint_event(GUI::PaintEvent&) override; - virtual void timer_event(Core::TimerEvent&) override; - - int m_cycles; - bool m_show_window_frame { true }; -};