Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[gui] Metal GGUI support & run metal ggui tests #8343

Merged
merged 28 commits into from
Sep 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
18f9b28
Fix circular dependency in GGUI CMake linking
bobcao3 Jun 21, 2023
119b9d9
[gui] Metal ggui wip (#8338)
AntonioFerreras Aug 30, 2023
7045957
Fix merge with cmake dependency loop
bobcao3 Aug 30, 2023
865cf50
Fix clearing / copyed handle destruction issue
bobcao3 Aug 31, 2023
280c7d1
Flip viewport Y
bobcao3 Aug 31, 2023
544c1cc
Fix depth clear / compare / test issues
bobcao3 Aug 31, 2023
135b5e1
Fix renderpass depth format assertion false
bobcao3 Aug 31, 2023
a85e992
Fix ImGui
AntonioFerreras Aug 31, 2023
de19c53
Fix not compile
AntonioFerreras Aug 31, 2023
697230e
Fix uninitialized id<> in Pipeline
bobcao3 Aug 31, 2023
24ba3ae
Merge branch 'metall-ggui-wip' of https://github.com/taichi-dev/taich…
bobcao3 Aug 31, 2023
f8f2688
Fix image read memory leaks
bobcao3 Aug 31, 2023
4d41154
Fix metal ggui tests
bobcao3 Aug 31, 2023
3b69d62
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 31, 2023
6ecab36
Guard GLFW_EXPOSE_NATIVE_COCOA
bobcao3 Aug 31, 2023
aad6349
Merge branch 'metall-ggui-wip' of https://github.com/taichi-dev/taich…
bobcao3 Aug 31, 2023
a406e26
guard ggui metal symbols
bobcao3 Aug 31, 2023
242f6ac
More guards
bobcao3 Aug 31, 2023
d3d1834
more guards
bobcao3 Aug 31, 2023
040be9e
guard includes
bobcao3 Aug 31, 2023
c021e82
More guards
bobcao3 Aug 31, 2023
a135a7e
Fix android build error
AntonioFerreras Sep 1, 2023
8f9ace6
Fix more Android build errors
AntonioFerreras Sep 1, 2023
42a724a
Able to build RHI example on non-macs
bobcao3 Sep 1, 2023
f880ce3
Fix set_image vulkan sampler issues when not aligned
bobcao3 Sep 1, 2023
e9dff13
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 1, 2023
544ac51
Raise tolerance
bobcao3 Sep 2, 2023
69b7f47
Merge branch 'metall-ggui-wip' of https://github.com/taichi-dev/taich…
bobcao3 Sep 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions cmake/TaichiCore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,6 @@ if(TI_WITH_PYTHON)
# This requires refactoring on the python/export_*.cpp as well as better
# error message on the Python side.
add_subdirectory(taichi/ui)
target_link_libraries(taichi_ui PUBLIC ${CORE_LIBRARY_NAME})

message("PYTHON_LIBRARIES: " ${PYTHON_LIBRARIES})
set(CORE_WITH_PYBIND_LIBRARY_NAME taichi_python)
Expand Down Expand Up @@ -383,7 +382,6 @@ if(TI_WITH_PYTHON)

if(TI_WITH_GGUI)
target_compile_definitions(${CORE_WITH_PYBIND_LIBRARY_NAME} PRIVATE -DTI_WITH_GGUI)
target_link_libraries(${CORE_WITH_PYBIND_LIBRARY_NAME} PRIVATE taichi_ui_vulkan)
endif()

target_link_libraries(${CORE_WITH_PYBIND_LIBRARY_NAME} PRIVATE taichi_ui)
Expand Down
15 changes: 11 additions & 4 deletions cpp_examples/rhi_examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
macro(make_sample executable_name src_file)
macro(make_sample executable_name src_file flags)
add_executable(${executable_name})
set_property(TARGET ${executable_name} PROPERTY CXX_STANDARD 17)
set_property(TARGET ${executable_name} PROPERTY C_STANDARD 17)
Expand Down Expand Up @@ -32,8 +32,15 @@ target_link_libraries(${executable_name} taichi_core glfw)
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
target_link_libraries(${executable_name} "-framework QuartzCore")
endif()
target_compile_definitions(${executable_name} PRIVATE ${flags})
endmacro()

make_sample(sample_1_window sample_1_window.cpp)
make_sample(sample_2_triangle sample_2_triangle.cpp)
make_sample(sample_3_textured_triangle sample_3_textured_triangle.cpp)
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
set(RHI_EXAMPLE_FLAGS "RHI_EXAMPLE_BACKEND_METAL")
else()
set(RHI_EXAMPLE_FLAGS "RHI_EXAMPLE_BACKEND_VULKAN")
endif()

make_sample(sample_1_window sample_1_window.cpp ${RHI_EXAMPLE_FLAGS})
make_sample(sample_2_triangle sample_2_triangle.cpp ${RHI_EXAMPLE_FLAGS})
make_sample(sample_3_textured_triangle sample_3_textured_triangle.cpp ${RHI_EXAMPLE_FLAGS})
23 changes: 0 additions & 23 deletions cpp_examples/rhi_examples/common_metal.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,6 @@
#import <GLFW/glfw3native.h>
#include "glm/glm.hpp"

#if defined(__APPLE__) && defined(__OBJC__)
#import <Metal/Metal.h>
#import <QuartzCore/QuartzCore.h>
#define DEFINE_METAL_ID_TYPE(x) typedef id<x> x##_id;
#else
#define DEFINE_METAL_ID_TYPE(x) typedef struct x##_t *x##_id;
#endif

DEFINE_METAL_ID_TYPE(MTLDevice);
DEFINE_METAL_ID_TYPE(MTLBuffer);
DEFINE_METAL_ID_TYPE(MTLTexture);
DEFINE_METAL_ID_TYPE(MTLSamplerState);
DEFINE_METAL_ID_TYPE(MTLLibrary);
DEFINE_METAL_ID_TYPE(MTLFunction);
DEFINE_METAL_ID_TYPE(MTLComputePipelineState);
DEFINE_METAL_ID_TYPE(MTLCommandQueue);
DEFINE_METAL_ID_TYPE(MTLCommandBuffer);
DEFINE_METAL_ID_TYPE(MTLBlitCommandEncoder);
DEFINE_METAL_ID_TYPE(MTLComputeCommandEncoder);
DEFINE_METAL_ID_TYPE(CAMetalDrawable);

#undef DEFINE_METAL_ID_TYPE

#include "taichi/rhi/metal/metal_api.h"
#include "taichi/rhi/metal/metal_device.h"

Expand Down
1 change: 0 additions & 1 deletion cpp_examples/rhi_examples/common_metal.mm
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "common_metal.h"

#include <assert.h>
#import <simd/simd.h>
#include <stdio.h>
#include <stdlib.h>

Expand Down
7 changes: 6 additions & 1 deletion cpp_examples/rhi_examples/sample_1_window.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#ifdef RHI_EXAMPLE_BACKEND_VULKAN
#include "common_vulkan.h"
// #include "common_metal.h"
#endif // RHI_EXAMPLE_BACKEND_VULKAN

#ifdef RHI_EXAMPLE_BACKEND_METAL
#include "common_metal.h"
#endif

class SampleApp : public App {
public:
Expand Down
7 changes: 6 additions & 1 deletion cpp_examples/rhi_examples/sample_2_triangle.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
// #include "common_vulkan.h"
#ifdef RHI_EXAMPLE_BACKEND_VULKAN
#include "common_vulkan.h"
#endif // RHI_EXAMPLE_BACKEND_VULKAN

#ifdef RHI_EXAMPLE_BACKEND_METAL
#include "common_metal.h"
#endif

std::vector<uint32_t> frag_spv =
#include "shaders/2_triangle.frag.spv.h"
Expand Down
9 changes: 7 additions & 2 deletions cpp_examples/rhi_examples/sample_3_textured_triangle.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
// #include "common_vulkan.h"
#ifdef RHI_EXAMPLE_BACKEND_VULKAN
#include "common_vulkan.h"
#endif // RHI_EXAMPLE_BACKEND_VULKAN

#ifdef RHI_EXAMPLE_BACKEND_METAL
#include "common_metal.h"
#endif

std::vector<uint32_t> frag_spv =
#include "shaders/3_triangle.frag.spv.h"
Expand Down Expand Up @@ -104,7 +109,7 @@ class SampleApp : public App {
{
constexpr uint32_t tex_size = 256;

// Just a little 8 bit, 256x256 voronoi texture
// Just a little 8 bit, 256x256 worley texture
std::vector<std::pair<double, double>> random_points;
for (int i = 0; i < 100; i++) {
double x = tex_size * static_cast<double>(std::rand()) / RAND_MAX;
Expand Down
4 changes: 2 additions & 2 deletions python/taichi/examples/ggui_examples/mass_spring_game_ggui.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import taichi as ti

arch = ti.vulkan if ti._lib.core.with_vulkan() else ti.cuda
ti.init(arch=arch)
# arch = ti.vulkan if ti._lib.core.with_vulkan() else ti.cuda
ti.init(arch=ti.metal)

spring_Y = ti.field(dtype=ti.f32, shape=()) # Young's modulus
paused = ti.field(dtype=ti.i32, shape=())
Expand Down
3 changes: 1 addition & 2 deletions python/taichi/examples/ggui_examples/mpm3d_ggui.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import taichi as ti

arch = ti.vulkan if ti._lib.core.with_vulkan() else ti.cuda
ti.init(arch=arch)
ti.init(arch=ti.gpu)

# dim, n_grid, steps, dt = 2, 128, 20, 2e-4
# dim, n_grid, steps, dt = 2, 256, 32, 1e-4
Expand Down
5 changes: 4 additions & 1 deletion python/taichi/shaders/SetImage_vk.frag
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ layout(location = 0) in vec2 frag_texcoord;
layout(location = 0) out vec4 out_color;

layout(binding = 1) uniform UBO {
vec2 lower_bound;
vec2 upper_bound;
float x_factor;
float y_factor;
int is_transposed;
} ubo;

void main() {
vec2 coord = frag_texcoord * vec2(ubo.x_factor,ubo.y_factor);
out_color = texture(texSampler, ubo.is_transposed != 0 ? coord.yx : coord);
coord = clamp(coord, ubo.lower_bound, ubo.upper_bound);
out_color = textureLod(texSampler, ubo.is_transposed != 0 ? coord.yx : coord, 0);
}
Binary file modified python/taichi/shaders/SetImage_vk_frag.spv
Binary file not shown.
13 changes: 7 additions & 6 deletions python/taichi/tools/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import taichi as ti

import ctypes


def cook_image_to_bytes(img):
"""
Expand All @@ -16,7 +18,7 @@ def cook_image_to_bytes(img):
if img.dtype in [np.uint16, np.uint32, np.uint64]:
img = (img // (np.iinfo(img.dtype).max // 256)).astype(np.uint8)
elif img.dtype in [np.float32, np.float64]:
img = (np.clip(img, 0, 1) * 255.0 + 0.5).astype(np.uint8)
img = (np.clip(img, 0, 1) * 255.0).astype(np.uint8)
elif img.dtype != np.uint8:
raise ValueError(f"Data type {img.dtype} not supported in ti.tools.imwrite")

Expand Down Expand Up @@ -81,11 +83,10 @@ def imread(filename, channels=0):
np.ndarray : An output image loaded from given filename.
"""
ptr, resx, resy, comp = _ti_core.imread(filename, channels)
img = np.ndarray(shape=(resy, resx, comp), dtype=np.uint8)
img = np.ascontiguousarray(img)
# TODO(archibate): Figure out how np.ndarray constructor works and replace:
_ti_core.C_memcpy(img.ctypes.data, ptr, resx * resy * comp)
# Discussion: https://github.com/taichi-dev/taichi/issues/802
img = np.copy(np.ctypeslib.as_array((ctypes.c_uint8 * resx * resy * comp).from_address(ptr))).reshape(
resy, resx, comp
)
_ti_core.imfree(ptr)
return img.swapaxes(0, 1)[:, ::-1, :]


Expand Down
26 changes: 19 additions & 7 deletions taichi/python/export_ggui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ namespace py = pybind11;

#include "taichi/ui/utils/utils.h"
#include "taichi/ui/common/window_base.h"
#include "taichi/ui/backends/vulkan/window.h"
#include "taichi/ui/ggui/window.h"
#include "taichi/ui/common/canvas_base.h"
#include "taichi/ui/common/camera.h"
#include "taichi/ui/backends/vulkan/canvas.h"
#include "taichi/ui/backends/vulkan/scene.h"
#include "taichi/ui/ggui/canvas.h"
#include "taichi/ui/ggui/scene.h"
#include "taichi/rhi/vulkan/vulkan_loader.h"
#include "taichi/rhi/arch.h"
#include "taichi/program/field_info.h"
Expand Down Expand Up @@ -521,6 +521,19 @@ struct PyWindow {
double fps_limit,
std::string package_path,
Arch ti_arch) {
Arch ggui_arch = Arch::vulkan;

if (ti_arch == Arch::metal) {
ggui_arch = Arch::metal;
}

if (ggui_arch == Arch::vulkan) {
// Verify vulkan available
if (!lang::vulkan::is_vulkan_api_available()) {
throw std::runtime_error("Vulkan must be available for GGUI");
}
}

AppConfig config = {name,
res[0].cast<int>(),
res[1].cast<int>(),
Expand All @@ -530,10 +543,9 @@ struct PyWindow {
show_window,
fps_limit,
package_path,
ti_arch};
if (!lang::vulkan::is_vulkan_api_available()) {
throw std::runtime_error("Vulkan must be available for GGUI");
}
ti_arch,
ggui_arch};

window = std::make_unique<vulkan::Window>(prog, config);
}

Expand Down
5 changes: 1 addition & 4 deletions taichi/python/export_visual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,7 @@ void export_visual(py::module &m) {
py::return_value_policy::reference);
m.def("imwrite", &imwrite);
m.def("imread", &imread);
// TODO(archibate): See misc/image.py
m.def("C_memcpy", [](size_t dst, size_t src, size_t size) {
std::memcpy((void *)dst, (void *)src, size);
});
m.def("imfree", &imfree);
}

} // namespace taichi
4 changes: 4 additions & 0 deletions taichi/rhi/common/window_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

#ifdef TI_WITH_GLFW
#include "GLFW/glfw3.h"
#ifdef TI_WITH_METAL
#define GLFW_EXPOSE_NATIVE_COCOA
#import <GLFW/glfw3native.h>
#endif
#endif // TI_WITH_GLFW

namespace taichi::lang::window_system {
Expand Down
11 changes: 11 additions & 0 deletions taichi/rhi/impl_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,5 +179,16 @@ inline void hash_combine(std::size_t &seed, const T &v) {
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}

// A helper to remove copy constructor
class NonAssignable {
private:
NonAssignable(NonAssignable const &);
NonAssignable &operator=(NonAssignable const &);

public:
NonAssignable() {
}
};

} // namespace rhi_impl
} // namespace taichi::lang
Loading
Loading