Skip to content

Commit

Permalink
Add standalone test and 'getting started section' to docs
Browse files Browse the repository at this point in the history
  • Loading branch information
kosude committed Dec 16, 2023
1 parent 8c903a3 commit a77aab0
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 30 deletions.
4 changes: 4 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,7 @@

breathe_show_define_initializer = True
breathe_show_enumvalue_initializer = True

breathe_domain_by_extension = {
"h": "c"
}
30 changes: 27 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ Home
:hidden:

self
pages/contributing

pages/getting_started

pages/api/_api


Expand All @@ -17,8 +19,7 @@ far future.
.. note::
The contents of this page can also be seen in the project's `README <https://github.com/kosude/thallium/blob/master/README.md/>`_.

For information about contributing, see the :doc:`Contributing page <pages/contributing>`. For comprehensive function and struct documentation, see
the :doc:`API reference <pages/api/_api>`.
For comprehensive function and struct documentation, see the :doc:`API reference <pages/api/_api>`.


Building
Expand All @@ -44,10 +45,33 @@ Option name Description Default
``THALLIUM_BUILD_DOCS`` Build HTML documentation OFF
=========================== ================================ =======

It's recommended to use the ``-DCMAKE_BUILD_TYPE=Debug`` flag when building Thallium for library development.


API modules
^^^^^^^^^^^

Thallium source compilation is split into **modules**, based on the graphics APIs you need support for. Each module can be manually enabled or
disabled with CMake flags, just like above. These flags are named ``THALLIUM_BUILD_MODULE_<API>``. For example, the Vulkan module can be compiled
using the ``-DTHALLIUM_BUILD_MODULE_VULKAN=ON`` build flag (this requires the Vulkan SDK to be installed).


WSI flags
^^^^^^^^^

Window system integration (WSI) is available depending on the target platform:

- On Apple systems, ``THALLIUM_WSI_COCOA`` is available and enabled by default.
- On other \*nix systems, ``THALLIUM_WSI_XCB`` and ``THALLIUM_WSI_XLIB`` are both available and enabled by default. *Wayland is not yet supported.*


Information for contributing
----------------------------


Document **all** new public functions or types with `Doxygen <https://www.doxygen.nl/>`_-style formatting. Also see the
`Breathe documentation <https://breathe.readthedocs.io/en/latest/index.html>`_ to find out how to include your code's documentation in the HTML
output.

I keep an upstream TO-DO list on `Trello <https://trello.com/b/ZHYGTiZr/thallium-development-tracking>`_. Submit issues and pull requests to the
`GitHub repo <https://github.com/kosude/thallium>`_.
24 changes: 0 additions & 24 deletions docs/pages/contributing.rst

This file was deleted.

46 changes: 46 additions & 0 deletions docs/pages/getting_started.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Getting started
===============


Understanding Thallium contexts and renderers
---------------------------------------------

Each Thallium application must have **one** context object. This object stores state data for APIs that need it, such as the Vulkan instance, and is
created using the :c:func:`TL_ContextCreate()` function.

The context data is initialised as necessary when any renderers are created - in other words, if there are no Vulkan renderers created, then no
Vulkan instance will be created, for example. One or more renderers can be created in batch with the :c:func:`TL_RendererCreate()` function - this can
only be done **once** per context!


Debugging functions
-------------------

While the context is usually the first object to be created in production builds, you might opt for creating a debugger first instead. This is
necessary to recieve any debug output, and can be done with the :c:func:`TL_DebuggerCreate()` function. You'll need to specify the severities and
sources of messages you want to stream to the debugger - this configuration is available in the descriptor, as well as an optional callback function.

Some functions might explicitly take an optional debugger argument to send output to. However, it's recommended to use a **debugger attachment** to
get much better output from the context. This is a virtual structure that is defined with the :c:struct:`TL_DebuggerAttachmentDescriptor_t`
descriptor, and is specified at context creation. With a debugger attachment, you can recieve output directly from the graphics API(s) your
application uses!


Object systems
--------------

API-specific versions of objects are abstracted in the form of **object systems**. For example, a renderer created with the
:c:enum:`TL_RendererAPIFlags_t` flag of ``TL_RENDERER_API_VULKAN_BIT`` will itself contain a Vulkan renderer system; swapchains will contain an
API-specific swapchain system, etc.

Object systems are, by default, not provided in the public API. However, you can still access them by including the appropriate graphics API header,
such as ``thallium_vulkan.h`` for Vulkan applications. These headers provide, among other things, their respective object systems.


Interacting with windows
------------------------

Windows are passed to Thallium through the :c:struct:`TL_WindowSurface_t` abstraction. This allows for compatibility with various window systems; for
example, on Apple systems, this struct can be created with the :c:func:`TL_WindowSurfaceCreateCocoa()` function. X11 and XCB equivalents exist for
Linux systems - the functions that are compiled depend on which CMake flags are enabled at config-time (e.g. ``THALLIUM_WSI_COCOA`` is ON by default
when building on macOS).
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ endfunction()
# tests defined below

thallium_add_test("hellotriangle" "bin/HelloTriangle.cpp")
thallium_add_test("standalone" "bin/Standalone.cpp")
10 changes: 7 additions & 3 deletions tests/bin/HelloTriangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ int main() {

swapchain1 = window1.CreateSwapchain(test.GetRenderers()[0]);

for (; !window1.ShouldClose();) {
Window::PollEvents();
}
Utils::Log("-- MAIN LOOP BEGIN --");

// for (; !window1.ShouldClose();) {
// Window::PollEvents();
// }

Utils::Log("-- MAIN LOOP END --");

TL_SwapchainDestroy(swapchain1);

Expand Down
149 changes: 149 additions & 0 deletions tests/bin/Standalone.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
* Copyright (c) 2023 Jack Bennett.
* All Rights Reserved.
*
* See the LICENCE file for more information.
*/

#include "thallium.h"

#if defined(__linux__)
# include <xcb/xcb.h>
# include <X11/Xlib-xcb.h>

# define GLFW_EXPOSE_NATIVE_X11
#elif defined(__APPLE__)
# if defined(__OBJC__)
# import <Cocoa/Cocoa.h>
# else
# include <ApplicationServices/ApplicationServices.h>
# include <objc/objc.h>
# endif

# define GLFW_EXPOSE_NATIVE_COCOA
#elif defined(_WIN32)
# error Useless operating systems are not yet supported by Thallium's WSI abstraction set
#endif

#include "glfw/include/GLFW/glfw3.h"
#include "glfw/include/GLFW/glfw3native.h"

#include <iostream>

#if defined(_THALLIUM_VULKAN_INCL)
# include "thallium_vulkan.h"
#endif

TL_Debugger_t *debugger;
TL_Context_t *context;
TL_Renderer_t *renderer;
TL_Swapchain_t *swapchain;

GLFWwindow *window;
TL_WindowSurface_t *window_surface;

int main() {
// Create the debugger

TL_DebuggerDescriptor_t debuggerdesc = {};
(int &) debuggerdesc.severities = TL_DEBUG_SEVERITY_WARNING_BIT | TL_DEBUG_SEVERITY_ERROR_BIT | TL_DEBUG_SEVERITY_FATAL_BIT;
(int &) debuggerdesc.sources = TL_DEBUG_SOURCE_ALL_BIT;

debugger = TL_DebuggerCreate(debuggerdesc);

if (!debugger) {
std::cerr << "Failed to create debugger" << std::endl;
return 1;
}

// debugger attachment will be used to attach debugger to context
TL_DebuggerAttachmentDescriptor_t debugger_attachment = {};
debugger_attachment.debugger = debugger;


// Create the context

TL_ContextDescriptor_t contextdesc = {};
contextdesc.debug_attachment_descriptor = &debugger_attachment;

context = TL_ContextCreate(contextdesc, debugger);

if (!context) {
std::cerr << "Failed to create context" << std::endl;
return 1;
}


// Create the renderer

TL_RendererFeatures_t rendererfeats = {};
rendererfeats.presentation = true;

TL_RendererDescriptor_t rendererdesc = {};
rendererdesc.api = TL_RENDERER_API_VULKAN_BIT;
rendererdesc.api_version = { 1, 3, 0 };
rendererdesc.requirements = rendererfeats;

uint32_t renderersucc = TL_RendererCreate(
context, 1,
(TL_RendererDescriptor_t[]) { rendererdesc },
(TL_Renderer_t **[]) { &renderer },
debugger);

if (renderersucc < 1) {
std::cerr << "Failed to create renderer" << std::endl;
return 1;
}


// Create the window

if (!glfwInit()) {
std::cerr << "Failed to init GLFW" << std::endl;
return 1;
}

window = glfwCreateWindow(640, 480, "Standalone test", nullptr, nullptr);

if (!window) {
std::cerr << "Failed to create window" << std::endl;
return 1;
}

// window surface for interfacing with Thallium swapchains
window_surface = TL_WindowSurfaceCreateXlib(glfwGetX11Display(), glfwGetX11Window(window), debugger);

if (!window_surface) {
std::cerr << "Failed to create window" << std::endl;
return 1;
}

// Initially create the swapchain

TL_SwapchainDescriptor_t swapchaindesc = {};
swapchaindesc.resolution = { 640, 480 };
swapchaindesc.window_surface = window_surface;

swapchain = TL_SwapchainCreate(renderer, swapchaindesc);

if (!swapchain) {
std::cerr << "Failed to create swapchain" << std::endl;
return 1;
}


// Main loop

for (; !glfwWindowShouldClose(window);) {
glfwPollEvents();
}


// Cleanup

TL_DebuggerDestroy(debugger);
TL_RendererDestroy(renderer);
TL_ContextDestroy(context);

glfwTerminate();
}

0 comments on commit a77aab0

Please sign in to comment.