Procházet zdrojové kódy

LibSoftGPU: Add methods to read and write image data

This adds two methods, write_texels and read_texels, to the Image class.
Conversion between image formats happens automatically. The layout of
the client image data is passed in via ImageDataLayout struct.
Stephan Unverwerth před 3 roky
rodič
revize
b41ad28654

+ 38 - 0
Userland/Libraries/LibSoftGPU/Image.cpp

@@ -41,4 +41,42 @@ Image::Image(ImageFormat format, unsigned width, unsigned height, unsigned depth
     m_data.resize(m_mipchain_size * m_num_layers);
 }
 
+void Image::write_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void const* data, ImageDataLayout const& layout)
+{
+    VERIFY(layer < num_layers());
+    VERIFY(level < num_levels());
+    VERIFY(offset.x() + size.x() <= level_width(level));
+    VERIFY(offset.y() + size.y() <= level_height(level));
+    VERIFY(offset.z() + size.z() <= level_depth(level));
+
+    for (unsigned z = 0; z < size.z(); ++z) {
+        for (unsigned y = 0; y < size.y(); ++y) {
+            for (unsigned x = 0; x < size.x(); ++x) {
+                auto ptr = reinterpret_cast<u8 const*>(data) + layout.depth_stride * z + layout.row_stride * y + layout.column_stride * x;
+                auto color = unpack_color(ptr, layout.format);
+                set_texel(layer, level, offset.x() + x, offset.y() + y, offset.z() + z, color);
+            }
+        }
+    }
+}
+
+void Image::read_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void* data, ImageDataLayout const& layout) const
+{
+    VERIFY(layer < num_layers());
+    VERIFY(level < num_levels());
+    VERIFY(offset.x() + size.x() <= level_width(level));
+    VERIFY(offset.y() + size.y() <= level_height(level));
+    VERIFY(offset.z() + size.z() <= level_depth(level));
+
+    for (unsigned z = 0; z < size.z(); ++z) {
+        for (unsigned y = 0; y < size.y(); ++y) {
+            for (unsigned x = 0; x < size.x(); ++x) {
+                auto color = texel(layer, level, offset.x() + x, offset.y() + y, offset.z() + z);
+                auto ptr = reinterpret_cast<u8*>(data) + layout.depth_stride * z + layout.row_stride * y + layout.column_stride * x;
+                pack_color(color, ptr, layout.format);
+            }
+        }
+    }
+}
+
 }

+ 4 - 0
Userland/Libraries/LibSoftGPU/Image.h

@@ -10,6 +10,7 @@
 #include <AK/Vector.h>
 #include <LibGfx/Vector3.h>
 #include <LibGfx/Vector4.h>
+#include <LibSoftGPU/ImageDataLayout.h>
 #include <LibSoftGPU/ImageFormat.h>
 
 namespace SoftGPU {
@@ -38,6 +39,9 @@ public:
         pack_color(color, texel_pointer(layer, level, x, y, z), m_format);
     }
 
+    void write_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void const* data, ImageDataLayout const& layout);
+    void read_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void* data, ImageDataLayout const& layout) const;
+
 private:
     void const* texel_pointer(unsigned layer, unsigned level, unsigned x, unsigned y, unsigned z) const
     {

+ 20 - 0
Userland/Libraries/LibSoftGPU/ImageDataLayout.h

@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2021, Stephan Unverwerth <s.unverwerth@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibSoftGPU/ImageFormat.h>
+
+namespace SoftGPU {
+
+struct ImageDataLayout final {
+    ImageFormat format;
+    size_t column_stride;
+    size_t row_stride;
+    size_t depth_stride;
+};
+
+}