From c14d4732b00c75a6fdccdb187be7893417d8921b Mon Sep 17 00:00:00 2001 From: Laura Hermanns Date: Tue, 1 Aug 2023 21:24:07 -0400 Subject: [PATCH] Started with C99 wrapper. --- CMakeLists.txt | 40 +- examples/C99/HelloTriangle/HelloTriangle.c | 190 +++ examples/C99/HelloTriangle/HelloTriangle.frag | 11 + examples/C99/HelloTriangle/HelloTriangle.png | Bin 0 -> 134150 bytes examples/C99/HelloTriangle/HelloTriangle.vert | 13 + examples/C99/README.md | 14 + include/LLGL-C/Buffer.h | 25 + include/LLGL-C/BufferFlags.h | 46 + include/LLGL-C/Canvas.h | 43 + include/LLGL-C/CanvasFlags.h | 27 + include/LLGL-C/CommandBuffer.h | 83 ++ include/LLGL-C/CommandBufferFlags.h | 92 ++ include/LLGL-C/CommandQueue.h | 30 + include/LLGL-C/Display.h | 41 + include/LLGL-C/DisplayFlags.h | 30 + include/LLGL-C/Export.h | 26 + include/LLGL-C/Format.h | 225 ++++ include/LLGL-C/FragmentAttribute.h | 33 + include/LLGL-C/ImageFlags.h | 42 + include/LLGL-C/IndirectArguments.h | 56 + include/LLGL-C/Key.h | 196 +++ include/LLGL-C/LLGL.h | 38 + include/LLGL-C/Log.h | 47 + include/LLGL-C/PipelineLayout.h | 27 + include/LLGL-C/PipelineLayoutFlags.h | 131 ++ include/LLGL-C/PipelineState.h | 24 + include/LLGL-C/PipelineStateFlags.h | 329 +++++ include/LLGL-C/QueryHeap.h | 24 + include/LLGL-C/QueryHeapFlags.h | 60 + include/LLGL-C/RenderPassFlags.h | 58 + include/LLGL-C/RenderSystem.h | 102 ++ include/LLGL-C/RenderSystemFlags.h | 224 ++++ include/LLGL-C/RenderTarget.h | 29 + include/LLGL-C/RenderTargetFlags.h | 46 + include/LLGL-C/Report.h | 25 + include/LLGL-C/Resource.h | 24 + include/LLGL-C/ResourceFlags.h | 63 + include/LLGL-C/ResourceHeapFlags.h | 51 + include/LLGL-C/SamplerFlags.h | 63 + include/LLGL-C/Shader.h | 27 + include/LLGL-C/ShaderFlags.h | 122 ++ include/LLGL-C/ShaderReflection.h | 64 + include/LLGL-C/Surface.h | 31 + include/LLGL-C/SwapChain.h | 35 + include/LLGL-C/SwapChainFlags.h | 45 + include/LLGL-C/SystemValue.h | 41 + include/LLGL-C/Texture.h | 29 + include/LLGL-C/TextureFlags.h | 122 ++ include/LLGL-C/Timer.h | 24 + include/LLGL-C/Types.h | 92 ++ include/LLGL-C/VertexAttribute.h | 39 + include/LLGL-C/Window.h | 88 ++ include/LLGL-C/WindowFlags.h | 43 + include/README.md | 17 + wrapper/C99/C99Buffer.cpp | 35 + wrapper/C99/C99Canvas.cpp | 129 ++ wrapper/C99/C99CommandBuffer.cpp | 310 +++++ wrapper/C99/C99CommandQueue.cpp | 52 + wrapper/C99/C99Display.cpp | 121 ++ wrapper/C99/C99FlagsAndDescriptors.cpp | 27 + wrapper/C99/C99Internal.h | 26 + wrapper/C99/C99Log.cpp | 65 + wrapper/C99/C99PipelineLayout.cpp | 43 + wrapper/C99/C99PipelineState.cpp | 28 + wrapper/C99/C99QueryHeap.cpp | 28 + wrapper/C99/C99RenderSystem.cpp | 606 +++++++++ wrapper/C99/C99RenderTarget.cpp | 55 + wrapper/C99/C99Report.cpp | 39 + wrapper/C99/C99Resource.cpp | 28 + wrapper/C99/C99Shader.cpp | 94 ++ wrapper/C99/C99Surface.cpp | 55 + wrapper/C99/C99SwapChain.cpp | 68 + wrapper/C99/C99Texture.cpp | 59 + wrapper/C99/C99Timer.cpp | 33 + wrapper/C99/C99TypeAssertions.cpp | 1112 +++++++++++++++++ wrapper/C99/C99Window.cpp | 319 +++++ 76 files changed, 6774 insertions(+), 5 deletions(-) create mode 100644 examples/C99/HelloTriangle/HelloTriangle.c create mode 100644 examples/C99/HelloTriangle/HelloTriangle.frag create mode 100644 examples/C99/HelloTriangle/HelloTriangle.png create mode 100644 examples/C99/HelloTriangle/HelloTriangle.vert create mode 100644 examples/C99/README.md create mode 100644 include/LLGL-C/Buffer.h create mode 100644 include/LLGL-C/BufferFlags.h create mode 100644 include/LLGL-C/Canvas.h create mode 100644 include/LLGL-C/CanvasFlags.h create mode 100644 include/LLGL-C/CommandBuffer.h create mode 100644 include/LLGL-C/CommandBufferFlags.h create mode 100644 include/LLGL-C/CommandQueue.h create mode 100644 include/LLGL-C/Display.h create mode 100644 include/LLGL-C/DisplayFlags.h create mode 100644 include/LLGL-C/Export.h create mode 100644 include/LLGL-C/Format.h create mode 100644 include/LLGL-C/FragmentAttribute.h create mode 100644 include/LLGL-C/ImageFlags.h create mode 100644 include/LLGL-C/IndirectArguments.h create mode 100644 include/LLGL-C/Key.h create mode 100644 include/LLGL-C/LLGL.h create mode 100644 include/LLGL-C/Log.h create mode 100644 include/LLGL-C/PipelineLayout.h create mode 100644 include/LLGL-C/PipelineLayoutFlags.h create mode 100644 include/LLGL-C/PipelineState.h create mode 100644 include/LLGL-C/PipelineStateFlags.h create mode 100644 include/LLGL-C/QueryHeap.h create mode 100644 include/LLGL-C/QueryHeapFlags.h create mode 100644 include/LLGL-C/RenderPassFlags.h create mode 100644 include/LLGL-C/RenderSystem.h create mode 100644 include/LLGL-C/RenderSystemFlags.h create mode 100644 include/LLGL-C/RenderTarget.h create mode 100644 include/LLGL-C/RenderTargetFlags.h create mode 100644 include/LLGL-C/Report.h create mode 100644 include/LLGL-C/Resource.h create mode 100644 include/LLGL-C/ResourceFlags.h create mode 100644 include/LLGL-C/ResourceHeapFlags.h create mode 100644 include/LLGL-C/SamplerFlags.h create mode 100644 include/LLGL-C/Shader.h create mode 100644 include/LLGL-C/ShaderFlags.h create mode 100644 include/LLGL-C/ShaderReflection.h create mode 100644 include/LLGL-C/Surface.h create mode 100644 include/LLGL-C/SwapChain.h create mode 100644 include/LLGL-C/SwapChainFlags.h create mode 100644 include/LLGL-C/SystemValue.h create mode 100644 include/LLGL-C/Texture.h create mode 100644 include/LLGL-C/TextureFlags.h create mode 100644 include/LLGL-C/Timer.h create mode 100644 include/LLGL-C/Types.h create mode 100644 include/LLGL-C/VertexAttribute.h create mode 100644 include/LLGL-C/Window.h create mode 100644 include/LLGL-C/WindowFlags.h create mode 100644 include/README.md create mode 100644 wrapper/C99/C99Buffer.cpp create mode 100644 wrapper/C99/C99Canvas.cpp create mode 100644 wrapper/C99/C99CommandBuffer.cpp create mode 100644 wrapper/C99/C99CommandQueue.cpp create mode 100644 wrapper/C99/C99Display.cpp create mode 100644 wrapper/C99/C99FlagsAndDescriptors.cpp create mode 100644 wrapper/C99/C99Internal.h create mode 100644 wrapper/C99/C99Log.cpp create mode 100644 wrapper/C99/C99PipelineLayout.cpp create mode 100644 wrapper/C99/C99PipelineState.cpp create mode 100644 wrapper/C99/C99QueryHeap.cpp create mode 100644 wrapper/C99/C99RenderSystem.cpp create mode 100644 wrapper/C99/C99RenderTarget.cpp create mode 100644 wrapper/C99/C99Report.cpp create mode 100644 wrapper/C99/C99Resource.cpp create mode 100644 wrapper/C99/C99Shader.cpp create mode 100644 wrapper/C99/C99Surface.cpp create mode 100644 wrapper/C99/C99SwapChain.cpp create mode 100644 wrapper/C99/C99Texture.cpp create mode 100644 wrapper/C99/C99Timer.cpp create mode 100644 wrapper/C99/C99TypeAssertions.cpp create mode 100644 wrapper/C99/C99Window.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cc9a9ded88..575ef21dec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ set(EXECUTABLE_OUTPUT_PATH ${OUTPUT_DIR} CACHE PATH "Build directory" FORCE) set(LIBRARY_OUTPUT_PATH ${OUTPUT_DIR} CACHE PATH "Build directory" FORCE) set(PROJECT_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include") set(EXAMPLE_PROJECTS_DIR "${PROJECT_SOURCE_DIR}/examples/Cpp") +set(EXAMPLE_C99_PROJECTS_DIR "${PROJECT_SOURCE_DIR}/examples/C99") # === Preprocessor definitions === @@ -98,6 +99,16 @@ macro(ADD_EXAMPLE_PROJECT TEST_NAME TEST_FILES LIB_FILES) set_target_properties(${TEST_NAME} PROPERTIES LINKER_LANGUAGE CXX DEBUG_POSTFIX "D") endmacro() +macro(ADD_C99_EXAMPLE_PROJECT TEST_NAME TEST_FILES LIB_FILES) + if(APPLE) + add_executable(${TEST_NAME} MACOSX_BUNDLE ${TEST_FILES}) + else() + add_executable(${TEST_NAME} ${TEST_FILES}) + endif() + target_link_libraries(${TEST_NAME} ${LIB_FILES}) + set_target_properties(${TEST_NAME} PROPERTIES LINKER_LANGUAGE C DEBUG_POSTFIX "D") +endmacro() + macro(ADD_MOBILE_EXAMPLE_PROJECT TEST_NAME TEST_FILES LIB_FILES) if(LLGL_IOS_PLATFORM) add_executable(${TEST_NAME} MACOSX_BUNDLE ${TEST_FILES}) @@ -195,6 +206,8 @@ if(WIN32) option(LLGL_BUILD_WRAPPER_CSHARP "Include wrapper for C#" OFF) endif() +option(LLGL_BUILD_WRAPPER_C99 "Include wrapper for C99" OFF) + if(LLGL_ENABLE_CHECKED_CAST) ADD_DEBUG_DEFINE(LLGL_ENABLE_CHECKED_CAST) endif() @@ -731,6 +744,15 @@ set( ${FilesRendererDXCommon} ) +# Wrapper: C99 +if(LLGL_BUILD_WRAPPER_C99) + file(GLOB FilesWrapperC99 ${PROJECT_SOURCE_DIR}/wrapper/C99/*.*) + file(GLOB FilesIncludeC99 ${PROJECT_INCLUDE_DIR}/LLGL-C/*.*) + source_group("Wrapper\\C99\\Include" FILES ${FilesIncludeC99}) + source_group("Wrapper\\C99\\Sources" FILES ${FilesWrapperC99}) + set(FilesLLGL ${FilesLLGL} ${FilesIncludeC99} ${FilesWrapperC99}) +endif() + # Base project if(LLGL_BUILD_STATIC_LIB) set(SUMMARY_LIBRARY_TYPE "Static") @@ -978,14 +1000,14 @@ if(GaussLib_INCLUDE_DIR) add_library(android_native_app_glue STATIC ${FilesAndroidNativeAppGlue}) target_link_libraries(ExampleBase android_native_app_glue) include_directories(${ANDROID_APP_GLUE_DIR}) - endif() + endif(LLGL_ANDROID_PLATFORM) set(EXAMPLE_PROJECT_LIBS ${LLGL_DEPENDENCIES} ExampleBase) if(LLGL_ANDROID_PLATFORM) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate") ADD_MOBILE_EXAMPLE_PROJECT(Example_HelloAndroid "${FilesExample_HelloAndroid}" "${EXAMPLE_PROJECT_LIBS}") - else() + else(LLGL_ANDROID_PLATFORM) ADD_EXAMPLE_PROJECT(Example_HelloTriangle "${FilesExample_HelloTriangle}" "${EXAMPLE_PROJECT_LIBS}") ADD_EXAMPLE_PROJECT(Example_Tessellation "${FilesExample_Tessellation}" "${EXAMPLE_PROJECT_LIBS}") ADD_EXAMPLE_PROJECT(Example_Texturing "${FilesExample_Texturing}" "${EXAMPLE_PROJECT_LIBS}") @@ -1009,8 +1031,12 @@ if(GaussLib_INCLUDE_DIR) ADD_EXAMPLE_PROJECT(Example_VolumeRendering "${FilesExample_VolumeRendering}" "${EXAMPLE_PROJECT_LIBS}") ADD_EXAMPLE_PROJECT(Example_PrimitiveRestart "${FilesExample_PrimitiveRestart}" "${EXAMPLE_PROJECT_LIBS}") ADD_EXAMPLE_PROJECT(Example_ResourceBinding "${FilesExample_ResourceBinding}" "${EXAMPLE_PROJECT_LIBS}") - endif() - endif() + + if (LLGL_BUILD_WRAPPER_C99) + ADD_C99_EXAMPLE_PROJECT(Example_C99_HelloTriangle "${EXAMPLE_C99_PROJECTS_DIR}/HelloTriangle/HelloTriangle.c" "${LLGL_DEPENDENCIES}") + endif(LLGL_BUILD_WRAPPER_C99) + endif(LLGL_ANDROID_PLATFORM) + endif(LLGL_BUILD_EXAMPLES) else() # if(LLGL_BUILD_TESTS) # message(SEND_ERROR "LLGL_BUILD_TESTS is enabled but 'GaussLib_INCLUDE_DIR' path is missing") @@ -1022,7 +1048,7 @@ endif() # Wrapper: C# if(WIN32 AND LLGL_BUILD_WRAPPER_CSHARP) - add_subdirectory(Wrapper/CSharp) + add_subdirectory(wrapper/CSharp) endif() # Install targets, headers, and CMake config files @@ -1080,6 +1106,10 @@ if(LLGL_BUILD_RENDERER_DIRECT3D12) message("Build Renderer: Direct3D 12.0") endif() +if(LLGL_BUILD_WRAPPER_C99) + message("Build Wrapper: C99") +endif() + if(WIN32 AND LLGL_BUILD_WRAPPER_CSHARP) message("Build Wrapper: C#") endif() diff --git a/examples/C99/HelloTriangle/HelloTriangle.c b/examples/C99/HelloTriangle/HelloTriangle.c new file mode 100644 index 0000000000..f18ca229cf --- /dev/null +++ b/examples/C99/HelloTriangle/HelloTriangle.c @@ -0,0 +1,190 @@ +/* + * HelloTriangle.c + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include + + +#define ENABLE_MULTISAMPLING 1 + +int main(int argc, char* argv[]) +{ + // Load render system module + const char* rendererModule = "OpenGL"; + if (llglLoadRenderSystem(rendererModule) == 0) + { + fprintf(stderr, "Failed to load render system: %s\n", rendererModule); + return 1; + } + + // Create swap-chain + LLGLSwapChainDescriptor swapChainDesc = + { + .resolution = { 800, 600 }, + .colorBits = 32, + .depthBits = 0, // We don't need a depth buffer for this example + .stencilBits = 0, // We don't need a stencil buffer for this example + #if ENABLE_MULTISAMPLING + .samples = 8, // check if LLGL adapts sample count that is too high + #endif + }; + LLGLSwapChain swapChain = llglCreateSwapChain(&swapChainDesc); + + // Enable V-sync + llglSetVsyncInterval(swapChain, 1); + + // Set window title and show window + LLGLSurface surface = llglGetSurface(swapChain); + LLGLWindow window = LLGL_GET_AS(LLGLWindow, surface); + + llglSetWindowTitle(window, L"LLGL C99 Example: Hello Triangle"); + llglShowWindow(window, true); + + // Vertex data structure + typedef struct Vertex + { + float position[2]; + uint8_t color[4]; + } + Vertex; + + // Vertex data (3 vertices for our triangle) + const float s = 0.5f; + + Vertex vertices[] = + { + { { 0, s }, { 255, 0, 0, 255 } }, // 1st vertex: center-top, red + { { s, -s }, { 0, 255, 0, 255 } }, // 2nd vertex: right-bottom, green + { { -s, -s }, { 0, 0, 255, 255 } }, // 3rd vertex: left-bottom, blue + }; + + // Vertex format with 2D floating-point vector for position and 4D byte vector for color + LLGLVertexAttribute vertexAttributes[2] = + { + { .name = "position", .format = LLGLFormatRG32Float, .location = 0, .offset = 0, .stride = sizeof(Vertex) }, + { .name = "color", .format = LLGLFormatRGBA8UNorm, .location = 1, .offset = offsetof(Vertex, color), .stride = sizeof(Vertex) }, + }; + + // Create vertex buffer + LLGLBufferDescriptor vertexBufferDesc = + { + .size = sizeof(vertices), // Size (in bytes) of the vertex buffer + .bindFlags = LLGLBindVertexBuffer, // Enables the buffer to be bound to a vertex buffer slot + .numVertexAttribs = 2, + .vertexAttribs = vertexAttributes, // Vertex format layout + }; + LLGLBuffer vertexBuffer = llglCreateBuffer(&vertexBufferDesc, vertices); + + // Create shaders + LLGLShaderDescriptor vertShaderDesc = { .type = LLGLShaderTypeVertex, .source = "HelloTriangle.vert", .sourceType = LLGLShaderSourceTypeCodeFile, }; + LLGLShaderDescriptor fragShaderDesc = { .type = LLGLShaderTypeFragment, .source = "HelloTriangle.frag", .sourceType = LLGLShaderSourceTypeCodeFile, }; + + // Specify vertex attributes for vertex shader + vertShaderDesc.vertex.numInputAttribs = 2; + vertShaderDesc.vertex.inputAttribs = vertexAttributes; + + LLGLShader shaders[2] = + { + llglCreateShader(&vertShaderDesc), + llglCreateShader(&fragShaderDesc), + }; + + for (int i = 0; i < 2; ++i) + { + LLGLReport shaderReport = llglGetShaderReport(shaders[i]); + if (llglHasReportErrors(shaderReport)) + { + fprintf(stderr, "%s\n", llglGetReportText(shaderReport)); + return 1; + } + } + + // Create graphics pipeline + LLGLGraphicsPipelineDescriptor pipelineDesc = + { + .vertexShader = shaders[0], + .fragmentShader = shaders[1], + .renderPass = llglGetRenderTargetRenderPass(LLGL_GET_AS(LLGLRenderTarget, swapChain)), + .primitiveTopology = LLGLPrimitiveTopologyTriangleList, + #if ENABLE_MULTISAMPLING + .rasterizer = { .multiSampleEnabled = (swapChainDesc.samples > 1) }, + #endif + .blend.targets[0].colorMask = LLGLColorMaskAll, + }; + + // Create graphics PSO + LLGLPipelineState pipeline = llglCreateGraphicsPipelineState(&pipelineDesc); + + // Link shader program and check for errors + LLGLReport pipelineReport = llglGetPipelineStateReport(pipeline); + if (llglHasReportErrors(pipelineReport)) + { + fprintf(stderr, "%s\n", llglGetReportText(pipelineReport)); + return 1; + } + + // Create command buffer to submit subsequent graphics commands to the GPU + LLGLCommandBufferDescriptor cmdBufferDesc = + { + .flags = LLGLCommandBufferImmediateSubmit, + .numNativeBuffers = 2, + }; + LLGLCommandBuffer cmdBuffer = llglCreateCommandBuffer(&cmdBufferDesc); + + // Initialize frame constants + const LLGLViewport viewport = + { + .x = 0.0f, + .y = 0.0f, + .width = (float)swapChainDesc.resolution.width, + .height = (float)swapChainDesc.resolution.height, + .minDepth = 0.0f, + .maxDepth = 1.0f + }; + + const LLGLClearValue clearColor = + { + .color = { 0.1f, 0.1f, 0.2f, 1.0f }, + }; + + // Enter main loop + while (llglProcessSurfaceEvents(surface)) + { + // Begin recording commands + llglBegin(cmdBuffer); + { + // Set viewport and scissor rectangle + llglSetViewport(&viewport); + + // Set vertex buffer + llglSetVertexBuffer(vertexBuffer); + + // Set the swap-chain as the initial render target + llglBeginRenderPass(LLGL_GET_AS(LLGLRenderTarget, swapChain)); + { + // Clear color buffer + llglClear(LLGLClearColor, &clearColor); + + // Set graphics pipeline + llglSetPipelineState(pipeline); + + // Draw triangle with 3 vertices + llglDraw(3, 0); + } + llglEndRenderPass(); + } + llglEnd(); + + // Present the result on the screen + llglPresent(swapChain); + } + + // Clean up + llglUnloadRenderSystem(); + + return 0; +} diff --git a/examples/C99/HelloTriangle/HelloTriangle.frag b/examples/C99/HelloTriangle/HelloTriangle.frag new file mode 100644 index 0000000000..be6095444f --- /dev/null +++ b/examples/C99/HelloTriangle/HelloTriangle.frag @@ -0,0 +1,11 @@ +// GLSL shader version 1.30 (for OpenGL 3.1) +#version 130 + +in vec4 vColor; + +out vec4 outColor; + +void main() +{ + outColor = vColor; +} diff --git a/examples/C99/HelloTriangle/HelloTriangle.png b/examples/C99/HelloTriangle/HelloTriangle.png new file mode 100644 index 0000000000000000000000000000000000000000..2b7a2727a16c05d7ab376c26abf52851d4298795 GIT binary patch literal 134150 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
    K&a+O`sl0y#XF)k*OCf`cDy=> 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 literal 0 HcmV?d00001 diff --git a/examples/C99/HelloTriangle/HelloTriangle.vert b/examples/C99/HelloTriangle/HelloTriangle.vert new file mode 100644 index 0000000000..84ea38e3d2 --- /dev/null +++ b/examples/C99/HelloTriangle/HelloTriangle.vert @@ -0,0 +1,13 @@ +// GLSL shader version 1.30 (for OpenGL 3.1) +#version 130 + +in vec2 position; +in vec4 color; + +out vec4 vColor; + +void main() +{ + gl_Position = vec4(position, 0, 1); + vColor = color; +} diff --git a/examples/C99/README.md b/examples/C99/README.md new file mode 100644 index 0000000000..b9fef65790 --- /dev/null +++ b/examples/C99/README.md @@ -0,0 +1,14 @@ +# C99 Examples + +This folder contains all LLGL examples written in the C programming language (ISO-C99). +Note that you need to set the **working directory** to `/examples/C99/` in order to get your examples running. +For the first example, this could be `/Users/JohnDoe/LLGL/examples/C99/HelloTriangle` or `C:\Users\JohnDoe\LLGL\examples\C99\HelloTriangle` for instance. + +## Examples + +### [Hello Triangle](HelloTriangle) + +This example illustrates how to interact with LLGL in the C programing language. + +

    + diff --git a/include/LLGL-C/Buffer.h b/include/LLGL-C/Buffer.h new file mode 100644 index 0000000000..4d7bad67e7 --- /dev/null +++ b/include/LLGL-C/Buffer.h @@ -0,0 +1,25 @@ +/* + * Buffer.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_BUFFER_H +#define LLGL_C99_BUFFER_H + + +#include +#include +#include + + +LLGL_C_EXPORT long llglGetBufferBindFlags(LLGLBuffer buffer); +LLGL_C_EXPORT void llglGetBufferDesc(LLGLBuffer buffer, LLGLBufferDescriptor* outDesc); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/BufferFlags.h b/include/LLGL-C/BufferFlags.h new file mode 100644 index 0000000000..3132089979 --- /dev/null +++ b/include/LLGL-C/BufferFlags.h @@ -0,0 +1,46 @@ +/* + * BufferFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_BUFFER_FLAG_H +#define LLGL_C99_BUFFER_FLAG_H + + +#include +#include +#include +#include + + +/* ----- Structures ----- */ + +typedef struct LLGLBufferDescriptor +{ + uint64_t size; + uint32_t stride; + LLGLFormat format; + long bindFlags; + long cpuAccessFlags; + long miscFlags; + size_t numVertexAttribs; + const LLGLVertexAttribute* vertexAttribs; +} +LLGLBufferDescriptor; + +typedef struct LLGLBufferViewDescriptor +{ + LLGLFormat format; + uint64_t offset; + uint64_t size; +} +LLGLBufferViewDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Canvas.h b/include/LLGL-C/Canvas.h new file mode 100644 index 0000000000..5f0088ea78 --- /dev/null +++ b/include/LLGL-C/Canvas.h @@ -0,0 +1,43 @@ +/* + * Canvas.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_CANVAS_H +#define LLGL_C99_CANVAS_H + + +#include +#include +#include +#include +#include + + +typedef void (*LLGL_PFN_OnCanvasProcessEvents)(LLGLCanvas sender); +typedef void (*LLGL_PFN_OnCanvasQuit)(LLGLCanvas sender, bool* veto); + +typedef struct LLGLCanvasEventListener +{ + LLGL_PFN_OnCanvasProcessEvents onProcessEvents; + LLGL_PFN_OnCanvasQuit onQuit; +} +LLGLCanvasEventListener; + +LLGL_C_EXPORT LLGLCanvas llglCreateCanvas(const LLGLCanvasDescriptor* canvasDesc); +LLGL_C_EXPORT void llglReleaseCanvas(LLGLCanvas canvas); +LLGL_C_EXPORT void llglSetCanvasTitle(LLGLCanvas canvas, const wchar_t* title); +LLGL_C_EXPORT size_t llglGetCanvasTitle(LLGLCanvas canvas, size_t outTitleLength, wchar_t* LLGL_NULLABLE(outTitle)); +LLGL_C_EXPORT bool llglHasCanvasQuit(LLGLCanvas canvas); +LLGL_C_EXPORT int llglAddCanvasEventListener(LLGLCanvas canvas, const LLGLCanvasEventListener* eventListener); +LLGL_C_EXPORT void llglRemoveCanvasEventListener(LLGLCanvas canvas, int eventListenerID); +LLGL_C_EXPORT void llglPostCanvasQuit(LLGLCanvas canvas); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/CanvasFlags.h b/include/LLGL-C/CanvasFlags.h new file mode 100644 index 0000000000..22bb4592e0 --- /dev/null +++ b/include/LLGL-C/CanvasFlags.h @@ -0,0 +1,27 @@ +/* + * CanvasFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_CANVAS_FLAGS_H +#define LLGL_C99_CANVAS_FLAGS_H + + +#include + + +typedef struct LLGLCanvasDescriptor +{ + const char* title; + bool borderless; +} +LLGLCanvasDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/CommandBuffer.h b/include/LLGL-C/CommandBuffer.h new file mode 100644 index 0000000000..f6e84829e2 --- /dev/null +++ b/include/LLGL-C/CommandBuffer.h @@ -0,0 +1,83 @@ +/* + * CommandBuffer.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_COMMAND_BUFFER_H +#define LLGL_C99_COMMAND_BUFFER_H + + +#include +#include +#include +#include +#include +#include +#include +#include + + +LLGL_C_EXPORT void llglBegin(LLGLCommandBuffer commandBuffer); +LLGL_C_EXPORT void llglEnd(); +LLGL_C_EXPORT void llglExecute(LLGLCommandBuffer deferredCommandBuffer); +LLGL_C_EXPORT void llglUpdateBuffer(LLGLBuffer dstBuffer, uint64_t dstOffset, const void* data, uint16_t dataSize); +LLGL_C_EXPORT void llglCopyBuffer(LLGLBuffer dstBuffer, uint64_t dstOffset, LLGLBuffer srcBuffer, uint64_t srcOffset, uint64_t size); +LLGL_C_EXPORT void llglCopyBufferFromTexture(LLGLBuffer dstBuffer, uint64_t dstOffset, LLGLTexture srcTexture, const LLGLTextureRegion* srcRegion, uint32_t rowStride, uint32_t layerStride); +LLGL_C_EXPORT void llglFillBuffer(LLGLBuffer dstBuffer, uint64_t dstOffset, uint32_t value, uint64_t fillSize); +LLGL_C_EXPORT void llglCopyTexture(LLGLTexture dstTexture, const LLGLTextureLocation* dstLocation, LLGLTexture srcTexture, const LLGLTextureLocation* srcLocation, const LLGLExtent3D* extent); +LLGL_C_EXPORT void llglCopyTextureFromBuffer(LLGLTexture dstTexture, const LLGLTextureRegion* dstRegion, LLGLBuffer srcBuffer, uint64_t srcOffset, uint32_t rowStride, uint32_t layerStride); +LLGL_C_EXPORT void llglCopyTextureFromFramebuffer(LLGLTexture dstTexture, const LLGLTextureRegion* dstRegion, const LLGLOffset2D* srcOffset); +LLGL_C_EXPORT void llglGenerateMips(LLGLTexture texture); +LLGL_C_EXPORT void llglGenerateMipsRange(LLGLTexture texture, const LLGLTextureSubresource* subresource); +LLGL_C_EXPORT void llglSetViewport(const LLGLViewport* viewport); +LLGL_C_EXPORT void llglSetViewports(uint32_t numViewports, const LLGLViewport* viewports); +LLGL_C_EXPORT void llglSetScissor(const LLGLScissor* scissor); +LLGL_C_EXPORT void llglSetScissors(uint32_t numScissors, const LLGLScissor* scissors); +LLGL_C_EXPORT void llglSetVertexBuffer(LLGLBuffer buffer); +LLGL_C_EXPORT void llglSetVertexBufferArray(LLGLBufferArray bufferArray); +LLGL_C_EXPORT void llglSetIndexBuffer(LLGLBuffer buffer); +LLGL_C_EXPORT void llglSetIndexBufferExt(LLGLBuffer buffer, LLGLFormat format, uint64_t offset); +LLGL_C_EXPORT void llglSetResourceHeap(LLGLResourceHeap resourceHeap, uint32_t descriptorSet); +LLGL_C_EXPORT void llglSetResource(uint32_t descriptor, LLGLResource resource); +LLGL_C_EXPORT void llglResetResourceSlots(LLGLResourceType resourceType, uint32_t firstSlot, uint32_t numSlots, long bindFlags, long stageFlags); +LLGL_C_EXPORT void llglBeginRenderPass(LLGLRenderTarget renderTarget); +LLGL_C_EXPORT void llglBeginRenderPassWithClear(LLGLRenderTarget renderTarget, LLGLRenderPass renderPass, uint32_t numClearValues, const LLGLClearValue* clearValues, uint32_t swapBufferIndex); +LLGL_C_EXPORT void llglEndRenderPass(); +LLGL_C_EXPORT void llglClear(long flags, const LLGLClearValue* clearValue); +LLGL_C_EXPORT void llglClearAttachments(uint32_t numAttachments, const LLGLAttachmentClear* attachments); +LLGL_C_EXPORT void llglSetPipelineState(LLGLPipelineState pipelineState); +LLGL_C_EXPORT void llglSetBlendFactor(const float color[4]); +LLGL_C_EXPORT void llglSetStencilReference(uint32_t reference, LLGLStencilFace stencilFace); +LLGL_C_EXPORT void llglSetUniforms(uint32_t first, const void* data, uint16_t dataSize); +LLGL_C_EXPORT void llglBeginQuery(LLGLQueryHeap queryHeap, uint32_t query); +LLGL_C_EXPORT void llglEndQuery(LLGLQueryHeap queryHeap, uint32_t query); +LLGL_C_EXPORT void llglBeginRenderCondition(LLGLQueryHeap queryHeap, uint32_t query, LLGLRenderConditionMode mode); +LLGL_C_EXPORT void llglEndRenderCondition(); +LLGL_C_EXPORT void llglBeginStreamOutput(uint32_t numBuffers, LLGLBuffer const * buffers); +LLGL_C_EXPORT void llglEndStreamOutput(); +LLGL_C_EXPORT void llglDraw(uint32_t numVertices, uint32_t firstVertex); +LLGL_C_EXPORT void llglDrawIndexed(uint32_t numIndices, uint32_t firstIndex); +LLGL_C_EXPORT void llglDrawIndexedExt(uint32_t numIndices, uint32_t firstIndex, int32_t vertexOffset); +LLGL_C_EXPORT void llglDrawInstanced(uint32_t numVertices, uint32_t firstVertex, uint32_t numInstances); +LLGL_C_EXPORT void llglDrawInstancedExt(uint32_t numVertices, uint32_t firstVertex, uint32_t numInstances, uint32_t firstInstance); +LLGL_C_EXPORT void llglDrawIndexedInstanced(uint32_t numIndices, uint32_t numInstances, uint32_t firstIndex); +LLGL_C_EXPORT void llglDrawIndexedInstancedExt(uint32_t numIndices, uint32_t numInstances, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); +LLGL_C_EXPORT void llglDrawIndirect(LLGLBuffer buffer, uint64_t offset); +LLGL_C_EXPORT void llglDrawIndirectExt(LLGLBuffer buffer, uint64_t offset, uint32_t numCommands, uint32_t stride); +LLGL_C_EXPORT void llglDrawIndexedIndirect(LLGLBuffer buffer, uint64_t offset); +LLGL_C_EXPORT void llglDrawIndexedIndirectExt(LLGLBuffer buffer, uint64_t offset, uint32_t numCommands, uint32_t stride); +LLGL_C_EXPORT void llglDispatch(uint32_t numWorkGroupsX, uint32_t numWorkGroupsY, uint32_t numWorkGroupsZ); +LLGL_C_EXPORT void llglDispatchIndirect(LLGLBuffer buffer, uint64_t offset); +LLGL_C_EXPORT void llglPushDebugGroup(const char* name); +LLGL_C_EXPORT void llglPopDebugGroup(); +LLGL_C_EXPORT void llglDoNativeCommand(const void* nativeCommand, size_t nativeCommandSize); +LLGL_C_EXPORT bool llglGetNativeHandle(void* nativeHandle, size_t nativeHandleSize); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/CommandBufferFlags.h b/include/LLGL-C/CommandBufferFlags.h new file mode 100644 index 0000000000..572b531349 --- /dev/null +++ b/include/LLGL-C/CommandBufferFlags.h @@ -0,0 +1,92 @@ +/* + * CommandBufferFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_COMMAND_BUFFER_FLAGS_H +#define LLGL_C99_COMMAND_BUFFER_FLAGS_H + + +#include +#include + + +/* ----- Enumerations ----- */ + +typedef enum LLGLRenderConditionMode +{ + LLGLRenderConditionModeWait, + LLGLRenderConditionModeNoWait, + LLGLRenderConditionModeByRegionWait, + LLGLRenderConditionModeByRegionNoWait, + LLGLRenderConditionModeWaitInverted, + LLGLRenderConditionModeNoWaitInverted, + LLGLRenderConditionModeByRegionWaitInverted, + LLGLRenderConditionModeByRegionNoWaitInverted, +} +LLGLRenderConditionMode; + +typedef enum LLGLStencilFace +{ + LLGLStencilFaceFrontAndBack, + LLGLStencilFaceFront, + LLGLStencilFaceBack, +} +LLGLStencilFace; + + +/* ----- Flags ----- */ + +enum LLGLCommandBufferFlags +{ + LLGLCommandBufferSecondary = (1 << 0), + LLGLCommandBufferMultiSubmit = (1 << 1), + LLGLCommandBufferImmediateSubmit = (1 << 2), +}; + +enum LLGLClearFlags +{ + LLGLClearColor = (1 << 0), + LLGLClearDepth = (1 << 1), + LLGLClearStencil = (1 << 2), + + LLGLClearColorDepth = (LLGLClearColor | LLGLClearDepth), + LLGLClearDepthStencil = (LLGLClearDepth | LLGLClearStencil), + LLGLClearAll = (LLGLClearColor | LLGLClearDepth | LLGLClearStencil), +}; + + +/* ----- Structures ----- */ + +typedef struct LLGLClearValue +{ + float color[4]; + float depth; + uint32_t stencil; +} +LLGLClearValue; + +typedef struct LLGLAttachmentClear +{ + long flags; + uint32_t colorAttachment; + LLGLClearValue clearValue; +} +LLGLAttachmentClear; + +typedef struct LLGLCommandBufferDescriptor +{ + long flags; + uint32_t numNativeBuffers; + uint64_t minStagingPoolSize; +} +LLGLCommandBufferDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/CommandQueue.h b/include/LLGL-C/CommandQueue.h new file mode 100644 index 0000000000..55c57354c6 --- /dev/null +++ b/include/LLGL-C/CommandQueue.h @@ -0,0 +1,30 @@ +/* + * CommandQueue.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_COMMAND_QUEUE_H +#define LLGL_C99_COMMAND_QUEUE_H + + +#include +#include +#include +#include +#include + + +LLGL_C_EXPORT void llglSubmitCommandBuffer(LLGLCommandBuffer commandBuffer); +LLGL_C_EXPORT bool llglQueryResult(LLGLQueryHeap queryHeap, uint32_t firstQuery, uint32_t numQueries, void* data, size_t dataSize); +LLGL_C_EXPORT void llglSubmitFence(LLGLFence fence); +LLGL_C_EXPORT bool llglWaitFence(LLGLFence fence, uint64_t timeout); +LLGL_C_EXPORT void llglWaitIdle(); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Display.h b/include/LLGL-C/Display.h new file mode 100644 index 0000000000..773125658d --- /dev/null +++ b/include/LLGL-C/Display.h @@ -0,0 +1,41 @@ +/* + * Display.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_DISPLAY_H +#define LLGL_C99_DISPLAY_H + + +#include +#include +#include +#include +#include + + +LLGL_C_EXPORT size_t llglDisplayCount(); +LLGL_C_EXPORT LLGLDisplay const * llglGetDisplayList(); +LLGL_C_EXPORT LLGLDisplay llglGetDisplay(size_t index); +LLGL_C_EXPORT LLGLDisplay llglGetPrimaryDisplay(); +LLGL_C_EXPORT bool llglShowCursor(bool show); +LLGL_C_EXPORT bool llglIsCursorShown(); +LLGL_C_EXPORT bool llglSetCursorPosition(const LLGLOffset2D* position); +LLGL_C_EXPORT void llglGetCursorPosition(LLGLOffset2D* outPosition); + +LLGL_C_EXPORT bool llglIsDisplayPrimary(LLGLDisplay display); +LLGL_C_EXPORT size_t llglGetDisplayDeviceName(LLGLDisplay display, size_t outNameLength, wchar_t* LLGL_NULLABLE(outName)); +LLGL_C_EXPORT void llglGetDisplayOffset(LLGLDisplay display, LLGLOffset2D* outOffset); +LLGL_C_EXPORT bool llglResetDisplayMode(LLGLDisplay display); +LLGL_C_EXPORT bool llglSetDisplayMode(LLGLDisplay display, const LLGLDisplayModeDescriptor* displayModeDesc); +LLGL_C_EXPORT void llglGetDisplayMode(LLGLDisplay display, LLGLDisplayModeDescriptor* outDisplayModeDesc); +LLGL_C_EXPORT size_t llglGetSupportedDisplayModes(LLGLDisplay display, size_t maxNumDisplayModes, LLGLDisplayModeDescriptor* LLGL_NULLABLE(outDisplayModes)); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/DisplayFlags.h b/include/LLGL-C/DisplayFlags.h new file mode 100644 index 0000000000..f37a55c761 --- /dev/null +++ b/include/LLGL-C/DisplayFlags.h @@ -0,0 +1,30 @@ +/* + * DisplayFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_DISPLAY_FLAGS_H +#define LLGL_C99_DISPLAY_FLAGS_H + + +#include +#include + + +/* ----- Structures ----- */ + +typedef struct LLGLDisplayModeDescriptor +{ + LLGLExtent2D resolution; + uint32_t refreshRate; +} +LLGLDisplayModeDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Export.h b/include/LLGL-C/Export.h new file mode 100644 index 0000000000..c1e39ffdcb --- /dev/null +++ b/include/LLGL-C/Export.h @@ -0,0 +1,26 @@ +/* + * Export.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C_EXPORT_H +#define LLGL_C_EXPORT_H + + +#include + + +#ifdef __cplusplus +# define LLGL_C_EXPORT extern "C" LLGL_EXPORT +#else +# define LLGL_C_EXPORT LLGL_EXPORT +#endif + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Format.h b/include/LLGL-C/Format.h new file mode 100644 index 0000000000..134f9f5457 --- /dev/null +++ b/include/LLGL-C/Format.h @@ -0,0 +1,225 @@ +/* + * Format.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_FORMAT_H +#define LLGL_C99_FORMAT_H + + +#include +#include + + +/* ----- Enumerations ----- */ + +typedef enum LLGLFormat +{ + LLGLFormatUndefined, + + /* --- Alpha channel color formats --- */ + LLGLFormatA8UNorm, + + /* --- Red channel color formats --- */ + LLGLFormatR8UNorm, + LLGLFormatR8SNorm, + LLGLFormatR8UInt, + LLGLFormatR8SInt, + + LLGLFormatR16UNorm, + LLGLFormatR16SNorm, + LLGLFormatR16UInt, + LLGLFormatR16SInt, + LLGLFormatR16Float, + + LLGLFormatR32UInt, + LLGLFormatR32SInt, + LLGLFormatR32Float, + + LLGLFormatR64Float, + + /* --- RG color formats --- */ + LLGLFormatRG8UNorm, + LLGLFormatRG8SNorm, + LLGLFormatRG8UInt, + LLGLFormatRG8SInt, + + LLGLFormatRG16UNorm, + LLGLFormatRG16SNorm, + LLGLFormatRG16UInt, + LLGLFormatRG16SInt, + LLGLFormatRG16Float, + + LLGLFormatRG32UInt, + LLGLFormatRG32SInt, + LLGLFormatRG32Float, + + LLGLFormatRG64Float, + + /* --- RGB color formats --- */ + LLGLFormatRGB8UNorm, + LLGLFormatRGB8UNorm_sRGB, + LLGLFormatRGB8SNorm, + LLGLFormatRGB8UInt, + LLGLFormatRGB8SInt, + + LLGLFormatRGB16UNorm, + LLGLFormatRGB16SNorm, + LLGLFormatRGB16UInt, + LLGLFormatRGB16SInt, + LLGLFormatRGB16Float, + + LLGLFormatRGB32UInt, + LLGLFormatRGB32SInt, + LLGLFormatRGB32Float, + + LLGLFormatRGB64Float, + + /* --- RGBA color formats --- */ + LLGLFormatRGBA8UNorm, + LLGLFormatRGBA8UNorm_sRGB, + LLGLFormatRGBA8SNorm, + LLGLFormatRGBA8UInt, + LLGLFormatRGBA8SInt, + + LLGLFormatRGBA16UNorm, + LLGLFormatRGBA16SNorm, + LLGLFormatRGBA16UInt, + LLGLFormatRGBA16SInt, + LLGLFormatRGBA16Float, + + LLGLFormatRGBA32UInt, + LLGLFormatRGBA32SInt, + LLGLFormatRGBA32Float, + + LLGLFormatRGBA64Float, + + /* --- BGRA color formats --- */ + LLGLFormatBGRA8UNorm, + LLGLFormatBGRA8UNorm_sRGB, + LLGLFormatBGRA8SNorm, + LLGLFormatBGRA8UInt, + LLGLFormatBGRA8SInt, + + /* --- Packed formats --- */ + LLGLFormatRGB10A2UNorm, + LLGLFormatRGB10A2UInt, + LLGLFormatRG11B10Float, + LLGLFormatRGB9E5Float, + + /* --- Depth-stencil formats --- */ + LLGLFormatD16UNorm, + LLGLFormatD24UNormS8UInt, + LLGLFormatD32Float, + LLGLFormatD32FloatS8X24UInt, + + /* --- Block compression (BC) formats --- */ + LLGLFormatBC1UNorm, + LLGLFormatBC1UNorm_sRGB, + LLGLFormatBC2UNorm, + LLGLFormatBC2UNorm_sRGB, + LLGLFormatBC3UNorm, + LLGLFormatBC3UNorm_sRGB, + LLGLFormatBC4UNorm, + LLGLFormatBC4SNorm, + LLGLFormatBC5UNorm, + LLGLFormatBC5SNorm, +} +LLGLFormat; + +typedef enum LLGLImageFormat +{ + /* Color formats */ + LLGLImageFormatAlpha, + LLGLImageFormatR, + LLGLImageFormatRG, + LLGLImageFormatRGB, + LLGLImageFormatBGR, + LLGLImageFormatRGBA, + LLGLImageFormatBGRA, + LLGLImageFormatARGB, + LLGLImageFormatABGR, + + /* Depth-stencil formats */ + LLGLImageFormatDepth, + LLGLImageFormatDepthStencil, + + /* Compressed formats */ + LLGLImageFormatBC1, + LLGLImageFormatBC2, + LLGLImageFormatBC3, + LLGLImageFormatBC4, + LLGLImageFormatBC5, +} +LLGLImageFormat; + +typedef enum LLGLDataType +{ + LLGLDataTypeUndefined, + + LLGLDataTypeInt8, + LLGLDataTypeUInt8, + + LLGLDataTypeInt16, + LLGLDataTypeUInt16, + + LLGLDataTypeInt32, + LLGLDataTypeUInt32, + + LLGLDataTypeFloat16, + LLGLDataTypeFloat32, + LLGLDataTypeFloat64, +} +LLGLDataType; + +typedef enum LLGLFormatFlags +{ + LLGLFormatHasDepth = (1 << 0), + LLGLFormatHasStencil = (1 << 1), + LLGLFormatIsColorSpace_sRGB = (1 << 2), + LLGLFormatIsCompressed = (1 << 3), + LLGLFormatIsNormalized = (1 << 4), + LLGLFormatIsInteger = (1 << 5), + LLGLFormatIsUnsigned = (1 << 6), + LLGLFormatIsPacked = (1 << 7), + LLGLFormatSupportsRenderTarget = (1 << 8), + LLGLFormatSupportsMips = (1 << 9), + LLGLFormatSupportsGenerateMips = (1 << 10), + LLGLFormatSupportsTexture1D = (1 << 11), + LLGLFormatSupportsTexture2D = (1 << 12), + LLGLFormatSupportsTexture3D = (1 << 13), + LLGLFormatSupportsTextureCube = (1 << 14), + LLGLFormatSupportsVertex = (1 << 15), + LLGLFormatIsUnsignedInteger = (LLGLFormatIsUnsigned | LLGLFormatIsInteger), + LLGLFormatHasDepthStencil = (LLGLFormatHasDepth | LLGLFormatHasStencil), +} +LLGLFormatFlags; + + +/* ----- Structures ----- */ + +typedef struct LLGLFormatAttributes +{ + uint16_t bitSize; + uint8_t blockWidth; + uint8_t blockHeight; + uint8_t components; + LLGLImageFormat format; + LLGLDataType dataType; + long flags; +} +LLGLFormatAttributes; + + +/* ----- Functions ----- */ + +LLGL_C_EXPORT const LLGLFormatAttributes* llglGetFormatAttribs(LLGLFormat format); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/FragmentAttribute.h b/include/LLGL-C/FragmentAttribute.h new file mode 100644 index 0000000000..b913a5bcae --- /dev/null +++ b/include/LLGL-C/FragmentAttribute.h @@ -0,0 +1,33 @@ +/* + * FragmentAttribute.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_FRAGMENT_ATTRIBUTE_H +#define LLGL_C99_FRAGMENT_ATTRIBUTE_H + + +#include +#include +#include + + +/* ----- Structures ----- */ + +typedef struct LLGLFragmentAttribute +{ + const char* name; + LLGLFormat format; + uint32_t location; + LLGLSystemValue systemValue; +} +LLGLFragmentAttribute; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/ImageFlags.h b/include/LLGL-C/ImageFlags.h new file mode 100644 index 0000000000..703e68dd64 --- /dev/null +++ b/include/LLGL-C/ImageFlags.h @@ -0,0 +1,42 @@ +/* + * ImageFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_IMAGE_FLAGS_H +#define LLGL_C99_IMAGE_FLAGS_H + + +#include +#include +#include + + +/* ----- Structures ----- */ + +typedef struct LLGLSrcImageDescriptor +{ + LLGLImageFormat format; + LLGLDataType dataType; + const void* data; + size_t dataSize; +} +LLGLSrcImageDescriptor; + +typedef struct LLGLDstImageDescriptor +{ + LLGLImageFormat format; + LLGLDataType dataType; + void* data; + size_t dataSize; +} +LLGLDstImageDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/IndirectArguments.h b/include/LLGL-C/IndirectArguments.h new file mode 100644 index 0000000000..3f2f364412 --- /dev/null +++ b/include/LLGL-C/IndirectArguments.h @@ -0,0 +1,56 @@ +/* + * IndirectArguments.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_INDIRECT_ARGUMENTS_H +#define LLGL_C99_INDIRECT_ARGUMENTS_H + + +#include + + +/* ----- Structures ----- */ + +typedef struct LLGLDrawIndirectArguments +{ + uint32_t numVertices; + uint32_t numInstances; + uint32_t firstVertex; + uint32_t firstInstance; +} +LLGLDrawIndirectArguments; + +typedef struct LLGLDrawIndexedIndirectArguments +{ + uint32_t numIndices; + uint32_t numInstances; + uint32_t firstIndex; + int32_t vertexOffset; + uint32_t firstInstance; +} +LLGLDrawIndexedIndirectArguments; + +typedef struct LLGLDrawPatchIndirectArguments +{ + uint32_t numPatches; + uint32_t numInstances; + uint32_t firstPatch; + uint32_t firstInstance; +} +LLGLDrawPatchIndirectArguments; + +typedef struct LLGLDispatchIndirectArguments +{ + uint32_t numThreadGroups[3]; +} +LLGLDispatchIndirectArguments; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Key.h b/include/LLGL-C/Key.h new file mode 100644 index 0000000000..4c7d3f99ab --- /dev/null +++ b/include/LLGL-C/Key.h @@ -0,0 +1,196 @@ +/* + * Key.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_KEY_H +#define LLGL_C99_KEY_H + + +typedef enum LLGLKey +{ + LLGLKeyLButton, + LLGLKeyRButton, + LLGLKeyCancel, + LLGLKeyMButton, + LLGLKeyXButton1, + LLGLKeyXButton2, + + LLGLKeyBack, + LLGLKeyTab, + LLGLKeyClear, + LLGLKeyReturn, + LLGLKeyShift, + LLGLKeyControl, + + LLGLKeyMenu, + LLGLKeyPause, + LLGLKeyCapital, + + LLGLKeyEscape, + LLGLKeySpace, + LLGLKeyPageUp, + LLGLKeyPageDown, + LLGLKeyEnd, + LLGLKeyHome, + + LLGLKeyLeft, + LLGLKeyUp, + LLGLKeyRight, + LLGLKeyDown, + + LLGLKeySelect, + LLGLKeyPrint, + LLGLKeyExe, + LLGLKeySnapshot, + LLGLKeyInsert, + LLGLKeyDelete, + LLGLKeyHelp, + + LLGLKeyD0, + LLGLKeyD1, + LLGLKeyD2, + LLGLKeyD3, + LLGLKeyD4, + LLGLKeyD5, + LLGLKeyD6, + LLGLKeyD7, + LLGLKeyD8, + LLGLKeyD9, + + LLGLKeyA, + LLGLKeyB, + LLGLKeyC, + LLGLKeyD, + LLGLKeyE, + LLGLKeyF, + LLGLKeyG, + LLGLKeyH, + LLGLKeyI, + LLGLKeyJ, + LLGLKeyK, + LLGLKeyL, + LLGLKeyM, + LLGLKeyN, + LLGLKeyO, + LLGLKeyP, + LLGLKeyQ, + LLGLKeyR, + LLGLKeyS, + LLGLKeyT, + LLGLKeyU, + LLGLKeyV, + LLGLKeyW, + LLGLKeyX, + LLGLKeyY, + LLGLKeyZ, + + LLGLKeyLWin, + LLGLKeyRWin, + LLGLKeyApps, + LLGLKeySleep, + + LLGLKeyKeypad0, + LLGLKeyKeypad1, + LLGLKeyKeypad2, + LLGLKeyKeypad3, + LLGLKeyKeypad4, + LLGLKeyKeypad5, + LLGLKeyKeypad6, + LLGLKeyKeypad7, + LLGLKeyKeypad8, + LLGLKeyKeypad9, + + LLGLKeyKeypadMultiply, + LLGLKeyKeypadPlus, + LLGLKeyKeypadSeparator, + LLGLKeyKeypadMinus, + LLGLKeyKeypadDecimal, + LLGLKeyKeypadDivide, + + LLGLKeyF1, + LLGLKeyF2, + LLGLKeyF3, + LLGLKeyF4, + LLGLKeyF5, + LLGLKeyF6, + LLGLKeyF7, + LLGLKeyF8, + LLGLKeyF9, + LLGLKeyF10, + LLGLKeyF11, + LLGLKeyF12, + LLGLKeyF13, + LLGLKeyF14, + LLGLKeyF15, + LLGLKeyF16, + LLGLKeyF17, + LLGLKeyF18, + LLGLKeyF19, + LLGLKeyF20, + LLGLKeyF21, + LLGLKeyF22, + LLGLKeyF23, + LLGLKeyF24, + + LLGLKeyNumLock, + LLGLKeyScrollLock, + + LLGLKeyLShift, + LLGLKeyRShift, + LLGLKeyLControl, + LLGLKeyRControl, + LLGLKeyLMenu, + LLGLKeyRMenu, + + LLGLKeyBrowserBack, + LLGLKeyBrowserForward, + LLGLKeyBrowserRefresh, + LLGLKeyBrowserStop, + LLGLKeyBrowserSearch, + LLGLKeyBrowserFavorits, + LLGLKeyBrowserHome, + + LLGLKeyVolumeMute, + LLGLKeyVolumeDown, + LLGLKeyVolumeUp, + + LLGLKeyMediaNextTrack, + LLGLKeyMediaPrevTrack, + LLGLKeyMediaStop, + LLGLKeyMediaPlayPause, + + LLGLKeyLaunchMail, + LLGLKeyLaunchMediaSelect, + LLGLKeyLaunchApp1, + LLGLKeyLaunchApp2, + + LLGLKeyPlus, + LLGLKeyComma, + LLGLKeyMinus, + LLGLKeyPeriod, + + LLGLKeyExponent, + + LLGLKeyAttn, + LLGLKeyCrSel, + LLGLKeyExSel, + LLGLKeyErEOF, + LLGLKeyPlay, + LLGLKeyZoom, + LLGLKeyNoName, + LLGLKeyPA1, + LLGLKeyOEMClear, + + LLGLKeyAny, +} +LLGLKey; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/LLGL.h b/include/LLGL-C/LLGL.h new file mode 100644 index 0000000000..ef04d17a50 --- /dev/null +++ b/include/LLGL-C/LLGL.h @@ -0,0 +1,38 @@ +/* + * LLGL.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_INCLUDE_H +#define LLGL_C99_INCLUDE_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Log.h b/include/LLGL-C/Log.h new file mode 100644 index 0000000000..932e2cce80 --- /dev/null +++ b/include/LLGL-C/Log.h @@ -0,0 +1,47 @@ +/* + * Log.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_LOG_H +#define LLGL_C99_LOG_H + + +#include +#include + + +/* ----- Enumerations ----- */ + +typedef enum LLGLReportType +{ + LLGLReportTypeDefault = 0, + LLGLReportTypeError, +} +LLGLReportType; + + +/* ----- Types ----- */ + +typedef void* LLGLLogHandle; + +typedef void (*LLGL_PFN_ReportCallback)(LLGLReportType type, const char* text, void* userData); + + +/* ----- Functions ----- */ + +LLGL_C_EXPORT void llglLogPrintf(const char* format, ...); +LLGL_C_EXPORT void llglLogErrorf(const char* format, ...); +LLGL_C_EXPORT LLGLLogHandle llglRegisterLogCallback(LLGL_PFN_ReportCallback callback, void* LLGL_NULLABLE(userData)); +LLGL_C_EXPORT LLGLLogHandle llglRegisterLogCallbackReport(LLGLReport report); +LLGL_C_EXPORT LLGLLogHandle llglRegisterLogCallbackStd(); +LLGL_C_EXPORT void llglUnregisterLogCallback(LLGLLogHandle handle); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/PipelineLayout.h b/include/LLGL-C/PipelineLayout.h new file mode 100644 index 0000000000..95cff68283 --- /dev/null +++ b/include/LLGL-C/PipelineLayout.h @@ -0,0 +1,27 @@ +/* + * PipelineLayout.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_PIPELINE_LAYOUT_H +#define LLGL_C99_PIPELINE_LAYOUT_H + + +#include +#include +#include + + +LLGL_C_EXPORT uint32_t llglGetPipelineLayoutNumHeapBindings(LLGLPipelineLayout pipelineLayout); +LLGL_C_EXPORT uint32_t llglGetPipelineLayoutNumBindings(LLGLPipelineLayout pipelineLayout); +LLGL_C_EXPORT uint32_t llglGetPipelineLayoutNumStaticSamplers(LLGLPipelineLayout pipelineLayout); +LLGL_C_EXPORT uint32_t llglGetPipelineLayoutNumUniforms(LLGLPipelineLayout pipelineLayout); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/PipelineLayoutFlags.h b/include/LLGL-C/PipelineLayoutFlags.h new file mode 100644 index 0000000000..1d293a244c --- /dev/null +++ b/include/LLGL-C/PipelineLayoutFlags.h @@ -0,0 +1,131 @@ +/* + * PipelineLayoutFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_PIPELINE_LAYOUT_FLAGS_H +#define LLGL_C99_PIPELINE_LAYOUT_FLAGS_H + + +#include +#include +#include +#include +#include +#include + + +/* ----- Enumerations ----- */ + +typedef enum LLGLUniformType +{ + LLGLUniformTypeUndefined, + + /* ----- Scalars & Vectors ----- */ + LLGLUniformTypeFloat1, + LLGLUniformTypeFloat2, + LLGLUniformTypeFloat3, + LLGLUniformTypeFloat4, + LLGLUniformTypeDouble1, + LLGLUniformTypeDouble2, + LLGLUniformTypeDouble3, + LLGLUniformTypeDouble4, + LLGLUniformTypeInt1, + LLGLUniformTypeInt2, + LLGLUniformTypeInt3, + LLGLUniformTypeInt4, + LLGLUniformTypeUInt1, + LLGLUniformTypeUInt2, + LLGLUniformTypeUInt3, + LLGLUniformTypeUInt4, + LLGLUniformTypeBool1, + LLGLUniformTypeBool2, + LLGLUniformTypeBool3, + LLGLUniformTypeBool4, + + /* ----- Matrices ----- */ + LLGLUniformTypeFloat2x2, + LLGLUniformTypeFloat2x3, + LLGLUniformTypeFloat2x4, + LLGLUniformTypeFloat3x2, + LLGLUniformTypeFloat3x3, + LLGLUniformTypeFloat3x4, + LLGLUniformTypeFloat4x2, + LLGLUniformTypeFloat4x3, + LLGLUniformTypeFloat4x4, + LLGLUniformTypeDouble2x2, + LLGLUniformTypeDouble2x3, + LLGLUniformTypeDouble2x4, + LLGLUniformTypeDouble3x2, + LLGLUniformTypeDouble3x3, + LLGLUniformTypeDouble3x4, + LLGLUniformTypeDouble4x2, + LLGLUniformTypeDouble4x3, + LLGLUniformTypeDouble4x4, + + /* ----- Resources ----- */ + LLGLUniformTypeSampler, + LLGLUniformTypeImage, + LLGLUniformTypeAtomicCounter, +} +LLGLUniformType; + + +/* ----- Structures ----- */ + +typedef struct LLGLBindingSlot +{ + uint32_t index; + uint32_t set; +} +LLGLBindingSlot; + +typedef struct LLGLBindingDescriptor +{ + const char* name; + LLGLResourceType type; + long bindFlags; + long stageFlags; + LLGLBindingSlot slot; + uint32_t arraySize; +} +LLGLBindingDescriptor; + +typedef struct LLGLStaticSamplerDescriptor +{ + const char* name; + long stageFlags; + LLGLBindingSlot slot; + LLGLSamplerDescriptor sampler; +} +LLGLStaticSamplerDescriptor; + +typedef struct LLGLUniformDescriptor +{ + const char* name; + LLGLUniformType type; + uint32_t arraySize; +} +LLGLUniformDescriptor; + +typedef struct LLGLPipelineLayoutDescriptor +{ + size_t numHeapBindings; + const LLGLBindingDescriptor* heapBindings; + size_t numBindings; + const LLGLBindingDescriptor* bindings; + size_t numStaticSamplers; + const LLGLStaticSamplerDescriptor* staticSamplers; + size_t numUniforms; + const LLGLUniformDescriptor* uniforms; +} +LLGLPipelineLayoutDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/PipelineState.h b/include/LLGL-C/PipelineState.h new file mode 100644 index 0000000000..a32ee86c72 --- /dev/null +++ b/include/LLGL-C/PipelineState.h @@ -0,0 +1,24 @@ +/* + * PipelineState.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_PIPELINE_STATE_H +#define LLGL_C99_PIPELINE_STATE_H + + + +#include +#include + + +LLGL_C_EXPORT LLGLReport llglGetPipelineStateReport(LLGLPipelineState pipelineState); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/PipelineStateFlags.h b/include/LLGL-C/PipelineStateFlags.h new file mode 100644 index 0000000000..14d013e877 --- /dev/null +++ b/include/LLGL-C/PipelineStateFlags.h @@ -0,0 +1,329 @@ +/* + * PipelineStateFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_PIPELINE_STATE_FLAGS_H +#define LLGL_C99_PIPELINE_STATE_FLAGS_H + + +#include +#include +#include +#include + + +/* ----- Enumerations ----- */ + +typedef enum LLGLPrimitiveTopology +{ + LLGLPrimitiveTopologyPointList, + LLGLPrimitiveTopologyLineList, + LLGLPrimitiveTopologyLineStrip, + LLGLPrimitiveTopologyLineListAdjacency, + LLGLPrimitiveTopologyLineStripAdjacency, + LLGLPrimitiveTopologyTriangleList, + LLGLPrimitiveTopologyTriangleStrip, + LLGLPrimitiveTopologyTriangleListAdjacency, + LLGLPrimitiveTopologyTriangleStripAdjacency, + LLGLPrimitiveTopologyPatches1, + LLGLPrimitiveTopologyPatches2, + LLGLPrimitiveTopologyPatches3, + LLGLPrimitiveTopologyPatches4, + LLGLPrimitiveTopologyPatches5, + LLGLPrimitiveTopologyPatches6, + LLGLPrimitiveTopologyPatches7, + LLGLPrimitiveTopologyPatches8, + LLGLPrimitiveTopologyPatches9, + LLGLPrimitiveTopologyPatches10, + LLGLPrimitiveTopologyPatches11, + LLGLPrimitiveTopologyPatches12, + LLGLPrimitiveTopologyPatches13, + LLGLPrimitiveTopologyPatches14, + LLGLPrimitiveTopologyPatches15, + LLGLPrimitiveTopologyPatches16, + LLGLPrimitiveTopologyPatches17, + LLGLPrimitiveTopologyPatches18, + LLGLPrimitiveTopologyPatches19, + LLGLPrimitiveTopologyPatches20, + LLGLPrimitiveTopologyPatches21, + LLGLPrimitiveTopologyPatches22, + LLGLPrimitiveTopologyPatches23, + LLGLPrimitiveTopologyPatches24, + LLGLPrimitiveTopologyPatches25, + LLGLPrimitiveTopologyPatches26, + LLGLPrimitiveTopologyPatches27, + LLGLPrimitiveTopologyPatches28, + LLGLPrimitiveTopologyPatches29, + LLGLPrimitiveTopologyPatches30, + LLGLPrimitiveTopologyPatches31, + LLGLPrimitiveTopologyPatches32, +} +LLGLPrimitiveTopology; + +typedef enum LLGLCompareOp +{ + LLGLCompareOpNeverPass, + LLGLCompareOpLess, + LLGLCompareOpEqual, + LLGLCompareOpLessEqual, + LLGLCompareOpGreater, + LLGLCompareOpNotEqual, + LLGLCompareOpGreaterEqual, + LLGLCompareOpAlwaysPass, +} +LLGLCompareOp; + +typedef enum LLGLStencilOp +{ + LLGLStencilOpKeep, + LLGLStencilOpZero, + LLGLStencilOpReplace, + LLGLStencilOpIncClamp, + LLGLStencilOpDecClamp, + LLGLStencilOpInvert, + LLGLStencilOpIncWrap, + LLGLStencilOpDecWrap, +} +LLGLStencilOp; + +typedef enum LLGLBlendOp +{ + LLGLBlendOpZero, + LLGLBlendOpOne, + LLGLBlendOpSrcColor, + LLGLBlendOpInvSrcColor, + LLGLBlendOpSrcAlpha, + LLGLBlendOpInvSrcAlpha, + LLGLBlendOpDstColor, + LLGLBlendOpInvDstColor, + LLGLBlendOpDstAlpha, + LLGLBlendOpInvDstAlpha, + LLGLBlendOpSrcAlphaSaturate, + LLGLBlendOpBlendFactor, + LLGLBlendOpInvBlendFactor, + LLGLBlendOpSrc1Color, + LLGLBlendOpInvSrc1Color, + LLGLBlendOpSrc1Alpha, + LLGLBlendOpInvSrc1Alpha, +} +LLGLBlendOp; + +typedef enum LLGLBlendArithmetic +{ + LLGLBlendArithmeticAdd, + LLGLBlendArithmeticSubtract, + LLGLBlendArithmeticRevSubtract, + LLGLBlendArithmeticMin, + LLGLBlendArithmeticMax, +} +LLGLBlendArithmetic; + +typedef enum LLGLPolygonMode +{ + LLGLPolygonModeFill, + LLGLPolygonModeWireframe, + LLGLPolygonModePoints, +} +LLGLPolygonMode; + +typedef enum LLGLCullMode +{ + LLGLCullModeDisabled, + LLGLCullModeFront, + LLGLCullModeBack, +} +LLGLCullMode; + +typedef enum LLGLLogicOp +{ + LLGLLogicOpDisabled, + LLGLLogicOpClear, + LLGLLogicOpSet, + LLGLLogicOpCopy, + LLGLLogicOpCopyInverted, + LLGLLogicOpNoOp, + LLGLLogicOpInvert, + LLGLLogicOpAND, + LLGLLogicOpANDReverse, + LLGLLogicOpANDInverted, + LLGLLogicOpNAND, + LLGLLogicOpOR, + LLGLLogicOpORReverse, + LLGLLogicOpORInverted, + LLGLLogicOpNOR, + LLGLLogicOpXOR, + LLGLLogicOpEquiv, +} +LLGLLogicOp; + +typedef enum LLGLTessellationPartition +{ + LLGLTessellationPartitionUndefined, + LLGLTessellationPartitionInteger, + LLGLTessellationPartitionPow2, + LLGLTessellationPartitionFractionalOdd, + LLGLTessellationPartitionFractionalEven, +} +LLGLTessellationPartition; + + +/* ----- Flags ----- */ + +enum LLGLColorMaskFlags +{ + LLGLColorMaskZero = 0, + LLGLColorMaskR = (1 << 0), + LLGLColorMaskG = (1 << 1), + LLGLColorMaskB = (1 << 2), + LLGLColorMaskA = (1 << 3), + LLGLColorMaskAll = (LLGLColorMaskR | LLGLColorMaskG | LLGLColorMaskB | LLGLColorMaskA), +}; + + +/* ----- Structures ----- */ + +typedef struct LLGLViewport +{ + float x; + float y; + float width; + float height; + float minDepth; + float maxDepth; +} +LLGLViewport; + +typedef struct LLGLScissor +{ + int32_t x; + int32_t y; + int32_t width; + int32_t height; +} +LLGLScissor; + +typedef struct LLGLDepthDescriptor +{ + bool testEnabled; + bool writeEnabled; + LLGLCompareOp compareOp; +} +LLGLDepthDescriptor; + +typedef struct LLGLStencilFaceDescriptor +{ + LLGLStencilOp stencilFailOp; + LLGLStencilOp depthFailOp; + LLGLStencilOp depthPassOp; + LLGLCompareOp compareOp; + uint32_t readMask; + uint32_t writeMask; + uint32_t reference; +} +LLGLStencilFaceDescriptor; + +typedef struct LLGLStencilDescriptor +{ + bool testEnabled; + bool referenceDynamic; + LLGLStencilFaceDescriptor front; + LLGLStencilFaceDescriptor back; +} +LLGLStencilDescriptor; + +typedef struct LLGLDepthBiasDescriptor +{ + float constantFactor; + float slopeFactor; + float clamp; +} +LLGLDepthBiasDescriptor; + +typedef struct LLGLRasterizerDescriptor +{ + LLGLPolygonMode polygonMode; + LLGLCullMode cullMode; + LLGLDepthBiasDescriptor depthBias; + bool frontCCW; + bool discardEnabled; + bool depthClampEnabled; + bool scissorTestEnabled; + bool multiSampleEnabled; + bool antiAliasedLineEnabled; + bool conservativeRasterization; + float lineWidth; +} +LLGLRasterizerDescriptor; + +typedef struct LLGLBlendTargetDescriptor +{ + bool blendEnabled; + LLGLBlendOp srcColor; + LLGLBlendOp dstColor; + LLGLBlendArithmetic colorArithmetic; + LLGLBlendOp srcAlpha; + LLGLBlendOp dstAlpha; + LLGLBlendArithmetic alphaArithmetic; + uint8_t colorMask; +} +LLGLBlendTargetDescriptor; + +typedef struct LLGLBlendDescriptor +{ + bool alphaToCoverageEnabled; + bool independentBlendEnabled; + uint32_t sampleMask; + LLGLLogicOp logicOp; + float blendFactor[4]; + bool blendFactorDynamic; + LLGLBlendTargetDescriptor targets[LLGL_MAX_NUM_COLOR_ATTACHMENTS]; +} +LLGLBlendDescriptor; + +typedef struct LLGLTessellationDescriptor +{ + LLGLTessellationPartition partition; + LLGLFormat indexFormat; + uint32_t maxTessFactor; + bool outputWindingCCW; +} +LLGLTessellationDescriptor; + +typedef struct LLGLGraphicsPipelineDescriptor +{ + LLGLPipelineLayout pipelineLayout; + LLGLRenderPass renderPass; + LLGLShader vertexShader; + LLGLShader tessControlShader; + LLGLShader tessEvaluationShader; + LLGLShader geometryShader; + LLGLShader fragmentShader; + LLGLPrimitiveTopology primitiveTopology; + size_t numViewports; + const LLGLViewport* viewports; + size_t numScissors; + const LLGLScissor* scissors; + LLGLDepthDescriptor depth; + LLGLStencilDescriptor stencil; + LLGLRasterizerDescriptor rasterizer; + LLGLBlendDescriptor blend; + LLGLTessellationDescriptor tessellation; +} +LLGLGraphicsPipelineDescriptor; + +typedef struct LLGLComputePipelineDescriptor +{ + LLGLPipelineLayout pipelineLayout; + LLGLShader computeShader; +} +LLGLComputePipelineDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/QueryHeap.h b/include/LLGL-C/QueryHeap.h new file mode 100644 index 0000000000..a89beb46ad --- /dev/null +++ b/include/LLGL-C/QueryHeap.h @@ -0,0 +1,24 @@ +/* + * QueryHeap.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_QUERY_HEAP_H +#define LLGL_C99_QUERY_HEAP_H + + +#include +#include +#include + + +LLGL_C_EXPORT LLGLQueryType llglGetQueryHeapType(LLGLQueryHeap queryHeap); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/QueryHeapFlags.h b/include/LLGL-C/QueryHeapFlags.h new file mode 100644 index 0000000000..2298a4dd82 --- /dev/null +++ b/include/LLGL-C/QueryHeapFlags.h @@ -0,0 +1,60 @@ +/* + * QueryHeapFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_QUERY_HEAP_FLAGS_H +#define LLGL_C99_QUERY_HEAP_FLAGS_H + + +#include +#include + + +typedef enum LLGLQueryType +{ + LLGLQueryTypeSamplesPassed, + LLGLQueryTypeAnySamplesPassed, + LLGLQueryTypeAnySamplesPassedConservative, + LLGLQueryTypeTimeElapsed, + LLGLQueryTypeStreamOutPrimitivesWritten, + LLGLQueryTypeStreamOutOverflow, + LLGLQueryTypePipelineStatistics, +} +LLGLQueryType; + + +/* ----- Structures ----- */ + +typedef struct LLGLQueryPipelineStatistics +{ + uint64_t inputAssemblyVertices; + uint64_t inputAssemblyPrimitives; + uint64_t vertexShaderInvocations; + uint64_t geometryShaderInvocations; + uint64_t geometryShaderPrimitives; + uint64_t clippingInvocations; + uint64_t clippingPrimitives; + uint64_t fragmentShaderInvocations; + uint64_t tessControlShaderInvocations; + uint64_t tessEvaluationShaderInvocations; + uint64_t computeShaderInvocations; +} +LLGLQueryPipelineStatistics; + +typedef struct LLGLQueryHeapDescriptor +{ + LLGLQueryType type; + uint32_t numQueries; + bool renderCondition; +} +LLGLQueryHeapDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/RenderPassFlags.h b/include/LLGL-C/RenderPassFlags.h new file mode 100644 index 0000000000..0ad3fd8b7f --- /dev/null +++ b/include/LLGL-C/RenderPassFlags.h @@ -0,0 +1,58 @@ +/* + * RenderPassFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_RENDER_PASS_FLAGS_H +#define LLGL_C99_RENDER_PASS_FLAGS_H + + +#include +#include + + +/* ----- Enumerations ----- */ + +typedef enum LLGLAttachmentLoadOp +{ + LLGLAttachmentLoadOpUndefined, + LLGLAttachmentLoadOpLoad, + LLGLAttachmentLoadOpClear, +} +LLGLAttachmentLoadOp; + +typedef enum LLGLAttachmentStoreOp +{ + LLGLAttachmentStoreOpUndefined, + LLGLAttachmentStoreOpStore, +} +LLGLAttachmentStoreOp; + + +/* ----- Structures ----- */ + +typedef struct LLGLAttachmentFormatDescriptor +{ + LLGLFormat format; + LLGLAttachmentLoadOp loadOp; + LLGLAttachmentStoreOp storeOp; +} +LLGLAttachmentFormatDescriptor; + +typedef struct LLGLRenderPassDescriptor +{ + LLGLAttachmentFormatDescriptor colorAttachments[LLGL_MAX_NUM_COLOR_ATTACHMENTS]; + LLGLAttachmentFormatDescriptor depthAttachment; + LLGLAttachmentFormatDescriptor stencilAttachment; + uint32_t samples; +} +LLGLRenderPassDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/RenderSystem.h b/include/LLGL-C/RenderSystem.h new file mode 100644 index 0000000000..b554ce5363 --- /dev/null +++ b/include/LLGL-C/RenderSystem.h @@ -0,0 +1,102 @@ +/* + * RenderSystem.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_RENDER_SYSTEM_H +#define LLGL_C99_RENDER_SYSTEM_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +LLGL_C_EXPORT int llglLoadRenderSystem(const char* moduleName); +LLGL_C_EXPORT int llglLoadRenderSystemExt(const LLGLRenderSystemDescriptor* renderSystemDesc, LLGLReport report); +LLGL_C_EXPORT void llglUnloadRenderSystem(); +LLGL_C_EXPORT void llglMakeRenderSystemCurrent(int id); + +LLGL_C_EXPORT int llglGetRendererID(); +LLGL_C_EXPORT const char* llglGetRendererName(); +LLGL_C_EXPORT void llglGetRendererInfo(LLGLRendererInfo* outInfo); +LLGL_C_EXPORT void llglGetRenderingCaps(LLGLRenderingCapabilities* outCaps); +LLGL_C_EXPORT LLGLReport llglGetRendererReport(); + +LLGL_C_EXPORT LLGLSwapChain llglCreateSwapChain(const LLGLSwapChainDescriptor* swapChainDesc); +LLGL_C_EXPORT LLGLSwapChain llglCreateSwapChainExt(const LLGLSwapChainDescriptor* swapChainDesc, LLGLSurface surface); +LLGL_C_EXPORT void llglReleaseSwapChain(LLGLSwapChain swapChain); + +LLGL_C_EXPORT LLGLCommandBuffer llglCreateCommandBuffer(const LLGLCommandBufferDescriptor* commandBufferDesc); +LLGL_C_EXPORT void llglReleaseCommandBuffer(LLGLCommandBuffer commandBuffer); + +LLGL_C_EXPORT LLGLBuffer llglCreateBuffer(const LLGLBufferDescriptor* bufferDesc, const void* initialData); +LLGL_C_EXPORT void llglReleaseBuffer(LLGLBuffer buffer); +LLGL_C_EXPORT void llglWriteBuffer(LLGLBuffer buffer, uint64_t offset, const void* data, uint64_t dataSize); +LLGL_C_EXPORT void llglReadBuffer(LLGLBuffer buffer, uint64_t offset, void* data, uint64_t dataSize); +LLGL_C_EXPORT void* llglMapBuffer(LLGLBuffer buffer, LLGLCPUAccess access); +LLGL_C_EXPORT void* llglMapBufferRange(LLGLBuffer buffer, LLGLCPUAccess access, uint64_t offset, uint64_t length); +LLGL_C_EXPORT void llglUnmapBuffer(LLGLBuffer buffer); + +LLGL_C_EXPORT LLGLBufferArray CreateBufferArray(uint32_t numBuffers, const LLGLBuffer* buffers); +LLGL_C_EXPORT void llglReleaseBufferArray(LLGLBufferArray bufferArray); + +LLGL_C_EXPORT LLGLTexture llglCreateTexture(const LLGLTextureDescriptor* textureDesc, const LLGLSrcImageDescriptor* imageDesc); +LLGL_C_EXPORT void llglReleaseTexture(LLGLTexture texture); +LLGL_C_EXPORT void llglWriteTexture(LLGLTexture texture, const LLGLTextureRegion* textureRegion, const LLGLSrcImageDescriptor* imageDesc); +LLGL_C_EXPORT void llglReadTexture(LLGLTexture texture, const LLGLTextureRegion* textureRegion, const LLGLDstImageDescriptor* imageDesc); + +LLGL_C_EXPORT LLGLSampler llglCreateSampler(const LLGLSamplerDescriptor* samplerDesc); +LLGL_C_EXPORT void llglReleaseSampler(LLGLSampler sampler); + +LLGL_C_EXPORT LLGLResourceHeap llglCreateResourceHeap(const LLGLResourceHeapDescriptor* resourceHeapDesc); +LLGL_C_EXPORT LLGLResourceHeap llglCreateResourceHeapExt(const LLGLResourceHeapDescriptor* resourceHeapDesc, size_t numInitialResourceViews, const LLGLResourceViewDescriptor* initialResourceViews); +LLGL_C_EXPORT void llglReleaseResourceHeap(LLGLResourceHeap resourceHeap); +LLGL_C_EXPORT uint32_t llglWriteResourceHeap(LLGLResourceHeap resourceHeap, uint32_t firstDescriptor, size_t numResourceViews, const LLGLResourceViewDescriptor* resourceViews); + +LLGL_C_EXPORT LLGLRenderPass llglCreateRenderPass(const LLGLRenderPassDescriptor* renderPassDesc); +LLGL_C_EXPORT void llglReleaseRenderPass(LLGLRenderPass renderPass); + +LLGL_C_EXPORT LLGLRenderTarget llglCreateRenderTarget(const LLGLRenderTargetDescriptor* renderTargetDesc); +LLGL_C_EXPORT void llglReleaseRenderTarget(LLGLRenderTarget renderTarget); + +LLGL_C_EXPORT LLGLShader llglCreateShader(const LLGLShaderDescriptor* shaderDesc); +LLGL_C_EXPORT void llglReleaseShader(LLGLShader shader); + +LLGL_C_EXPORT LLGLPipelineLayout llglCreatePipelineLayout(const LLGLPipelineLayoutDescriptor* pipelineLayoutDesc); +LLGL_C_EXPORT void llglReleasePipelineLayout(LLGLPipelineLayout pipelineLayout); + +LLGL_C_EXPORT LLGLPipelineState llglCreateGraphicsPipelineState(const LLGLGraphicsPipelineDescriptor* pipelineStateDesc); +LLGL_C_EXPORT LLGLPipelineState llglCreateComputePipelineState(const LLGLComputePipelineDescriptor* pipelineStateDesc); +LLGL_C_EXPORT void llglReleasePipelineState(LLGLPipelineState pipelineState); + +LLGL_C_EXPORT LLGLQueryHeap llglCreateQueryHeap(const LLGLQueryHeapDescriptor* queryHeapDesc); +LLGL_C_EXPORT void llglReleaseQueryHeap(LLGLQueryHeap queryHeap); + +LLGL_C_EXPORT LLGLFence llglCreateFence(); +LLGL_C_EXPORT void llglReleaseFence(LLGLFence fence); + +LLGL_C_EXPORT bool llglGetRenderSystemNativeHandle(void* nativeHandle, size_t nativeHandleSize); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/RenderSystemFlags.h b/include/LLGL-C/RenderSystemFlags.h new file mode 100644 index 0000000000..2a30c0e546 --- /dev/null +++ b/include/LLGL-C/RenderSystemFlags.h @@ -0,0 +1,224 @@ +/* + * RenderSystemFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_RENDER_SYSTEM_FLAGS_H +#define LLGL_C99_RENDER_SYSTEM_FLAGS_H + + +#include +#include +#include +#include + + +#define LLGL_RENDERERID_UNDEFINED ( 0x00000000 ) + +#define LLGL_RENDERERID_NULL ( 0x00000001 ) +#define LLGL_RENDERERID_OPENGL ( 0x00000002 ) +#define LLGL_RENDERERID_OPENGLES1 ( 0x00000003 ) +#define LLGL_RENDERERID_OPENGLES2 ( 0x00000004 ) +#define LLGL_RENDERERID_OPENGLES3 ( 0x00000005 ) +#define LLGL_RENDERERID_DIRECT3D9 ( 0x00000006 ) +#define LLGL_RENDERERID_DIRECT3D10 ( 0x00000007 ) +#define LLGL_RENDERERID_DIRECT3D11 ( 0x00000008 ) +#define LLGL_RENDERERID_DIRECT3D12 ( 0x00000009 ) +#define LLGL_RENDERERID_VULKAN ( 0x0000000a ) +#define LLGL_RENDERERID_METAL ( 0x0000000b ) + +#define LLGL_RENDERERID_RESERVED ( 0x000000ff ) + + +/* ----- Enumerations ----- */ + +typedef enum LLGLShadingLanguage +{ + LLGLShadingLanguageGLSL = (0x10000), //!< GLSL (OpenGL Shading Language). + LLGLShadingLanguageGLSL_110 = (0x10000 | 110), //!< GLSL 1.10 (since OpenGL 2.0). + LLGLShadingLanguageGLSL_120 = (0x10000 | 120), //!< GLSL 1.20 (since OpenGL 2.1). + LLGLShadingLanguageGLSL_130 = (0x10000 | 130), //!< GLSL 1.30 (since OpenGL 3.0). + LLGLShadingLanguageGLSL_140 = (0x10000 | 140), //!< GLSL 1.40 (since OpenGL 3.1). + LLGLShadingLanguageGLSL_150 = (0x10000 | 150), //!< GLSL 1.50 (since OpenGL 3.2). + LLGLShadingLanguageGLSL_330 = (0x10000 | 330), //!< GLSL 3.30 (since OpenGL 3.3). + LLGLShadingLanguageGLSL_400 = (0x10000 | 400), //!< GLSL 4.00 (since OpenGL 4.0). + LLGLShadingLanguageGLSL_410 = (0x10000 | 410), //!< GLSL 4.10 (since OpenGL 4.1). + LLGLShadingLanguageGLSL_420 = (0x10000 | 420), //!< GLSL 4.20 (since OpenGL 4.2). + LLGLShadingLanguageGLSL_430 = (0x10000 | 430), //!< GLSL 4.30 (since OpenGL 4.3). + LLGLShadingLanguageGLSL_440 = (0x10000 | 440), //!< GLSL 4.40 (since OpenGL 4.4). + LLGLShadingLanguageGLSL_450 = (0x10000 | 450), //!< GLSL 4.50 (since OpenGL 4.5). + LLGLShadingLanguageGLSL_460 = (0x10000 | 460), //!< GLSL 4.60 (since OpenGL 4.6). + + LLGLShadingLanguageESSL = (0x20000), //!< ESSL (OpenGL ES Shading Language). + LLGLShadingLanguageESSL_100 = (0x20000 | 100), //!< ESSL 1.00 (since OpenGL ES 2.0). + LLGLShadingLanguageESSL_300 = (0x20000 | 300), //!< ESSL 3.00 (since OpenGL ES 3.0). + LLGLShadingLanguageESSL_310 = (0x20000 | 310), //!< ESSL 3.10 (since OpenGL ES 3.1). + LLGLShadingLanguageESSL_320 = (0x20000 | 320), //!< ESSL 3.20 (since OpenGL ES 3.2). + + LLGLShadingLanguageHLSL = (0x30000), //!< HLSL (High Level Shading Language). + LLGLShadingLanguageHLSL_2_0 = (0x30000 | 200), //!< HLSL 2.0 (since Direct3D 9). + LLGLShadingLanguageHLSL_2_0a = (0x30000 | 201), //!< HLSL 2.0a (since Direct3D 9a). + LLGLShadingLanguageHLSL_2_0b = (0x30000 | 202), //!< HLSL 2.0b (since Direct3D 9b). + LLGLShadingLanguageHLSL_3_0 = (0x30000 | 300), //!< HLSL 3.0 (since Direct3D 9c). + LLGLShadingLanguageHLSL_4_0 = (0x30000 | 400), //!< HLSL 4.0 (since Direct3D 10). + LLGLShadingLanguageHLSL_4_1 = (0x30000 | 410), //!< HLSL 4.1 (since Direct3D 10.1). + LLGLShadingLanguageHLSL_5_0 = (0x30000 | 500), //!< HLSL 5.0 (since Direct3D 11). + LLGLShadingLanguageHLSL_5_1 = (0x30000 | 510), //!< HLSL 5.1 (since Direct3D 11.3). + LLGLShadingLanguageHLSL_6_0 = (0x30000 | 600), //!< HLSL 6.0 (since Direct3D 12). Shader model 6.0 adds wave intrinsics and 64-bit integer types to HLSL. + LLGLShadingLanguageHLSL_6_1 = (0x30000 | 601), //!< HLSL 6.1 (since Direct3D 12). Shader model 6.1 adds \c SV_ViewID and \c SV_Barycentrics semantics to HLSL. + LLGLShadingLanguageHLSL_6_2 = (0x30000 | 602), //!< HLSL 6.2 (since Direct3D 12). Shader model 6.2 adds 16-bit scalar types to HLSL. + LLGLShadingLanguageHLSL_6_3 = (0x30000 | 603), //!< HLSL 6.3 (since Direct3D 12). Shader model 6.3 adds ray tracing (DXR) to HLSL. + LLGLShadingLanguageHLSL_6_4 = (0x30000 | 604), //!< HLSL 6.4 (since Direct3D 12). Shader model 6.4 adds machine learning intrinsics to HLSL. + + LLGLShadingLanguageMetal = (0x40000), //!< Metal Shading Language. + LLGLShadingLanguageMetal_1_0 = (0x40000 | 100), //!< Metal 1.0 (since iOS 8.0). + LLGLShadingLanguageMetal_1_1 = (0x40000 | 110), //!< Metal 1.1 (since iOS 9.0 and OS X 10.11). + LLGLShadingLanguageMetal_1_2 = (0x40000 | 120), //!< Metal 1.2 (since iOS 10.0 and macOS 10.12). + LLGLShadingLanguageMetal_2_0 = (0x40000 | 200), //!< Metal 2.0 (since iOS 11.0 and macOS 10.13). + LLGLShadingLanguageMetal_2_1 = (0x40000 | 210), //!< Metal 2.1 (since iOS 12.0 and macOS 10.14). + + LLGLShadingLanguageSPIRV = (0x50000), //!< SPIR-V Shading Language. + LLGLShadingLanguageSPIRV_100 = (0x50000 | 100), //!< SPIR-V 1.0. + + LLGLShadingLanguageVersionBitmask = 0x0000ffff, //!< Bitmask for the version number of each shading language enumeration entry. +} +LLGLShadingLanguage; + +typedef enum LLGLScreenOrigin +{ + LLGLScreenOriginLowerLeft, + LLGLScreenOriginUpperLeft, +} +LLGLScreenOrigin; + +typedef enum LLGLClippingRange +{ + LLGLClippingRangeMinusOneToOne, + LLGLClippingRangeZeroToOne, +} +LLGLClippingRange; + +typedef enum LLGLCPUAccess +{ + LLGLCPUAccessReadOnly, + LLGLCPUAccessWriteOnly, + LLGLCPUAccessWriteDiscard, + LLGLCPUAccessReadWrite, +} +LLGLCPUAccess; + + +/* ----- Flags ----- */ + +enum LLGLRenderSystemFlags +{ + LLGLRenderSystemDebugDevice = (1 << 0), +}; + + +/* ----- Structures ----- */ + +typedef struct LLGLRendererInfo +{ + const char* rendererName; + const char* deviceName; + const char* vendorName; + const char* shadingLanguageName; + size_t numExtensionNames; + const char* const* extensionNames; +} +LLGLRendererInfo; + +typedef struct LLGLRenderSystemDescriptor +{ + const char* moduleName; + long flags; + //LLGLRenderingProfiler* profiler; + //LLGLRenderingDebugger* debugger; + const void* rendererConfig; + size_t rendererConfigSize; + + #ifdef LLGL_OS_ANDROID + android_app* androidApp; + #endif +} +LLGLRenderSystemDescriptor; + +typedef struct LLGLRenderingFeatures +{ + bool hasRenderTargets; + bool has3DTextures; + bool hasCubeTextures; + bool hasArrayTextures; + bool hasCubeArrayTextures; + bool hasMultiSampleTextures; + bool hasMultiSampleArrayTextures; + bool hasTextureViews; + bool hasTextureViewSwizzle; + bool hasBufferViews; + bool hasSamplers; + bool hasConstantBuffers; + bool hasStorageBuffers; + bool hasUniforms; + bool hasGeometryShaders; + bool hasTessellationShaders; + bool hasTessellatorStage; + bool hasComputeShaders; + bool hasInstancing; + bool hasOffsetInstancing; + bool hasIndirectDrawing; + bool hasViewportArrays; + bool hasConservativeRasterization; + bool hasStreamOutputs; + bool hasLogicOp; + bool hasPipelineStatistics; + bool hasRenderCondition; +} +LLGLRenderingFeatures; + +typedef struct LLGLRenderingLimits +{ + float lineWidthRange[2]; + uint32_t maxTextureArrayLayers; + uint32_t maxColorAttachments; + uint32_t maxPatchVertices; + uint32_t max1DTextureSize; + uint32_t max2DTextureSize; + uint32_t max3DTextureSize; + uint32_t maxCubeTextureSize; + uint32_t maxAnisotropy; + uint32_t maxComputeShaderWorkGroups[3]; + uint32_t maxComputeShaderWorkGroupSize[3]; + uint32_t maxViewports; + uint32_t maxViewportSize[2]; + uint64_t maxBufferSize; + uint64_t maxConstantBufferSize; + uint32_t maxStreamOutputs; + uint32_t maxTessFactor; + uint64_t minConstantBufferAlignment; + uint64_t minSampledBufferAlignment; + uint64_t minStorageBufferAlignment; +} +LLGLRenderingLimits; + +typedef struct LLGLRenderingCapabilities +{ + LLGLScreenOrigin screenOrigin; + LLGLClippingRange clippingRange; + size_t numShadingLanguages; + const LLGLShadingLanguage* shadingLanguages; + size_t numTextureFormats; + const LLGLFormat* textureFormats; + LLGLRenderingFeatures features; + LLGLRenderingLimits limits; +} +LLGLRenderingCapabilities; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/RenderTarget.h b/include/LLGL-C/RenderTarget.h new file mode 100644 index 0000000000..eaa049592c --- /dev/null +++ b/include/LLGL-C/RenderTarget.h @@ -0,0 +1,29 @@ +/* + * RenderTarget.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_RENDER_TARGET_H +#define LLGL_C99_RENDER_TARGET_H + + +#include +#include +#include + + +LLGL_C_EXPORT void llglGetRenderTargetResolution(LLGLRenderTarget renderTarget, LLGLExtent2D* outResolution); +LLGL_C_EXPORT uint32_t llglGetRenderTargetSamples(LLGLRenderTarget renderTarget); +LLGL_C_EXPORT uint32_t llglGetRenderTargetNumColorAttachments(LLGLRenderTarget renderTarget); +LLGL_C_EXPORT bool llglHasRenderTargetDepthAttachment(LLGLRenderTarget renderTarget); +LLGL_C_EXPORT bool llglHasRenderTargetStencilAttachment(LLGLRenderTarget renderTarget); +LLGL_C_EXPORT LLGLRenderPass llglGetRenderTargetRenderPass(LLGLRenderTarget renderTarget); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/RenderTargetFlags.h b/include/LLGL-C/RenderTargetFlags.h new file mode 100644 index 0000000000..5897971e47 --- /dev/null +++ b/include/LLGL-C/RenderTargetFlags.h @@ -0,0 +1,46 @@ +/* + * RenderTargetFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_RENDER_TARGET_FLAGS_H +#define LLGL_C99_RENDER_TARGET_FLAGS_H + + +#include +#include +#include +#include +#include + + +/* ----- Structures ----- */ + +typedef struct LLGLAttachmentDescriptor +{ + LLGLFormat format; + LLGLTexture texture; + uint32_t mipLevel; + uint32_t arrayLayer; +} +LLGLAttachmentDescriptor; + +typedef struct LLGLRenderTargetDescriptor +{ + LLGLRenderPass renderPass; + LLGLExtent2D resolution; + uint32_t samples; + LLGLAttachmentDescriptor colorAttachments[LLGL_MAX_NUM_COLOR_ATTACHMENTS]; + LLGLAttachmentDescriptor resolveAttachments[LLGL_MAX_NUM_COLOR_ATTACHMENTS]; + LLGLAttachmentDescriptor depthStencilAttachment; +} +LLGLRenderTargetDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Report.h b/include/LLGL-C/Report.h new file mode 100644 index 0000000000..7d45e9c838 --- /dev/null +++ b/include/LLGL-C/Report.h @@ -0,0 +1,25 @@ +/* + * Report.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_REPORT_H +#define LLGL_C99_REPORT_H + + +#include +#include +#include + + +LLGL_C_EXPORT const char* llglGetReportText(LLGLReport report); +LLGL_C_EXPORT bool llglHasReportErrors(LLGLReport report); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Resource.h b/include/LLGL-C/Resource.h new file mode 100644 index 0000000000..70bae81049 --- /dev/null +++ b/include/LLGL-C/Resource.h @@ -0,0 +1,24 @@ +/* + * Resource.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_RESOURCE_H +#define LLGL_C99_RESOURCE_H + + +#include +#include +#include + + +LLGL_C_EXPORT LLGLResourceType lgllGetResourceType(LLGLResource resource); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/ResourceFlags.h b/include/LLGL-C/ResourceFlags.h new file mode 100644 index 0000000000..198a74f6db --- /dev/null +++ b/include/LLGL-C/ResourceFlags.h @@ -0,0 +1,63 @@ +/* + * ResourceFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_RESOURCE_FLAGS_H +#define LLGL_C99_RESOURCE_FLAGS_H + + +/* ----- Enumerations ----- */ + +typedef enum LLGLResourceType +{ + LLGLResourceTypeUndefined, + LLGLResourceTypeBuffer, + LLGLResourceTypeTexture, + LLGLResourceTypeSampler, +} +LLGLResourceType; + + +/* ----- Flags ----- */ + +enum LLGLBindFlags +{ + LLGLBindVertexBuffer = (1 << 0), + LLGLBindIndexBuffer = (1 << 1), + LLGLBindConstantBuffer = (1 << 2), + LLGLBindStreamOutputBuffer = (1 << 3), + LLGLBindIndirectBuffer = (1 << 4), + LLGLBindSampled = (1 << 5), + LLGLBindStorage = (1 << 6), + LLGLBindColorAttachment = (1 << 7), + LLGLBindDepthStencilAttachment = (1 << 8), + LLGLBindCombinedSampler = (1 << 9), + LLGLBindCopySrc = (1 << 10), + LLGLBindCopyDst = (1 << 11), +}; + +enum LLGLCPUAccessFlags +{ + LLGLCPUAccessRead = (1 << 0), + LLGLCPUAccessWrite = (1 << 1), +}; + +enum LLGLMiscFlags +{ + LLGLMiscDynamicUsage = (1 << 0), + LLGLMiscFixedSamples = (1 << 1), + LLGLMiscGenerateMips = (1 << 2), + LLGLMiscNoInitialData = (1 << 3), + LLGLMiscAppend = (1 << 4), + LLGLMiscCounter = (1 << 5), +}; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/ResourceHeapFlags.h b/include/LLGL-C/ResourceHeapFlags.h new file mode 100644 index 0000000000..96f2c8ca85 --- /dev/null +++ b/include/LLGL-C/ResourceHeapFlags.h @@ -0,0 +1,51 @@ +/* + * ResourceViewHeapFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_RESOURCE_VIEW_HEAP_FLAGS_H +#define LLGL_C99_RESOURCE_VIEW_HEAP_FLAGS_H + + +#include +#include +#include + + +/* ----- Flags ----- */ + +enum LLGLBarrierFlags +{ + LLGLBarrierStorageBuffer = (1 << 0), + LLGLBarrierStorageTexture = (1 << 1), + LLGLBarrierStorage = (LLGLBarrierStorageBuffer | LLGLBarrierStorageTexture), +}; + + +/* ----- Structures ----- */ + +typedef struct LLGLResourceViewDescriptor +{ + LLGLResource resource; + LLGLTextureViewDescriptor textureView; + LLGLBufferViewDescriptor bufferView; + uint32_t initialCount; +} +LLGLResourceViewDescriptor; + +typedef struct LLGLResourceHeapDescriptor +{ + LLGLPipelineLayout pipelineLayout; + uint32_t numResourceViews; + long barrierFlags; +} +LLGLResourceHeapDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/SamplerFlags.h b/include/LLGL-C/SamplerFlags.h new file mode 100644 index 0000000000..33062c037b --- /dev/null +++ b/include/LLGL-C/SamplerFlags.h @@ -0,0 +1,63 @@ +/* + * SamplerFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_SAMPLER_FLAGS_H +#define LLGL_C99_SAMPLER_FLAGS_H + + +#include +#include +#include + + +/* ----- Enumerations ----- */ + +typedef enum LLGLSamplerAddressMode +{ + LLGLSamplerAddressModeRepeat, + LLGLSamplerAddressModeMirror, + LLGLSamplerAddressModeClamp, + LLGLSamplerAddressModeBorder, + LLGLSamplerAddressModeMirrorOnce, +} +LLGLSamplerAddressMode; + +typedef enum LLGLSamplerFilter +{ + LLGLSamplerFilterNearest, + LLGLSamplerFilterLinear, +} +LLGLSamplerFilter; + + +/* ----- Structures ----- */ + +typedef struct LLGLSamplerDescriptor +{ + LLGLSamplerAddressMode addressModeU; + LLGLSamplerAddressMode addressModeV; + LLGLSamplerAddressMode addressModeW; + LLGLSamplerFilter minFilter; + LLGLSamplerFilter magFilter; + LLGLSamplerFilter mipMapFilter; + bool mipMapEnabled; + float mipMapLODBias; + float minLOD; + float maxLOD; + uint32_t maxAnisotropy; + bool compareEnabled; + LLGLCompareOp compareOp; + float borderColor[4]; +} +LLGLSamplerDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Shader.h b/include/LLGL-C/Shader.h new file mode 100644 index 0000000000..412926f911 --- /dev/null +++ b/include/LLGL-C/Shader.h @@ -0,0 +1,27 @@ +/* + * Shader.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_SHADER_H +#define LLGL_C99_SHADER_H + + +#include +#include +#include +#include + + +LLGL_C_EXPORT LLGLReport llglGetShaderReport(LLGLShader shader); +LLGL_C_EXPORT bool llglReflectShader(LLGLShader shader, LLGLShaderReflection* reflection); +LLGL_C_EXPORT LLGLShaderType llglGetShaderType(LLGLShader shader); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/ShaderFlags.h b/include/LLGL-C/ShaderFlags.h new file mode 100644 index 0000000000..16761edd8f --- /dev/null +++ b/include/LLGL-C/ShaderFlags.h @@ -0,0 +1,122 @@ +/* + * ShaderFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_SHADER_FLAGS_H +#define LLGL_C99_SHADER_FLAGS_H + + +#include +#include +#include +#include + + +/* ----- Enumerations ----- */ + +typedef enum LLGLShaderType +{ + LLGLShaderTypeUndefined, + LLGLShaderTypeVertex, + LLGLShaderTypeTessControl, + LLGLShaderTypeTessEvaluation, + LLGLShaderTypeGeometry, + LLGLShaderTypeFragment, + LLGLShaderTypeCompute, +} +LLGLShaderType; + +typedef enum LLGLShaderSourceType +{ + LLGLShaderSourceTypeCodeString, + LLGLShaderSourceTypeCodeFile, + LLGLShaderSourceTypeBinaryBuffer, + LLGLShaderSourceTypeBinaryFile, +} +LLGLShaderSourceType; + + +/* ----- Flags ----- */ + +enum LLGLShaderCompileFlags +{ + LLGLShaderCompileDebug = (1 << 0), + LLGLShaderCompileNoOptimization = (1 << 1), + LLGLShaderCompileOptimizationLevel1 = (1 << 2), + LLGLShaderCompileOptimizationLevel2 = (1 << 3), + LLGLShaderCompileOptimizationLevel3 = (1 << 4), + LLGLShaderCompileWarningsAreErrors = (1 << 5), + LLGLShaderCompilePatchClippingOrigin = (1 << 6), + LLGLShaderCompileSeparateShader = (1 << 7), +}; + +enum LLGLStageFlags +{ + LLGLStageVertexStage = (1 << 0), + LLGLStageTessControlStage = (1 << 1), + LLGLStageTessEvaluationStage = (1 << 2), + LLGLStageGeometryStage = (1 << 3), + LLGLStageFragmentStage = (1 << 4), + LLGLStageComputeStage = (1 << 5), + LLGLStageAllTessStages = (LLGLStageTessControlStage | LLGLStageTessEvaluationStage), + LLGLStageAllGraphicsStages = (LLGLStageVertexStage | LLGLStageAllTessStages | LLGLStageGeometryStage | LLGLStageFragmentStage), + LLGLStageAllStages = (LLGLStageAllGraphicsStages | LLGLStageComputeStage), +}; + + +/* ----- Structures ----- */ + +typedef struct LLGLShaderMacro +{ + const char* name; + const char* definition; +} +LLGLShaderMacro; + +typedef struct LLGLVertexShaderAttributes +{ + size_t numInputAttribs; + const LLGLVertexAttribute* inputAttribs; + size_t numOutputAttribs; + const LLGLVertexAttribute* outputAttribs; +} +LLGLVertexShaderAttributes; + +typedef struct LLGLFragmentShaderAttributes +{ + size_t numOutputAttribs; + const LLGLFragmentAttribute* outputAttribs; +} +LLGLFragmentShaderAttributes; + +typedef struct LLGLComputeShaderAttributes +{ + LLGLExtent3D workGroupSize; +} +LLGLComputeShaderAttributes; + +typedef struct LLGLShaderDescriptor +{ + LLGLShaderType type; + const char* source; + size_t sourceSize; + LLGLShaderSourceType sourceType; + const char* entryPoint; + const char* profile; + const LLGLShaderMacro* defines; + long flags; + LLGLVertexShaderAttributes vertex; + LLGLFragmentShaderAttributes fragment; + LLGLComputeShaderAttributes compute; +} +LLGLShaderDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/ShaderReflection.h b/include/LLGL-C/ShaderReflection.h new file mode 100644 index 0000000000..c2b1d86fe7 --- /dev/null +++ b/include/LLGL-C/ShaderReflection.h @@ -0,0 +1,64 @@ +/* + * ShaderReflectionFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_SHADER_REFLECTION_H +#define LLGL_C99_SHADER_REFLECTION_H + + +#include +#include +#include +#include +#include +#include + + +/* ----- Enumerations ----- */ + +typedef enum LLGLStorageBufferType +{ + LLGLStorageBufferTypeUndefined, + LLGLStorageBufferTypeTypedBuffer, + LLGLStorageBufferTypeStructuredBuffer, + LLGLStorageBufferTypeByteAddressBuffer, + LLGLStorageBufferTypeRWTypedBuffer, + LLGLStorageBufferTypeRWStructuredBuffer, + LLGLStorageBufferTypeRWByteAddressBuffer, + LLGLStorageBufferTypeAppendStructuredBuffer, + LLGLStorageBufferTypeConsumeStructuredBuffer, +} +LLGLStorageBufferType; + + +/* ----- Structures ----- */ + +typedef struct LLGLShaderResourceReflection +{ + LLGLBindingDescriptor binding; + uint32_t constantBufferSize; + LLGLStorageBufferType storageBufferType; +} +LLGLShaderResourceReflection; + +typedef struct LLGLShaderReflection +{ + size_t numResources; + const LLGLShaderResourceReflection* resources; + size_t numUniforms; + const LLGLUniformDescriptor* uniforms; + LLGLVertexShaderAttributes vertex; + LLGLFragmentShaderAttributes fragment; + LLGLComputeShaderAttributes compute; +} +LLGLShaderReflection; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Surface.h b/include/LLGL-C/Surface.h new file mode 100644 index 0000000000..a62ed8e00b --- /dev/null +++ b/include/LLGL-C/Surface.h @@ -0,0 +1,31 @@ +/* + * Surface.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_SURFACE_H +#define LLGL_C99_SURFACE_H + + +#include +#include +#include +#include +#include + + +LLGL_C_EXPORT bool llglGetSurfaceNativeHandle(LLGLSurface surface, void* nativeHandle, size_t nativeHandleSize); +LLGL_C_EXPORT void llglGetSurfaceContentSize(LLGLSurface surface, LLGLExtent2D* outSize); +LLGL_C_EXPORT bool llglAdaptSurfaceForVideoMode(LLGLSurface surface, LLGLExtent2D* outResolution, bool* outFullscreen); +LLGL_C_EXPORT void llglResetSurfacePixelFormat(LLGLSurface surface); +LLGL_C_EXPORT bool llglProcessSurfaceEvents(LLGLSurface surface); +LLGL_C_EXPORT LLGLDisplay llglFindSurfaceResidentDisplay(LLGLSurface surface); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/SwapChain.h b/include/LLGL-C/SwapChain.h new file mode 100644 index 0000000000..473bb9e7d6 --- /dev/null +++ b/include/LLGL-C/SwapChain.h @@ -0,0 +1,35 @@ +/* + * SwapChain.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_SWAP_CHAIN_H +#define LLGL_C99_SWAP_CHAIN_H + + +#include +#include +#include +#include +#include +#include + + +LLGL_C_EXPORT void llglPresent(LLGLSwapChain swapChain); +LLGL_C_EXPORT uint32_t llglGetCurrentSwapIndex(LLGLSwapChain swapChain); +LLGL_C_EXPORT uint32_t llglGetNumSwapBuffers(LLGLSwapChain swapChain); +LLGL_C_EXPORT LLGLFormat llglGetColorFormat(LLGLSwapChain swapChain); +LLGL_C_EXPORT LLGLFormat llglGetDepthStencilFormat(LLGLSwapChain swapChain); +LLGL_C_EXPORT bool llglResizeBuffers(LLGLSwapChain swapChain, const LLGLExtent2D* resolution, long flags); +LLGL_C_EXPORT bool llglSetVsyncInterval(LLGLSwapChain swapChain, uint32_t vsyncInterval); +LLGL_C_EXPORT bool llglSwitchFullscreen(LLGLSwapChain swapChain, bool enable); +LLGL_C_EXPORT LLGLSurface llglGetSurface(LLGLSwapChain swapChain); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/SwapChainFlags.h b/include/LLGL-C/SwapChainFlags.h new file mode 100644 index 0000000000..831c5159b4 --- /dev/null +++ b/include/LLGL-C/SwapChainFlags.h @@ -0,0 +1,45 @@ +/* + * SwapChainFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_SWAP_CHAIN_FLAGS_H +#define LLGL_C99_SWAP_CHAIN_FLAGS_H + + +#include +#include + + +/* ----- Flags ----- */ + +enum LLGLResizeBuffersFlags +{ + LLGLResizeBuffersAdaptSurface = (1 << 0), + LLGLResizeBuffersFullscreenMode = (1 << 1), + LLGLResizeBuffersWindowedMode = (1 << 2), +}; + + +/* ----- Structures ----- */ + +typedef struct LLGLSwapChainDescriptor +{ + LLGLExtent2D resolution; + int colorBits; + int depthBits; + int stencilBits; + uint32_t samples; + uint32_t swapBuffers; + bool fullscreen; +} +LLGLSwapChainDescriptor; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/SystemValue.h b/include/LLGL-C/SystemValue.h new file mode 100644 index 0000000000..fd6b342056 --- /dev/null +++ b/include/LLGL-C/SystemValue.h @@ -0,0 +1,41 @@ +/* + * SystemValue.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_SYSTEM_VALUE_H +#define LLGL_C99_SYSTEM_VALUE_H + + +/* ----- Enumerations ----- */ + +typedef enum LLGLSystemValue +{ + LLGLSystemValueUndefined, + LLGLSystemValueClipDistance, + LLGLSystemValueColor, + LLGLSystemValueCullDistance, + LLGLSystemValueDepth, + LLGLSystemValueDepthGreater, + LLGLSystemValueDepthLess, + LLGLSystemValueFrontFacing, + LLGLSystemValueInstanceID, + LLGLSystemValuePosition, + LLGLSystemValuePrimitiveID, + LLGLSystemValueRenderTargetIndex, + LLGLSystemValueSampleMask, + LLGLSystemValueSampleID, + LLGLSystemValueStencil, + LLGLSystemValueVertexID, + LLGLSystemValueViewportIndex, +} +LLGLSystemValue; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Texture.h b/include/LLGL-C/Texture.h new file mode 100644 index 0000000000..aad85d9993 --- /dev/null +++ b/include/LLGL-C/Texture.h @@ -0,0 +1,29 @@ +/* + * Texture.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_TEXTURE_H +#define LLGL_C99_TEXTURE_H + + +#include +#include +#include + + +LLGL_C_EXPORT LLGLTextureType llglGetTextureType(LLGLTexture texture); +LLGL_C_EXPORT long llglGetTextureBindFlags(LLGLTexture texture); +LLGL_C_EXPORT void llglGetTextureDesc(LLGLTexture texture, LLGLTextureDescriptor* outDesc); +LLGL_C_EXPORT LLGLFormat llglGetTextureFormat(LLGLTexture texture); +LLGL_C_EXPORT void llglGetTextureMipExtent(LLGLTexture texture, uint32_t mipLevel, LLGLExtent3D* outExtent); +LLGL_C_EXPORT void llglGetTextureSubresourceFootprint(LLGLTexture texture, uint32_t mipLevel, LLGLSubresourceFootprint* outFootprint); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/TextureFlags.h b/include/LLGL-C/TextureFlags.h new file mode 100644 index 0000000000..2ee520704a --- /dev/null +++ b/include/LLGL-C/TextureFlags.h @@ -0,0 +1,122 @@ +/* + * TextureFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_TEXTURE_FLAGS_H +#define LLGL_C99_TEXTURE_FLAGS_H + + +#include +#include +#include +#include +#include + + +/* ----- Enumerations ----- */ + +typedef enum LLGLTextureType +{ + LLGLTextureTypeTexture1D, + LLGLTextureTypeTexture2D, + LLGLTextureTypeTexture3D, + LLGLTextureTypeTextureCube, + LLGLTextureTypeTexture1DArray, + LLGLTextureTypeTexture2DArray, + LLGLTextureTypeTextureCubeArray, + LLGLTextureTypeTexture2DMS, + LLGLTextureTypeTexture2DMSArray, +} +LLGLTextureType; + +typedef enum LLGLTextureSwizzle +{ + LLGLTextureSwizzleZero, + LLGLTextureSwizzleOne, + LLGLTextureSwizzleRed, + LLGLTextureSwizzleGreen, + LLGLTextureSwizzleBlue, + LLGLTextureSwizzleAlpha, +} +LLGLTextureSwizzle; + + +/* ----- Structures ----- */ + +typedef struct LLGLTextureSwizzleRGBA +{ + LLGLTextureSwizzle r : 8; + LLGLTextureSwizzle g : 8; + LLGLTextureSwizzle b : 8; + LLGLTextureSwizzle a : 8; +} +LLGLTextureSwizzleRGBA; + +typedef struct LLGLTextureSubresource +{ + uint32_t baseArrayLayer; + uint32_t numArrayLayers; + uint32_t baseMipLevel; + uint32_t numMipLevels; +} +LLGLTextureSubresource; + +typedef struct LLGLTextureLocation +{ + LLGLOffset3D offset; + uint32_t arrayLayer; + uint32_t mipLevel; +} +LLGLTextureLocation; + +typedef struct LLGLTextureRegion +{ + LLGLTextureSubresource subresource; + LLGLOffset3D offset; + LLGLExtent3D extent; +} +LLGLTextureRegion; + +typedef struct LLGLTextureDescriptor +{ + LLGLTextureType type; + long bindFlags; + long miscFlags; + LLGLFormat format; + LLGLExtent3D extent; + uint32_t arrayLayers; + uint32_t mipLevels; + uint32_t samples; + LLGLClearValue clearValue; +} +LLGLTextureDescriptor; + +typedef struct LLGLTextureViewDescriptor +{ + LLGLTextureType type; + LLGLFormat format; + LLGLTextureSubresource subresource; + LLGLTextureSwizzleRGBA swizzle; +} +LLGLTextureViewDescriptor; + +typedef struct LLGLSubresourceFootprint +{ + uint64_t size; + uint32_t rowAlignment; + uint32_t rowSize; + uint32_t rowStride; + uint32_t layerSize; + uint32_t layerStride; +} +LLGLSubresourceFootprint; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Timer.h b/include/LLGL-C/Timer.h new file mode 100644 index 0000000000..f7916dbb25 --- /dev/null +++ b/include/LLGL-C/Timer.h @@ -0,0 +1,24 @@ +/* + * Timer.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_TIMER_H +#define LLGL_C99_TIMER_H + + +#include +#include + + +LLGL_C_EXPORT uint64_t llglTimerFrequency(); +LLGL_C_EXPORT uint64_t llglTimerTick(); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Types.h b/include/LLGL-C/Types.h new file mode 100644 index 0000000000..68a404ec80 --- /dev/null +++ b/include/LLGL-C/Types.h @@ -0,0 +1,92 @@ +/* + * Types.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_TYPES_H +#define LLGL_C99_TYPES_H + + +#include + + +#define LLGL_NULL_OBJECT { NULL } +#define LLGL_GET(OBJ) ((OBJ).internal) +#define LLGL_GET_AS(TYPE, OBJ) (TYPE){ LLGL_GET(OBJ) } +#define LLGL_NULLABLE(IDENT) IDENT + +#define LLGL_DECL_WRAPPER_TYPE(NAME) \ + typedef struct NAME { void* internal; } NAME + +#define LLGL_DECL_CONST_WRAPPER_TYPE(NAME) \ + typedef struct NAME { const void* internal; } NAME + +LLGL_DECL_WRAPPER_TYPE( LLGLBuffer ); +LLGL_DECL_WRAPPER_TYPE( LLGLBufferArray ); +LLGL_DECL_WRAPPER_TYPE( LLGLCanvas ); +LLGL_DECL_WRAPPER_TYPE( LLGLCommandBuffer ); +LLGL_DECL_WRAPPER_TYPE( LLGLCommandQueue ); +LLGL_DECL_WRAPPER_TYPE( LLGLDisplay ); +LLGL_DECL_WRAPPER_TYPE( LLGLFence ); +LLGL_DECL_WRAPPER_TYPE( LLGLImage ); +LLGL_DECL_WRAPPER_TYPE( LLGLPipelineLayout ); +LLGL_DECL_WRAPPER_TYPE( LLGLPipelineState ); +LLGL_DECL_WRAPPER_TYPE( LLGLQueryHeap ); +LLGL_DECL_WRAPPER_TYPE( LLGLRenderPass ); +/*LLGL_DECL_WRAPPER_TYPE( LLGLRenderSystem );*/ +LLGL_DECL_WRAPPER_TYPE( LLGLRenderTarget ); +LLGL_DECL_WRAPPER_TYPE( LLGLResource ); +LLGL_DECL_WRAPPER_TYPE( LLGLResourceHeap ); +LLGL_DECL_WRAPPER_TYPE( LLGLSampler ); +LLGL_DECL_WRAPPER_TYPE( LLGLShader ); +LLGL_DECL_WRAPPER_TYPE( LLGLSurface ); +LLGL_DECL_WRAPPER_TYPE( LLGLSwapChain ); +LLGL_DECL_WRAPPER_TYPE( LLGLTexture ); +LLGL_DECL_WRAPPER_TYPE( LLGLWindow ); + +LLGL_DECL_CONST_WRAPPER_TYPE( LLGLReport ); + +#undef LLGL_DECL_WRAPPER_TYPE +#undef LLGL_DECL_CONST_WRAPPER_TYPE + + +/* ----- Structures ----- */ + +typedef struct LLGLExtent2D +{ + uint32_t width; + uint32_t height; +} +LLGLExtent2D; + +typedef struct LLGLExtent3D +{ + uint32_t width; + uint32_t height; + uint32_t depth; +} +LLGLExtent3D; + +typedef struct LLGLOffset2D +{ + int32_t x; + int32_t y; +} +LLGLOffset2D; + +typedef struct LLGLOffset3D +{ + int32_t x; + int32_t y; + int32_t z; +} +LLGLOffset3D; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/VertexAttribute.h b/include/LLGL-C/VertexAttribute.h new file mode 100644 index 0000000000..581c4ca012 --- /dev/null +++ b/include/LLGL-C/VertexAttribute.h @@ -0,0 +1,39 @@ +/* + * VertexAttribute.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_VERTEX_ATTRIBUTE_H +#define LLGL_C99_VERTEX_ATTRIBUTE_H + + +#include +#include +#include +#include + + +/* ----- Structures ----- */ + +typedef struct LLGLVertexAttribute +{ + const char* name; + LLGLFormat format; + uint32_t location; + uint32_t semanticIndex; + LLGLSystemValue systemValue; + uint32_t slot; + uint32_t offset; + uint32_t stride; + uint32_t instanceDivisor; +} +LLGLVertexAttribute; + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/Window.h b/include/LLGL-C/Window.h new file mode 100644 index 0000000000..99e4bc468b --- /dev/null +++ b/include/LLGL-C/Window.h @@ -0,0 +1,88 @@ +/* + * Window.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_WINDOW_H +#define LLGL_C99_WINDOW_H + + +#include +#include +#include +#include +#include +#include + + +typedef void (*LLGL_PFN_OnWindowProcessEvents)(LLGLWindow sender); +typedef void (*LLGL_PFN_OnWindowQuit)(LLGLWindow sender, bool* veto); +typedef void (*LLGL_PFN_OnWindowKeyDown)(LLGLWindow sender, LLGLKey keyCode); +typedef void (*LLGL_PFN_OnWindowKeyUp)(LLGLWindow sender, LLGLKey keyCode); +typedef void (*LLGL_PFN_OnWindowDoubleClick)(LLGLWindow sender, LLGLKey keyCode); +typedef void (*LLGL_PFN_OnWindowChar)(LLGLWindow sender, wchar_t chr); +typedef void (*LLGL_PFN_OnWindowWheelMotion)(LLGLWindow sender, int motion); +typedef void (*LLGL_PFN_OnWindowLocalMotion)(LLGLWindow sender, const LLGLOffset2D* position); +typedef void (*LLGL_PFN_OnWindowGlobalMotion)(LLGLWindow sender, const LLGLOffset2D* motion); +typedef void (*LLGL_PFN_OnWindowResize)(LLGLWindow sender, const LLGLExtent2D* clientAreaSize); +typedef void (*LLGL_PFN_OnWindowGetFocus)(LLGLWindow sender); +typedef void (*LLGL_PFN_OnWindowLostFocus)(LLGLWindow sender); +typedef void (*LLGL_PFN_OnWindowTimer)(LLGLWindow sender, uint32_t timerID); + +typedef struct LLGLWindowEventListener +{ + LLGL_PFN_OnWindowProcessEvents onProcessEvents; + LLGL_PFN_OnWindowQuit onQuit; + LLGL_PFN_OnWindowKeyDown onKeyDown; + LLGL_PFN_OnWindowKeyUp onKeyUp; + LLGL_PFN_OnWindowDoubleClick onDoubleClick; + LLGL_PFN_OnWindowChar onChar; + LLGL_PFN_OnWindowWheelMotion onWheelMotion; + LLGL_PFN_OnWindowLocalMotion onLocalMotion; + LLGL_PFN_OnWindowGlobalMotion onGlobalMotion; + LLGL_PFN_OnWindowResize onResize; + LLGL_PFN_OnWindowGetFocus onGetFocus; + LLGL_PFN_OnWindowLostFocus onLostFocus; + LLGL_PFN_OnWindowTimer onTimer; +} +LLGLWindowEventListener; + +LLGL_C_EXPORT LLGLWindow llglCreateWindow(const LLGLWindowDescriptor* windowDesc); +LLGL_C_EXPORT void llglReleaseWindow(LLGLWindow window); +LLGL_C_EXPORT void llglSetWindowPosition(LLGLWindow window, const LLGLOffset2D* position); +LLGL_C_EXPORT void llglGetWindowPosition(LLGLWindow window, LLGLOffset2D* outPosition); +LLGL_C_EXPORT void llglSetWindowSize(LLGLWindow window, const LLGLExtent2D* size, bool useClientArea); +LLGL_C_EXPORT void llglGetWindowSize(LLGLWindow window, LLGLExtent2D* outSize, bool useClientArea); +LLGL_C_EXPORT void llglSetWindowTitle(LLGLWindow window, const wchar_t* title); +LLGL_C_EXPORT size_t llglGetWindowTitle(LLGLWindow window, size_t outTitleLength, wchar_t* LLGL_NULLABLE(outTitle)); +LLGL_C_EXPORT void llglShowWindow(LLGLWindow window, bool show); +LLGL_C_EXPORT bool llglIsWindowShown(LLGLWindow window); +LLGL_C_EXPORT void llglSetWindowDesc(LLGLWindow window, const LLGLWindowDescriptor* windowDesc); +LLGL_C_EXPORT void llglGetWindowDesc(LLGLWindow window, LLGLWindowDescriptor* outWindowDesc); +LLGL_C_EXPORT bool llglHasWindowFocus(LLGLWindow window); +LLGL_C_EXPORT bool llglHasWindowQuit(LLGLWindow window); +LLGL_C_EXPORT void llglSetWindowBehavior(LLGLWindow window, const LLGLWindowBehavior* behavior); +LLGL_C_EXPORT void llglGetWindowBehavior(LLGLWindow window, LLGLWindowBehavior* outBehavior); +LLGL_C_EXPORT int llglAddWindowEventListener(LLGLWindow window, const LLGLWindowEventListener* eventListener); +LLGL_C_EXPORT void llglRemoveWindowEventListener(LLGLWindow window, int eventListenerID); +LLGL_C_EXPORT void llglPostWindowQuit(LLGLWindow window); +LLGL_C_EXPORT void llglPostWindowKeyDown(LLGLWindow window, LLGLKey keyCode); +LLGL_C_EXPORT void llglPostWindowKeyUp(LLGLWindow window, LLGLKey keyCode); +LLGL_C_EXPORT void llglPostWindowDoubleClick(LLGLWindow window, LLGLKey keyCode); +LLGL_C_EXPORT void llglPostWindowChar(LLGLWindow window, wchar_t chr); +LLGL_C_EXPORT void llglPostWindowWheelMotion(LLGLWindow window, int motion); +LLGL_C_EXPORT void llglPostWindowLocalMotion(LLGLWindow window, const LLGLOffset2D* position); +LLGL_C_EXPORT void llglPostWindowGlobalMotion(LLGLWindow window, const LLGLOffset2D* motion); +LLGL_C_EXPORT void llglPostWindowResize(LLGLWindow window, const LLGLExtent2D* clientAreaSize); +LLGL_C_EXPORT void llglPostWindowGetFocus(LLGLWindow window); +LLGL_C_EXPORT void llglPostWindowLostFocus(LLGLWindow window); +LLGL_C_EXPORT void llglPostWindowTimer(LLGLWindow window, uint32_t timerID); + + +#endif + + + +// ================================================================================ diff --git a/include/LLGL-C/WindowFlags.h b/include/LLGL-C/WindowFlags.h new file mode 100644 index 0000000000..62747896a5 --- /dev/null +++ b/include/LLGL-C/WindowFlags.h @@ -0,0 +1,43 @@ +/* + * WindowFlags.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_WINDOW_FLAGS_H +#define LLGL_C99_WINDOW_FLAGS_H + + +#include +#include +#include + + +typedef struct LLGLWindowDescriptor +{ + const char* title; + LLGLOffset2D position; + LLGLExtent2D size; + bool visible; + bool borderless; + bool resizable; + bool acceptDropFiles; + bool centered; + const void* windowContext; +} +LLGLWindowDescriptor; + +typedef struct LLGLWindowBehavior +{ + bool disableClearOnResize; + uint32_t moveAndResizeTimerID; +} +LLGLWindowBehavior; + + +#endif + + + +// ================================================================================ diff --git a/include/README.md b/include/README.md new file mode 100644 index 0000000000..e02c8bdcd3 --- /dev/null +++ b/include/README.md @@ -0,0 +1,17 @@ +# Root directory to include LLGL + +This should be your directory to add to your include paths for C and C++. +All LLGL headers include their dependencies via `` and so should your application. +For instance, add `#include ` at the top of your source files for C++ applications and `#include ` for C applications. + + +## Wrappers + +## C99 Wrapper + +All typenames in the C99 wrapper follow the same naming convention: +- **Enumeration** entries start with upper case `LLGL` followed by their typename and then their entry name, e.g. `LLGL::TextureType::Texture2D` translates to `LLGLTextureTypeTexture2D`. +- **Structures** start with upper case `LLGL` followed by their typename, e.g. `LLGL::TextureDescriptor` translates to `LLGLTextureDescriptor`. +- **Interface** instances start with upper case `LLGL` followed by their typename and are declared as structures with opaque pointers, e.g. `LLGL::Buffer*` translates to `LLGLBuffer`. +- **Function** start with lower case `llgl` followed by an individual name that varies from interface to interface, e.g. `LLGL::Texture::GetDesc` translates to `llglGetTextureDesc`. + diff --git a/wrapper/C99/C99Buffer.cpp b/wrapper/C99/C99Buffer.cpp new file mode 100644 index 0000000000..f2b3215ab6 --- /dev/null +++ b/wrapper/C99/C99Buffer.cpp @@ -0,0 +1,35 @@ +/* + * C99Buffer.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT long llglGetBufferBindFlags(LLGLBuffer buffer) +{ + return LLGL_PTR(Buffer, buffer)->GetBindFlags(); +} + +LLGL_C_EXPORT void llglGetBufferDesc(LLGLBuffer buffer, LLGLBufferDescriptor* outDesc) +{ + LLGL_ASSERT_PTR(outDesc); + const BufferDescriptor internalDesc = LLGL_PTR(Buffer, buffer)->GetDesc(); + *outDesc = *reinterpret_cast(&internalDesc); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99Canvas.cpp b/wrapper/C99/C99Canvas.cpp new file mode 100644 index 0000000000..5a01c8ca73 --- /dev/null +++ b/wrapper/C99/C99Canvas.cpp @@ -0,0 +1,129 @@ +/* + * C99Canvas.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" +#include "../sources/Core/CoreUtils.h" +#include +#include +#include + + +// namespace LLGL { + + +using namespace LLGL; + +#define LLGL_CALLBACK_WRAPPER(FUNC, ...) \ + if (callbacks_.FUNC != NULL) { callbacks_.FUNC(LLGLCanvas{ &sender }, __VA_ARGS__); } + +class InternalCanvasEventListener final : public Canvas::EventListener +{ + + LLGLCanvasEventListener callbacks_; + + public: + + InternalCanvasEventListener(const LLGLCanvasEventListener* callbacks) + { + memcpy(&callbacks_, callbacks, sizeof(LLGLCanvasEventListener)); + } + + void OnProcessEvents(Canvas& sender) override + { + LLGL_CALLBACK_WRAPPER(onProcessEvents); + } + + void OnQuit(Canvas& sender, bool& veto) override + { + LLGL_CALLBACK_WRAPPER(onQuit, &veto); + } + +}; + +#undef LLGL_CALLBACK_WRAPPER + +static std::vector> g_Canvases; + +static void ConvertCanvasDesc(CanvasDescriptor& dst, const LLGLCanvasDescriptor& src) +{ + dst.title = src.title; + dst.borderless = src.borderless; +} + +static void ConvertCanvasDesc(LLGLCanvasDescriptor& dst, const CanvasDescriptor& src) +{ + static thread_local std::string internalTitle; + internalTitle = src.title.c_str(); + dst.title = internalTitle.c_str(); + dst.borderless = src.borderless; +} + +LLGL_C_EXPORT LLGLCanvas llglCreateCanvas(const LLGLCanvasDescriptor* canvasDesc) +{ + LLGL_ASSERT_PTR(canvasDesc); + CanvasDescriptor internalCanvasDesc; + ConvertCanvasDesc(internalCanvasDesc, *canvasDesc); + g_Canvases.push_back(Canvas::Create(internalCanvasDesc)); + return LLGLCanvas{ g_Canvases.back().get() }; +} + +LLGL_C_EXPORT void llglReleaseCanvas(LLGLCanvas canvas) +{ + RemoveFromListIf( + g_Canvases, + [canvas](const std::unique_ptr& entry) -> bool + { + return (entry.get() == LLGL_PTR(Canvas, canvas)); + } + ); +} + +LLGL_C_EXPORT void llglSetCanvasTitle(LLGLCanvas canvas, const wchar_t* title) +{ + LLGL_PTR(Canvas, canvas)->SetTitle(title); +} + +LLGL_C_EXPORT size_t llglGetCanvasTitle(LLGLCanvas canvas, size_t outTitleLength, wchar_t* outTitle) +{ + UTF8String title = LLGL_PTR(Canvas, canvas)->GetTitle(); + SmallVector titleUTF16 = title.to_utf16(); + if (outTitle != NULL) + { + outTitleLength = (outTitleLength < titleUTF16.size() ? outTitleLength : titleUTF16.size()); + memcpy(outTitle, titleUTF16.data(), outTitleLength * sizeof(wchar_t)); + } + return titleUTF16.size(); +} + +LLGL_C_EXPORT bool llglHasCanvasQuit(LLGLCanvas canvas) +{ + return LLGL_PTR(Canvas, canvas)->HasQuit(); +} + +LLGL_C_EXPORT int llglAddCanvasEventListener(LLGLCanvas canvas, const LLGLCanvasEventListener* eventListener) +{ + return 0; //todo +} + +LLGL_C_EXPORT void llglRemoveCanvasEventListener(LLGLCanvas canvas, int eventListenerID) +{ + //todo +} + +LLGL_C_EXPORT void llglPostCanvasQuit(LLGLCanvas canvas) +{ + LLGL_PTR(Canvas, canvas)->PostQuit(); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99CommandBuffer.cpp b/wrapper/C99/C99CommandBuffer.cpp new file mode 100644 index 0000000000..bb5158bc09 --- /dev/null +++ b/wrapper/C99/C99CommandBuffer.cpp @@ -0,0 +1,310 @@ +/* + * C99CommandBuffer.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include +#include "C99Internal.h" +#include "../../../sources/Core/Assertion.h" + + +// namespace LLGL { + + +using namespace LLGL; + +static thread_local CommandBuffer* g_CurrentCmdBuf = NULL; + + +LLGL_C_EXPORT void llglBegin(LLGLCommandBuffer commandBuffer) +{ + LLGL_ASSERT(g_CurrentCmdBuf == NULL); + g_CurrentCmdBuf = LLGL_PTR(CommandBuffer, commandBuffer); + g_CurrentCmdBuf->Begin(); +} + +LLGL_C_EXPORT void llglEnd() +{ + LLGL_ASSERT(g_CurrentCmdBuf != NULL); + g_CurrentCmdBuf->End(); + g_CurrentCmdBuf = NULL; +} + +LLGL_C_EXPORT void llglExecute(LLGLCommandBuffer deferredCommandBuffer) +{ + g_CurrentCmdBuf->Execute(LLGL_REF(CommandBuffer, deferredCommandBuffer)); +} + +LLGL_C_EXPORT void llglUpdateBuffer(LLGLBuffer dstBuffer, uint64_t dstOffset, const void* data, uint16_t dataSize) +{ + g_CurrentCmdBuf->UpdateBuffer(LLGL_REF(Buffer, dstBuffer), dstOffset, data, dataSize); +} + +LLGL_C_EXPORT void llglCopyBuffer(LLGLBuffer dstBuffer, uint64_t dstOffset, LLGLBuffer srcBuffer, uint64_t srcOffset, uint64_t size) +{ + g_CurrentCmdBuf->CopyBuffer(LLGL_REF(Buffer, dstBuffer), dstOffset, LLGL_REF(Buffer, srcBuffer), srcOffset, size); +} + +LLGL_C_EXPORT void llglCopyBufferFromTexture(LLGLBuffer dstBuffer, uint64_t dstOffset, LLGLTexture srcTexture, const LLGLTextureRegion* srcRegion, uint32_t rowStride, uint32_t layerStride) +{ + g_CurrentCmdBuf->CopyBufferFromTexture(LLGL_REF(Buffer, dstBuffer), dstOffset, LLGL_REF(Texture, srcTexture), *(const TextureRegion*)srcRegion, rowStride, layerStride); +} + +LLGL_C_EXPORT void llglFillBuffer(LLGLBuffer dstBuffer, uint64_t dstOffset, uint32_t value, uint64_t fillSize) +{ + g_CurrentCmdBuf->FillBuffer(LLGL_REF(Buffer, dstBuffer), dstOffset, value, fillSize); +} + +LLGL_C_EXPORT void llglCopyTexture(LLGLTexture dstTexture, const LLGLTextureLocation* dstLocation, LLGLTexture srcTexture, const LLGLTextureLocation* srcLocation, const LLGLExtent3D* extent) +{ + g_CurrentCmdBuf->CopyTexture(LLGL_REF(Texture, dstTexture), *(const TextureLocation*)dstLocation, LLGL_REF(Texture, srcTexture), *(const TextureLocation*)srcLocation, *(const Extent3D*)extent); +} + +LLGL_C_EXPORT void llglCopyTextureFromBuffer(LLGLTexture dstTexture, const LLGLTextureRegion* dstRegion, LLGLBuffer srcBuffer, uint64_t srcOffset, uint32_t rowStride, uint32_t layerStride) +{ + g_CurrentCmdBuf->CopyTextureFromBuffer(LLGL_REF(Texture, dstTexture), *(const TextureRegion*)dstRegion, LLGL_REF(Buffer, srcBuffer), srcOffset, rowStride, layerStride); +} + +LLGL_C_EXPORT void llglCopyTextureFromFramebuffer(LLGLTexture dstTexture, const LLGLTextureRegion* dstRegion, const LLGLOffset2D* srcOffset) +{ + g_CurrentCmdBuf->CopyTextureFromFramebuffer(LLGL_REF(Texture, dstTexture), *(const TextureRegion*)dstRegion, *(const Offset2D*)srcOffset); +} + +LLGL_C_EXPORT void llglGenerateMips(LLGLTexture texture) +{ + g_CurrentCmdBuf->GenerateMips(LLGL_REF(Texture, texture)); +} + +LLGL_C_EXPORT void llglGenerateMipsRange(LLGLTexture texture, const LLGLTextureSubresource* subresource) +{ + g_CurrentCmdBuf->GenerateMips(LLGL_REF(Texture, texture), *(const TextureSubresource*)subresource); +} + +LLGL_C_EXPORT void llglSetViewport(const LLGLViewport* viewport) +{ + g_CurrentCmdBuf->SetViewport(*(const Viewport*)viewport); +} + +LLGL_C_EXPORT void llglSetViewports(uint32_t numViewports, const LLGLViewport* viewports) +{ + g_CurrentCmdBuf->SetViewports(numViewports, (const Viewport*)viewports); +} + +LLGL_C_EXPORT void llglSetScissor(const LLGLScissor* scissor) +{ + g_CurrentCmdBuf->SetScissor(*(const Scissor*)scissor); +} + +LLGL_C_EXPORT void llglSetScissors(uint32_t numScissors, const LLGLScissor* scissors) +{ + g_CurrentCmdBuf->SetScissors(numScissors, (const Scissor*)scissors); +} + +LLGL_C_EXPORT void llglSetVertexBuffer(LLGLBuffer buffer) +{ + g_CurrentCmdBuf->SetVertexBuffer(LLGL_REF(Buffer, buffer)); +} + +LLGL_C_EXPORT void llglSetVertexBufferArray(LLGLBufferArray bufferArray) +{ + g_CurrentCmdBuf->SetVertexBufferArray(LLGL_REF(BufferArray, bufferArray)); +} + +LLGL_C_EXPORT void llglSetIndexBuffer(LLGLBuffer buffer) +{ + g_CurrentCmdBuf->SetIndexBuffer(LLGL_REF(Buffer, buffer)); +} + +LLGL_C_EXPORT void llglSetIndexBufferExt(LLGLBuffer buffer, LLGLFormat format, uint64_t offset) +{ + g_CurrentCmdBuf->SetIndexBuffer(LLGL_REF(Buffer, buffer), (Format)format, offset); +} + +LLGL_C_EXPORT void llglSetResourceHeap(LLGLResourceHeap resourceHeap, uint32_t descriptorSet) +{ + g_CurrentCmdBuf->SetResourceHeap(LLGL_REF(ResourceHeap, resourceHeap), descriptorSet); +} + +LLGL_C_EXPORT void llglSetResource(uint32_t descriptor, LLGLResource resource) +{ + g_CurrentCmdBuf->SetResource(descriptor, LLGL_REF(Resource, resource)); +} + +LLGL_C_EXPORT void llglResetResourceSlots(LLGLResourceType resourceType, uint32_t firstSlot, uint32_t numSlots, long bindFlags, long stageFlags) +{ + g_CurrentCmdBuf->ResetResourceSlots((ResourceType)resourceType, firstSlot, numSlots, bindFlags, stageFlags); +} + +LLGL_C_EXPORT void llglBeginRenderPass(LLGLRenderTarget renderTarget) +{ + g_CurrentCmdBuf->BeginRenderPass(LLGL_REF(RenderTarget, renderTarget)); +} + +LLGL_C_EXPORT void llglBeginRenderPassWithClear(LLGLRenderTarget renderTarget, LLGLRenderPass renderPass, uint32_t numClearValues, const LLGLClearValue* clearValues, uint32_t swapBufferIndex) +{ + g_CurrentCmdBuf->BeginRenderPass(LLGL_REF(RenderTarget, renderTarget), LLGL_PTR(RenderPass, renderPass), numClearValues, (const ClearValue*)clearValues, swapBufferIndex); +} + +LLGL_C_EXPORT void llglEndRenderPass() +{ + g_CurrentCmdBuf->EndRenderPass(); +} + +LLGL_C_EXPORT void llglClear(long flags, const LLGLClearValue* clearValue) +{ + g_CurrentCmdBuf->Clear(flags, *(const ClearValue*)clearValue); +} + +LLGL_C_EXPORT void llglClearAttachments(uint32_t numAttachments, const LLGLAttachmentClear* attachments) +{ + g_CurrentCmdBuf->ClearAttachments(numAttachments, (const AttachmentClear*)attachments); +} + +LLGL_C_EXPORT void llglSetPipelineState(LLGLPipelineState pipelineState) +{ + g_CurrentCmdBuf->SetPipelineState(LLGL_REF(PipelineState, pipelineState)); +} + +LLGL_C_EXPORT void llglSetBlendFactor(const float color[4]) +{ + g_CurrentCmdBuf->SetBlendFactor(color); +} + +LLGL_C_EXPORT void llglSetStencilReference(uint32_t reference, LLGLStencilFace stencilFace) +{ + g_CurrentCmdBuf->SetStencilReference(reference, (StencilFace)stencilFace); +} + +LLGL_C_EXPORT void llglSetUniforms(uint32_t first, const void* data, uint16_t dataSize) +{ + g_CurrentCmdBuf->SetUniforms(first, data, dataSize); +} + +LLGL_C_EXPORT void llglBeginQuery(LLGLQueryHeap queryHeap, uint32_t query) +{ + g_CurrentCmdBuf->BeginQuery(LLGL_REF(QueryHeap, queryHeap), query); +} + +LLGL_C_EXPORT void llglEndQuery(LLGLQueryHeap queryHeap, uint32_t query) +{ + g_CurrentCmdBuf->EndQuery(LLGL_REF(QueryHeap, queryHeap), query); +} + +LLGL_C_EXPORT void llglBeginRenderCondition(LLGLQueryHeap queryHeap, uint32_t query, LLGLRenderConditionMode mode) +{ + g_CurrentCmdBuf->BeginRenderCondition(LLGL_REF(QueryHeap, queryHeap), query, (RenderConditionMode)mode); +} + +LLGL_C_EXPORT void llglEndRenderCondition() +{ + g_CurrentCmdBuf->EndRenderCondition(); +} + +LLGL_C_EXPORT void llglBeginStreamOutput(uint32_t numBuffers, LLGLBuffer const * buffers) +{ + Buffer* internalBuffers[LLGL_MAX_NUM_SO_BUFFERS]; + for_range(i, numBuffers) + internalBuffers[i] = LLGL_PTR(Buffer, buffers[i]); + g_CurrentCmdBuf->BeginStreamOutput(numBuffers, internalBuffers); +} + +LLGL_C_EXPORT void llglEndStreamOutput() +{ + g_CurrentCmdBuf->EndStreamOutput(); +} + +LLGL_C_EXPORT void llglDraw(uint32_t numVertices, uint32_t firstVertex) +{ + g_CurrentCmdBuf->Draw(numVertices, firstVertex); +} + +LLGL_C_EXPORT void llglDrawIndexed(uint32_t numIndices, uint32_t firstIndex) +{ + g_CurrentCmdBuf->DrawIndexed(numIndices, firstIndex); +} + +LLGL_C_EXPORT void llglDrawIndexedExt(uint32_t numIndices, uint32_t firstIndex, int32_t vertexOffset) +{ + g_CurrentCmdBuf->DrawIndexed(numIndices, firstIndex, vertexOffset); +} + +LLGL_C_EXPORT void llglDrawInstanced(uint32_t numVertices, uint32_t firstVertex, uint32_t numInstances) +{ + g_CurrentCmdBuf->DrawInstanced(numVertices, firstVertex, numInstances); +} + +LLGL_C_EXPORT void llglDrawInstancedExt(uint32_t numVertices, uint32_t firstVertex, uint32_t numInstances, uint32_t firstInstance) +{ + g_CurrentCmdBuf->DrawInstanced(numVertices, firstVertex, numInstances, firstInstance); +} + +LLGL_C_EXPORT void llglDrawIndexedInstanced(uint32_t numIndices, uint32_t numInstances, uint32_t firstIndex) +{ + g_CurrentCmdBuf->DrawIndexedInstanced(numIndices, numInstances, firstIndex); +} + +LLGL_C_EXPORT void llglDrawIndexedInstancedExt(uint32_t numIndices, uint32_t numInstances, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) +{ + g_CurrentCmdBuf->DrawIndexedInstanced(numIndices, numInstances, firstIndex, vertexOffset, firstInstance); +} + +LLGL_C_EXPORT void llglDrawIndirect(LLGLBuffer buffer, uint64_t offset) +{ + g_CurrentCmdBuf->DrawIndirect(LLGL_REF(Buffer, buffer), offset); +} + +LLGL_C_EXPORT void llglDrawIndirectExt(LLGLBuffer buffer, uint64_t offset, uint32_t numCommands, uint32_t stride) +{ + g_CurrentCmdBuf->DrawIndirect(LLGL_REF(Buffer, buffer), offset, numCommands, stride); +} + +LLGL_C_EXPORT void llglDrawIndexedIndirect(LLGLBuffer buffer, uint64_t offset) +{ + g_CurrentCmdBuf->DrawIndexedIndirect(LLGL_REF(Buffer, buffer), offset); +} + +LLGL_C_EXPORT void llglDrawIndexedIndirectExt(LLGLBuffer buffer, uint64_t offset, uint32_t numCommands, uint32_t stride) +{ + g_CurrentCmdBuf->DrawIndexedIndirect(LLGL_REF(Buffer, buffer), offset, numCommands, stride); +} + +LLGL_C_EXPORT void llglDispatch(uint32_t numWorkGroupsX, uint32_t numWorkGroupsY, uint32_t numWorkGroupsZ) +{ + g_CurrentCmdBuf->Dispatch(numWorkGroupsX, numWorkGroupsY, numWorkGroupsZ); +} + +LLGL_C_EXPORT void llglDispatchIndirect(LLGLBuffer buffer, uint64_t offset) +{ + g_CurrentCmdBuf->DispatchIndirect(LLGL_REF(Buffer, buffer), offset); +} + +LLGL_C_EXPORT void llglPushDebugGroup(const char* name) +{ + g_CurrentCmdBuf->PushDebugGroup(name); +} + +LLGL_C_EXPORT void llglPopDebugGroup() +{ + g_CurrentCmdBuf->PopDebugGroup(); +} + +LLGL_C_EXPORT void llglDoNativeCommand(const void* nativeCommand, size_t nativeCommandSize) +{ + g_CurrentCmdBuf->DoNativeCommand(nativeCommand, nativeCommandSize); +} + +LLGL_C_EXPORT bool llglGetNativeHandle(void* nativeHandle, size_t nativeHandleSize) +{ + return g_CurrentCmdBuf->GetNativeHandle(nativeHandle, nativeHandleSize); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99CommandQueue.cpp b/wrapper/C99/C99CommandQueue.cpp new file mode 100644 index 0000000000..811b85bbe4 --- /dev/null +++ b/wrapper/C99/C99CommandQueue.cpp @@ -0,0 +1,52 @@ +/* + * C99CommandQueue.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" +#include "../../../sources/Core/Assertion.h" + + +// namespace LLGL { + + +using namespace LLGL; + +CommandQueue* g_CurrentCmdQueue = NULL; + + +LLGL_C_EXPORT void llglSubmitCommandBuffer(LLGLCommandBuffer commandBuffer) +{ + g_CurrentCmdQueue->Submit(LLGL_REF(CommandBuffer, commandBuffer)); +} + +LLGL_C_EXPORT bool llglQueryResult(LLGLQueryHeap queryHeap, uint32_t firstQuery, uint32_t numQueries, void* data, size_t dataSize) +{ + return g_CurrentCmdQueue->QueryResult(LLGL_REF(QueryHeap, queryHeap), firstQuery, numQueries, data, dataSize); +} + +LLGL_C_EXPORT void llglSubmitFence(LLGLFence fence) +{ + g_CurrentCmdQueue->Submit(LLGL_REF(Fence, fence)); +} + +LLGL_C_EXPORT bool llglWaitFence(LLGLFence fence, uint64_t timeout) +{ + return g_CurrentCmdQueue->WaitFence(LLGL_REF(Fence, fence), timeout); +} + +LLGL_C_EXPORT void llglWaitIdle() +{ + g_CurrentCmdQueue->WaitIdle(); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99Display.cpp b/wrapper/C99/C99Display.cpp new file mode 100644 index 0000000000..0754701de5 --- /dev/null +++ b/wrapper/C99/C99Display.cpp @@ -0,0 +1,121 @@ +/* + * C99Display.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" +#include "../sources/Core/CoreUtils.h" +#include + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT size_t llglDisplayCount() +{ + return Display::Count(); +} + +LLGL_C_EXPORT LLGLDisplay const * llglGetDisplayList() +{ + return reinterpret_cast(Display::GetList()); +} + +LLGL_C_EXPORT LLGLDisplay llglGetDisplay(size_t index) +{ + return LLGLDisplay{ Display::Get(index) }; +} + +LLGL_C_EXPORT LLGLDisplay llglGetPrimaryDisplay() +{ + return LLGLDisplay{ Display::GetPrimary() }; +} + +LLGL_C_EXPORT bool llglShowCursor(bool show) +{ + return Display::ShowCursor(show); +} + +LLGL_C_EXPORT bool llglIsCursorShown() +{ + return Display::IsCursorShown(); +} + +LLGL_C_EXPORT bool llglSetCursorPosition(const LLGLOffset2D* position) +{ + return Display::SetCursorPosition(*reinterpret_cast(position)); +} + +LLGL_C_EXPORT void llglGetCursorPosition(LLGLOffset2D* outPosition) +{ + LLGL_ASSERT_PTR(outPosition); + Offset2D internalPosition = Display::GetCursorPosition(); + outPosition->x = internalPosition.x; + outPosition->y = internalPosition.y; +} + +LLGL_C_EXPORT bool llglIsDisplayPrimary(LLGLDisplay display) +{ + return LLGL_PTR(Display, display)->IsPrimary(); +} + +LLGL_C_EXPORT size_t llglGetDisplayDeviceName(LLGLDisplay display, size_t outNameLength, wchar_t* outName) +{ + UTF8String title = LLGL_PTR(Display, display)->GetDeviceName(); + SmallVector titleUTF16 = title.to_utf16(); + if (outName != nullptr) + { + outNameLength = std::min(outNameLength, titleUTF16.size()); + ::memcpy(outName, titleUTF16.data(), outNameLength * sizeof(wchar_t)); + } + return titleUTF16.size(); +} + +LLGL_C_EXPORT void llglGetDisplayOffset(LLGLDisplay display, LLGLOffset2D* outOffset) +{ + LLGL_ASSERT_PTR(outOffset); + Offset2D internalOffset = LLGL_PTR(Display, display)->GetOffset(); + outOffset->x = internalOffset.x; + outOffset->y = internalOffset.y; +} + +LLGL_C_EXPORT bool llglResetDisplayMode(LLGLDisplay display) +{ + return LLGL_PTR(Display, display)->ResetDisplayMode(); +} + +LLGL_C_EXPORT bool llglSetDisplayMode(LLGLDisplay display, const LLGLDisplayModeDescriptor* displayModeDesc) +{ + return LLGL_PTR(Display, display)->SetDisplayMode(*reinterpret_cast(displayModeDesc)); +} + +LLGL_C_EXPORT void llglGetDisplayMode(LLGLDisplay display, LLGLDisplayModeDescriptor* outDisplayModeDesc) +{ + LLGL_ASSERT_PTR(outDisplayModeDesc); + DisplayModeDescriptor internalDisplayModeDesc = LLGL_PTR(Display, display)->GetDisplayMode(); + ::memcpy(outDisplayModeDesc, &internalDisplayModeDesc, sizeof(LLGLDisplayModeDescriptor)); +} + +LLGL_C_EXPORT size_t llglGetSupportedDisplayModes(LLGLDisplay display, size_t maxNumDisplayModes, LLGLDisplayModeDescriptor* outDisplayModes) +{ + std::vector internalDisplayModes = LLGL_PTR(Display, display)->GetSupportedDisplayModes(); + if (outDisplayModes != nullptr) + { + maxNumDisplayModes = std::min(maxNumDisplayModes, internalDisplayModes.size()); + ::memcpy(outDisplayModes, internalDisplayModes.data(), sizeof(LLGLDisplayModeDescriptor) * maxNumDisplayModes); + } + return internalDisplayModes.size(); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99FlagsAndDescriptors.cpp b/wrapper/C99/C99FlagsAndDescriptors.cpp new file mode 100644 index 0000000000..b89db8cdd7 --- /dev/null +++ b/wrapper/C99/C99FlagsAndDescriptors.cpp @@ -0,0 +1,27 @@ +/* + * C99FlagsAndDescriptors.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT const LLGLFormatAttributes* llglGetFormatAttribs(LLGLFormat format) +{ + return (const LLGLFormatAttributes*)(&GetFormatAttribs((Format)format)); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99Internal.h b/wrapper/C99/C99Internal.h new file mode 100644 index 0000000000..22d5abd3fb --- /dev/null +++ b/wrapper/C99/C99Internal.h @@ -0,0 +1,26 @@ +/* + * C99Internal.h + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#ifndef LLGL_C99_INTERNAL_H +#define LLGL_C99_INTERNAL_H + + +#include "../../sources/Core/Assertion.h" + + +#define LLGL_PTR(TYPE, OBJ) \ + ((TYPE*)((OBJ).internal)) + +#define LLGL_REF(TYPE, OBJ) \ + (*((TYPE*)((OBJ).internal))) + + +#endif + + + +// ================================================================================ diff --git a/wrapper/C99/C99Log.cpp b/wrapper/C99/C99Log.cpp new file mode 100644 index 0000000000..380600d399 --- /dev/null +++ b/wrapper/C99/C99Log.cpp @@ -0,0 +1,65 @@ +/* + * C99Log.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" +#include "../../sources/Core/StringUtils.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT void llglLogPrintf(const char* format, ...) +{ + std::string text; + LLGL_STRING_PRINTF(text, format); + Log::Printf("%s", text.c_str()); +} + +LLGL_C_EXPORT void llglLogErrorf(const char* format, ...) +{ + std::string text; + LLGL_STRING_PRINTF(text, format); + Log::Errorf("%s", text.c_str()); +} + +LLGL_C_EXPORT LLGLLogHandle llglRegisterLogCallback(LLGL_PFN_ReportCallback callback, void* LLGL_NULLABLE(userData)) +{ + LLGL_ASSERT_PTR(callback); + return Log::RegisterCallback( + [callback](Log::ReportType type, const char* text, void* userData) -> void + { + callback(static_cast(type), text, userData); + }, + userData + ); +} + +LLGL_C_EXPORT LLGLLogHandle llglRegisterLogCallbackReport(LLGLReport report) +{ + return Log::RegisterCallbackReport(LLGL_REF(Report, report)); +} + +LLGL_C_EXPORT LLGLLogHandle llglRegisterLogCallbackStd() +{ + return Log::RegisterCallbackStd(); +} + +LLGL_C_EXPORT void llglUnregisterLogCallback(LLGLLogHandle handle) +{ + Log::UnregisterCallback(handle); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99PipelineLayout.cpp b/wrapper/C99/C99PipelineLayout.cpp new file mode 100644 index 0000000000..6b1645d04b --- /dev/null +++ b/wrapper/C99/C99PipelineLayout.cpp @@ -0,0 +1,43 @@ +/* + * C99PipelineLayout.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT uint32_t llglGetPipelineLayoutNumHeapBindings(LLGLPipelineLayout pipelineLayout) +{ + return LLGL_PTR(PipelineLayout, pipelineLayout)->GetNumHeapBindings(); +} + +LLGL_C_EXPORT uint32_t llglGetPipelineLayoutNumBindings(LLGLPipelineLayout pipelineLayout) +{ + return LLGL_PTR(PipelineLayout, pipelineLayout)->GetNumBindings(); +} + +LLGL_C_EXPORT uint32_t llglGetPipelineLayoutNumStaticSamplers(LLGLPipelineLayout pipelineLayout) +{ + return LLGL_PTR(PipelineLayout, pipelineLayout)->GetNumStaticSamplers(); +} + +LLGL_C_EXPORT uint32_t llglGetPipelineLayoutNumUniforms(LLGLPipelineLayout pipelineLayout) +{ + return LLGL_PTR(PipelineLayout, pipelineLayout)->GetNumUniforms(); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99PipelineState.cpp b/wrapper/C99/C99PipelineState.cpp new file mode 100644 index 0000000000..f95fae76a1 --- /dev/null +++ b/wrapper/C99/C99PipelineState.cpp @@ -0,0 +1,28 @@ +/* + * C99PipelineState.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT LLGLReport llglGetPipelineStateReport(LLGLPipelineState pipelineState) +{ + return LLGLReport{ LLGL_PTR(PipelineState, pipelineState)->GetReport() }; +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99QueryHeap.cpp b/wrapper/C99/C99QueryHeap.cpp new file mode 100644 index 0000000000..6ce7b2f134 --- /dev/null +++ b/wrapper/C99/C99QueryHeap.cpp @@ -0,0 +1,28 @@ +/* + * C99QueryHeap.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT LLGLQueryType llglGetQueryHeapType(LLGLQueryHeap queryHeap) +{ + return static_cast(LLGL_PTR(QueryHeap, queryHeap)->GetType()); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99RenderSystem.cpp b/wrapper/C99/C99RenderSystem.cpp new file mode 100644 index 0000000000..f2ef6f7618 --- /dev/null +++ b/wrapper/C99/C99RenderSystem.cpp @@ -0,0 +1,606 @@ +/* + * C99RenderSystem.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include +#include "C99Internal.h" +#include +#include +#include + + +// namespace LLGL { + + +using namespace LLGL; + +extern CommandQueue* g_CurrentCmdQueue; + +static int gl_CurrentRenderSystemID = 0; +static RenderSystem* g_CurrentRenderSystem = NULL; +static std::vector g_RenderSystems; + +#define LLGL_ASSERT_RENDER_SYSTEM() \ + LLGL_ASSERT_PTR(g_CurrentRenderSystem) + +#define LLGL_RELEASE(TYPE, OBJ) \ + { \ + LLGL_ASSERT_RENDER_SYSTEM(); \ + LLGL_ASSERT_PTR(LLGL_PTR(TYPE, OBJ)); \ + g_CurrentRenderSystem->Release(LLGL_REF(TYPE, OBJ)); \ + } + +LLGL_C_EXPORT int llglLoadRenderSystem(const char* moduleName) +{ + LLGLRenderSystemDescriptor desc = {}; + { + desc.moduleName = moduleName; + } + return llglLoadRenderSystemExt(&desc, LLGL_NULL_OBJECT); +} + +static void ConvertRenderSystemDesc(RenderSystemDescriptor& dst, const LLGLRenderSystemDescriptor& src) +{ + dst.moduleName = src.moduleName; + dst.flags = src.flags; + //dst.profiler = src.profiler; + //dst.debugger = src.debugger; + dst.rendererConfig = src.rendererConfig; + dst.rendererConfigSize = src.rendererConfigSize; + #ifdef LLGL_OS_ANDROID + dst.androidApp = src.androidApp; + #endif +} + +LLGL_C_EXPORT int llglLoadRenderSystemExt(const LLGLRenderSystemDescriptor* renderSystemDesc, LLGLReport report) +{ + LLGL_ASSERT_PTR(renderSystemDesc); + RenderSystemDescriptor internalDesc; + ConvertRenderSystemDesc(internalDesc, *renderSystemDesc); + + if (RenderSystemPtr renderSystem = RenderSystem::Load(internalDesc, LLGL_PTR(Report, report))) + { + size_t renderSystemIndex = g_RenderSystems.size(); + g_RenderSystems.push_back(std::move(renderSystem)); + + int renderSystemID = (int)(renderSystemIndex + 1); + llglMakeRenderSystemCurrent(renderSystemID); + + return renderSystemID; + } + + return 0; +} + +LLGL_C_EXPORT void llglUnloadRenderSystem() +{ + if (gl_CurrentRenderSystemID != 0) + { + size_t renderSystemIndex = (size_t)(gl_CurrentRenderSystemID - 1); + RenderSystem::Unload(std::move(g_RenderSystems[renderSystemIndex])); + g_RenderSystems.erase(g_RenderSystems.begin() + renderSystemIndex); + llglMakeRenderSystemCurrent(0); + } +} + +LLGL_C_EXPORT void llglMakeRenderSystemCurrent(int id) +{ + if (gl_CurrentRenderSystemID != id) + { + if (id > 0) + { + size_t renderSystemIndex = (size_t)(id - 1); + gl_CurrentRenderSystemID = id; + g_CurrentRenderSystem = g_RenderSystems[renderSystemIndex].get(); + g_CurrentCmdQueue = g_CurrentRenderSystem->GetCommandQueue(); + } + else + { + gl_CurrentRenderSystemID = 0; + g_CurrentRenderSystem = NULL; + g_CurrentCmdQueue = NULL; + } + } +} + +LLGL_C_EXPORT int llglGetRendererID() +{ + LLGL_ASSERT_RENDER_SYSTEM(); + return g_CurrentRenderSystem->GetRendererID(); +} + +LLGL_C_EXPORT const char* llglGetRendererName() +{ + LLGL_ASSERT_RENDER_SYSTEM(); + return g_CurrentRenderSystem->GetName(); +} + +struct RendererInfoC99Wrapper +{ + std::vector extensionNames; +}; + +static void ConvertRendererInfo(RendererInfoC99Wrapper& wrapper, LLGLRendererInfo& dst, const RendererInfo& src) +{ + wrapper.extensionNames.resize(src.extensionNames.size()); + for_range(i, src.extensionNames.size()) + wrapper.extensionNames[i] = src.extensionNames[i].c_str(); + + dst.rendererName = src.rendererName.c_str(); + dst.deviceName = src.deviceName.c_str(); + dst.vendorName = src.vendorName.c_str(); + dst.shadingLanguageName = src.shadingLanguageName.c_str(); + dst.numExtensionNames = wrapper.extensionNames.size(); + dst.extensionNames = wrapper.extensionNames.data(); +} + +LLGL_C_EXPORT void llglGetRendererInfo(LLGLRendererInfo* outInfo) +{ + static RendererInfoC99Wrapper wrapper; + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(outInfo); + ConvertRendererInfo(wrapper, *outInfo, g_CurrentRenderSystem->GetRendererInfo()); +} + +struct RenderingCapabilitiesC99Wrapper +{ + std::vector shadingLanguages; + std::vector textureFormats; +}; + +static void ConvertRenderingCaps(RenderingCapabilitiesC99Wrapper& wrapper, LLGLRenderingCapabilities& dst, const RenderingCapabilities& src) +{ + wrapper.shadingLanguages.resize(src.shadingLanguages.size()); + ::memcpy(wrapper.shadingLanguages.data(), src.shadingLanguages.data(), sizeof(LLGLShadingLanguage) * src.shadingLanguages.size()); + + wrapper.textureFormats.resize(src.textureFormats.size()); + ::memcpy(wrapper.textureFormats.data(), src.textureFormats.data(), sizeof(LLGLFormat) * src.textureFormats.size()); + + dst.screenOrigin = static_cast(src.screenOrigin); + dst.clippingRange = static_cast(src.clippingRange); + dst.numShadingLanguages = wrapper.shadingLanguages.size(); + dst.shadingLanguages = wrapper.shadingLanguages.data(); + dst.numTextureFormats = wrapper.textureFormats.size(); + dst.textureFormats = wrapper.textureFormats.data(); + ::memcpy(&(dst.features), &(src.features), sizeof(LLGLRenderingFeatures)); + ::memcpy(&(dst.limits), &(src.limits), sizeof(LLGLRenderingLimits)); +} + +LLGL_C_EXPORT void llglGetRenderingCaps(LLGLRenderingCapabilities* outCaps) +{ + static RenderingCapabilitiesC99Wrapper wrapper; + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(outCaps); + ConvertRenderingCaps(wrapper, *outCaps, g_CurrentRenderSystem->GetRenderingCaps()); +} + +LLGL_C_EXPORT LLGLReport llglGetRendererReport() +{ + LLGL_ASSERT_RENDER_SYSTEM(); + return LLGLReport{ g_CurrentRenderSystem->GetReport() }; +} + +LLGL_C_EXPORT LLGLSwapChain llglCreateSwapChain(const LLGLSwapChainDescriptor* swapChainDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(swapChainDesc); + return LLGLSwapChain{ g_CurrentRenderSystem->CreateSwapChain(*reinterpret_cast(swapChainDesc)) }; +} + +LLGL_C_EXPORT LLGLSwapChain llglCreateSwapChainExt(const LLGLSwapChainDescriptor* swapChainDesc, LLGLSurface surface) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(swapChainDesc); + return LLGL_NULL_OBJECT; //todo +} + +LLGL_C_EXPORT void llglReleaseSwapChain(LLGLSwapChain swapChain) +{ + LLGL_RELEASE(SwapChain, swapChain); +} + +LLGL_C_EXPORT LLGLCommandBuffer llglCreateCommandBuffer(const LLGLCommandBufferDescriptor* commandBufferDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(commandBufferDesc); + return LLGLCommandBuffer{ g_CurrentRenderSystem->CreateCommandBuffer(*reinterpret_cast(commandBufferDesc)) }; +} + +LLGL_C_EXPORT void llglReleaseCommandBuffer(LLGLCommandBuffer commandBuffer) +{ + LLGL_RELEASE(CommandBuffer, commandBuffer); +} + +static void ConvertVertexAttrib(VertexAttribute& dst, const LLGLVertexAttribute& src) +{ + dst.name = src.name; + dst.format = static_cast(src.format); + dst.location = src.location; + dst.semanticIndex = src.semanticIndex; + dst.systemValue = static_cast(src.systemValue); + dst.slot = src.slot; + dst.offset = src.offset; + dst.stride = src.stride; + dst.instanceDivisor = src.instanceDivisor; +} + +static void ConvertBufferDesc(BufferDescriptor& dst, SmallVector& dstVertexAttribs, const LLGLBufferDescriptor& src) +{ + dstVertexAttribs.resize(src.numVertexAttribs); + for_range(i, src.numVertexAttribs) + ConvertVertexAttrib(dstVertexAttribs[i], src.vertexAttribs[i]); + + dst.size = src.size; + dst.stride = src.stride; + dst.format = (Format)src.format; + dst.bindFlags = src.bindFlags; + dst.cpuAccessFlags = src.cpuAccessFlags; + dst.miscFlags = src.miscFlags; + dst.vertexAttribs = dstVertexAttribs; +} + +LLGL_C_EXPORT LLGLBuffer llglCreateBuffer(const LLGLBufferDescriptor* bufferDesc, const void* initialData) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(bufferDesc); + BufferDescriptor internalBufferDesc; + SmallVector internalVertexAttribs; + ConvertBufferDesc(internalBufferDesc, internalVertexAttribs, *bufferDesc); + return LLGLBuffer{ g_CurrentRenderSystem->CreateBuffer(internalBufferDesc, initialData) }; +} + +LLGL_C_EXPORT void llglReleaseBuffer(LLGLBuffer buffer) +{ + LLGL_RELEASE(Buffer, buffer); +} + +LLGL_C_EXPORT void llglWriteBuffer(LLGLBuffer buffer, uint64_t offset, const void* data, uint64_t dataSize) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + g_CurrentRenderSystem->WriteBuffer(LLGL_REF(Buffer, buffer), offset, data, dataSize); +} + +LLGL_C_EXPORT void llglReadBuffer(LLGLBuffer buffer, uint64_t offset, void* data, uint64_t dataSize) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + g_CurrentRenderSystem->ReadBuffer(LLGL_REF(Buffer, buffer), offset, data, dataSize); +} + +LLGL_C_EXPORT void* llglMapBuffer(LLGLBuffer buffer, LLGLCPUAccess access) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + return g_CurrentRenderSystem->MapBuffer(LLGL_REF(Buffer, buffer), (CPUAccess)access); +} + +LLGL_C_EXPORT void* llglMapBufferRange(LLGLBuffer buffer, LLGLCPUAccess access, uint64_t offset, uint64_t length) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + return g_CurrentRenderSystem->MapBuffer(LLGL_REF(Buffer, buffer), (CPUAccess)access, offset, length); +} + +LLGL_C_EXPORT void llglUnmapBuffer(LLGLBuffer buffer) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + g_CurrentRenderSystem->UnmapBuffer(LLGL_REF(Buffer, buffer)); +} + +LLGL_C_EXPORT LLGLBufferArray CreateBufferArray(uint32_t numBuffers, const LLGLBuffer* buffers) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(buffers); + return LLGLBufferArray{ g_CurrentRenderSystem->CreateBufferArray(numBuffers, reinterpret_cast(buffers)) }; +} + +LLGL_C_EXPORT void llglReleaseBufferArray(LLGLBufferArray bufferArray) +{ + LLGL_RELEASE(BufferArray, bufferArray); +} + +LLGL_C_EXPORT LLGLTexture llglCreateTexture(const LLGLTextureDescriptor* textureDesc, const LLGLSrcImageDescriptor* imageDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(textureDesc); + return LLGLTexture{ g_CurrentRenderSystem->CreateTexture(*reinterpret_cast(textureDesc), reinterpret_cast(imageDesc)) }; +} + +LLGL_C_EXPORT void llglReleaseTexture(LLGLTexture texture) +{ + LLGL_RELEASE(Texture, texture); +} + +LLGL_C_EXPORT void llglWriteTexture(LLGLTexture texture, const LLGLTextureRegion* textureRegion, const LLGLSrcImageDescriptor* imageDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(textureRegion); + LLGL_ASSERT_PTR(imageDesc); + g_CurrentRenderSystem->WriteTexture(LLGL_REF(Texture, texture), *reinterpret_cast(textureRegion), *reinterpret_cast(imageDesc)); +} + +LLGL_C_EXPORT void llglReadTexture(LLGLTexture texture, const LLGLTextureRegion* textureRegion, const LLGLDstImageDescriptor* imageDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(textureRegion); + LLGL_ASSERT_PTR(imageDesc); + g_CurrentRenderSystem->ReadTexture(LLGL_REF(Texture, texture), *reinterpret_cast(textureRegion), *reinterpret_cast(imageDesc)); +} + +LLGL_C_EXPORT LLGLSampler llglCreateSampler(const LLGLSamplerDescriptor* samplerDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(samplerDesc); + return LLGLSampler{ g_CurrentRenderSystem->CreateSampler(*reinterpret_cast(samplerDesc)) }; +} + +LLGL_C_EXPORT void llglReleaseSampler(LLGLSampler sampler) +{ + LLGL_RELEASE(Sampler, sampler); +} + +LLGL_C_EXPORT LLGLResourceHeap llglCreateResourceHeap(const LLGLResourceHeapDescriptor* resourceHeapDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(resourceHeapDesc); + return LLGLResourceHeap{ g_CurrentRenderSystem->CreateResourceHeap(*reinterpret_cast(resourceHeapDesc)) }; +} + +LLGL_C_EXPORT LLGLResourceHeap llglCreateResourceHeapExt(const LLGLResourceHeapDescriptor* resourceHeapDesc, size_t numInitialResourceViews, const LLGLResourceViewDescriptor* initialResourceViews) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(resourceHeapDesc); + const ArrayView internalInitialResourceViews{ reinterpret_cast(initialResourceViews), numInitialResourceViews }; + return LLGLResourceHeap{ g_CurrentRenderSystem->CreateResourceHeap(*reinterpret_cast(resourceHeapDesc), internalInitialResourceViews) }; +} + +LLGL_C_EXPORT void llglReleaseResourceHeap(LLGLResourceHeap resourceHeap) +{ + LLGL_RELEASE(ResourceHeap, resourceHeap); +} + +LLGL_C_EXPORT uint32_t llglWriteResourceHeap(LLGLResourceHeap resourceHeap, uint32_t firstDescriptor, size_t numResourceViews, const LLGLResourceViewDescriptor* resourceViews) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + if (numResourceViews > 0) + { + LLGL_ASSERT_PTR(resourceViews); + const ArrayView internalResourceViews{ reinterpret_cast(resourceViews), numResourceViews }; + return g_CurrentRenderSystem->WriteResourceHeap(LLGL_REF(ResourceHeap, resourceHeap), firstDescriptor, internalResourceViews); + } + return 0; +} + +LLGL_C_EXPORT LLGLRenderPass llglCreateRenderPass(const LLGLRenderPassDescriptor* renderPassDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(renderPassDesc); + return LLGLRenderPass{ g_CurrentRenderSystem->CreateRenderPass(*reinterpret_cast(renderPassDesc)) }; +} + +LLGL_C_EXPORT void llglReleaseRenderPass(LLGLRenderPass renderPass) +{ + LLGL_RELEASE(RenderPass, renderPass); +} + +LLGL_C_EXPORT LLGLRenderTarget llglCreateRenderTarget(const LLGLRenderTargetDescriptor* renderTargetDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(renderTargetDesc); + return LLGLRenderTarget{ g_CurrentRenderSystem->CreateRenderTarget(*reinterpret_cast(renderTargetDesc)) }; +} + +LLGL_C_EXPORT void llglReleaseRenderTarget(LLGLRenderTarget renderTarget) +{ + LLGL_RELEASE(RenderTarget, renderTarget); +} + +static void ConvertVertexShaderAttribs(VertexShaderAttributes& dst, const LLGLVertexShaderAttributes& src) +{ + dst.inputAttribs.resize(src.numInputAttribs); + for_range(i, src.numInputAttribs) + ConvertVertexAttrib(dst.inputAttribs[i], src.inputAttribs[i]); + + dst.outputAttribs.resize(src.numOutputAttribs); + for_range(i, src.numOutputAttribs) + ConvertVertexAttrib(dst.outputAttribs[i], src.outputAttribs[i]); +} + +static void ConvertFragmentAttrib(FragmentAttribute& dst, const LLGLFragmentAttribute& src) +{ + dst.name = src.name; + dst.format = static_cast(src.format); + dst.location = src.location; + dst.systemValue = static_cast(src.systemValue); +} + +static void ConvertFragmentShaderAttribs(FragmentShaderAttributes& dst, const LLGLFragmentShaderAttributes& src) +{ + dst.outputAttribs.resize(src.numOutputAttribs); + for_range(i, src.numOutputAttribs) + ConvertFragmentAttrib(dst.outputAttribs[i], src.outputAttribs[i]); +} + +static void ConvertComputeShaderAttribs(ComputeShaderAttributes& dst, const LLGLComputeShaderAttributes& src) +{ + dst.workGroupSize = *(const Extent3D*)(&(src.workGroupSize)); +} + +static void ConvertShaderDesc(ShaderDescriptor& dst, const LLGLShaderDescriptor& src) +{ + dst.type = static_cast(src.type); + dst.source = src.source; + dst.sourceSize = src.sourceSize; + dst.sourceType = static_cast(src.sourceType); + dst.entryPoint = src.entryPoint; + dst.profile = src.profile; + dst.defines = reinterpret_cast(src.defines); + dst.flags = src.flags; + + ConvertVertexShaderAttribs(dst.vertex, src.vertex); + ConvertFragmentShaderAttribs(dst.fragment, src.fragment); + ConvertComputeShaderAttribs(dst.compute, src.compute); +} + +LLGL_C_EXPORT LLGLShader llglCreateShader(const LLGLShaderDescriptor* shaderDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(shaderDesc); + ShaderDescriptor internalShaderDesc; + ConvertShaderDesc(internalShaderDesc, *shaderDesc); + return LLGLShader{ g_CurrentRenderSystem->CreateShader(internalShaderDesc) }; +} + +LLGL_C_EXPORT void llglReleaseShader(LLGLShader shader) +{ + LLGL_RELEASE(Shader, shader); +} + +static void ConvertBindingDesc(BindingDescriptor& dst, const LLGLBindingDescriptor& src) +{ + dst.name = src.name; + dst.type = static_cast(src.type); + dst.bindFlags = src.bindFlags; + dst.stageFlags = src.stageFlags; + dst.slot = { src.slot.index, src.slot.set }; + dst.arraySize = src.arraySize; +} + +static void ConvertStaticSamplerDesc(StaticSamplerDescriptor& dst, const LLGLStaticSamplerDescriptor& src) +{ + dst.name = src.name; + dst.stageFlags = src.stageFlags; + dst.slot = { src.slot.index, src.slot.set }; + memcpy(&(dst.sampler), &(src.sampler), sizeof(LLGLSamplerDescriptor)); +} + +static void ConvertUniformDesc(UniformDescriptor& dst, const LLGLUniformDescriptor& src) +{ + dst.name = src.name; + dst.type = static_cast(src.type); + dst.arraySize = src.arraySize; +} + +static void ConvertPipelineLayoutDesc(PipelineLayoutDescriptor& dst, const LLGLPipelineLayoutDescriptor& src) +{ + dst.heapBindings.resize(src.numHeapBindings); + for_range(i, src.numHeapBindings) + ConvertBindingDesc(dst.heapBindings[i], src.heapBindings[i]); + + dst.bindings.resize(src.numBindings); + for_range(i, src.numBindings) + ConvertBindingDesc(dst.bindings[i], src.bindings[i]); + + dst.staticSamplers.resize(src.numStaticSamplers); + for_range(i, src.numStaticSamplers) + ConvertStaticSamplerDesc(dst.staticSamplers[i], src.staticSamplers[i]); + + dst.uniforms.resize(src.numUniforms); + for_range(i, src.numUniforms) + ConvertUniformDesc(dst.uniforms[i], src.uniforms[i]); +} + +LLGL_C_EXPORT LLGLPipelineLayout llglCreatePipelineLayout(const LLGLPipelineLayoutDescriptor* pipelineLayoutDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(pipelineLayoutDesc); + PipelineLayoutDescriptor internalPipelineLayoutDesc; + ConvertPipelineLayoutDesc(internalPipelineLayoutDesc, *pipelineLayoutDesc); + return LLGLPipelineLayout{ g_CurrentRenderSystem->CreatePipelineLayout(internalPipelineLayoutDesc) }; +} + +LLGL_C_EXPORT void llglReleasePipelineLayout(LLGLPipelineLayout pipelineLayout) +{ + LLGL_RELEASE(PipelineLayout, pipelineLayout); +} + +static void ConvertGraphicsPipelineDesc(GraphicsPipelineDescriptor& dst, const LLGLGraphicsPipelineDescriptor& src) +{ + dst.pipelineLayout = LLGL_PTR(PipelineLayout, src.pipelineLayout); + dst.renderPass = LLGL_PTR(RenderPass, src.renderPass); + dst.vertexShader = LLGL_PTR(Shader, src.vertexShader); + dst.tessControlShader = LLGL_PTR(Shader, src.tessControlShader); + dst.tessEvaluationShader = LLGL_PTR(Shader, src.tessEvaluationShader); + dst.geometryShader = LLGL_PTR(Shader, src.geometryShader); + dst.fragmentShader = LLGL_PTR(Shader, src.fragmentShader); + dst.primitiveTopology = static_cast(src.primitiveTopology); + + dst.viewports.resize(src.numViewports); + ::memcpy(dst.viewports.data(), src.viewports, src.numViewports * sizeof(LLGLViewport)); + + dst.scissors.resize(src.numScissors); + ::memcpy(dst.scissors.data(), src.scissors, src.numScissors * sizeof(LLGLScissor)); + + ::memcpy(&(dst.depth), &(src.depth), sizeof(LLGLDepthDescriptor)); + ::memcpy(&(dst.stencil), &(src.stencil), sizeof(LLGLStencilDescriptor)); + ::memcpy(&(dst.rasterizer), &(src.rasterizer), sizeof(LLGLRasterizerDescriptor)); + ::memcpy(&(dst.blend), &(src.blend), sizeof(LLGLBlendDescriptor)); + ::memcpy(&(dst.tessellation), &(src.tessellation), sizeof(LLGLTessellationDescriptor)); +} + +LLGL_C_EXPORT LLGLPipelineState llglCreateGraphicsPipelineState(const LLGLGraphicsPipelineDescriptor* pipelineStateDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(pipelineStateDesc); + GraphicsPipelineDescriptor internalPipelineStateDesc; + ConvertGraphicsPipelineDesc(internalPipelineStateDesc, *pipelineStateDesc); + return LLGLPipelineState{ g_CurrentRenderSystem->CreatePipelineState(internalPipelineStateDesc) }; +} + +static void ConvertComputePipelineDesc(ComputePipelineDescriptor& dst, const LLGLComputePipelineDescriptor& src) +{ + dst.pipelineLayout = LLGL_PTR(PipelineLayout, src.pipelineLayout); + dst.computeShader = LLGL_PTR(Shader, src.computeShader); +} + +LLGL_C_EXPORT LLGLPipelineState llglCreateComputePipelineState(const LLGLComputePipelineDescriptor* pipelineStateDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(pipelineStateDesc); + ComputePipelineDescriptor internalPipelineStateDesc; + ConvertComputePipelineDesc(internalPipelineStateDesc, *pipelineStateDesc); + return LLGLPipelineState{ g_CurrentRenderSystem->CreatePipelineState(internalPipelineStateDesc) }; +} + +LLGL_C_EXPORT void llglReleasePipelineState(LLGLPipelineState pipelineState) +{ + LLGL_RELEASE(PipelineState, pipelineState); +} + +LLGL_C_EXPORT LLGLQueryHeap llglCreateQueryHeap(const LLGLQueryHeapDescriptor* queryHeapDesc) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + LLGL_ASSERT_PTR(queryHeapDesc); + return LLGLQueryHeap{ g_CurrentRenderSystem->CreateQueryHeap(*reinterpret_cast(queryHeapDesc)) }; +} + +LLGL_C_EXPORT void llglReleaseQueryHeap(LLGLQueryHeap queryHeap) +{ + LLGL_RELEASE(QueryHeap, queryHeap); +} + +LLGL_C_EXPORT LLGLFence llglCreateFence() +{ + LLGL_ASSERT_RENDER_SYSTEM(); + return LLGLFence{ g_CurrentRenderSystem->CreateFence() }; +} + +LLGL_C_EXPORT void llglReleaseFence(LLGLFence fence) +{ + LLGL_RELEASE(Fence, fence); +} + +LLGL_C_EXPORT bool llglGetRenderSystemNativeHandle(void* nativeHandle, size_t nativeHandleSize) +{ + LLGL_ASSERT_RENDER_SYSTEM(); + return g_CurrentRenderSystem->GetNativeHandle(nativeHandle, nativeHandleSize); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99RenderTarget.cpp b/wrapper/C99/C99RenderTarget.cpp new file mode 100644 index 0000000000..bd0bbecab7 --- /dev/null +++ b/wrapper/C99/C99RenderTarget.cpp @@ -0,0 +1,55 @@ +/* + * C99RenderTarget.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT void llglGetRenderTargetResolution(LLGLRenderTarget renderTarget, LLGLExtent2D* outResolution) +{ + Extent2D resolution = LLGL_PTR(RenderTarget, renderTarget)->GetResolution(); + outResolution->width = resolution.width; + outResolution->height = resolution.height; +} + +LLGL_C_EXPORT uint32_t llglGetRenderTargetSamples(LLGLRenderTarget renderTarget) +{ + return LLGL_PTR(RenderTarget, renderTarget)->GetSamples(); +} + +LLGL_C_EXPORT uint32_t llglGetRenderTargetNumColorAttachments(LLGLRenderTarget renderTarget) +{ + return LLGL_PTR(RenderTarget, renderTarget)->GetNumColorAttachments(); +} + +LLGL_C_EXPORT bool llglHasRenderTargetDepthAttachment(LLGLRenderTarget renderTarget) +{ + return LLGL_PTR(RenderTarget, renderTarget)->HasDepthAttachment(); +} + +LLGL_C_EXPORT bool llglHasRenderTargetStencilAttachment(LLGLRenderTarget renderTarget) +{ + return LLGL_PTR(RenderTarget, renderTarget)->HasStencilAttachment(); +} + +LLGL_C_EXPORT LLGLRenderPass llglGetRenderTargetRenderPass(LLGLRenderTarget renderTarget) +{ + return LLGLRenderPass{ const_cast(LLGL_PTR(RenderTarget, renderTarget)->GetRenderPass()) }; +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99Report.cpp b/wrapper/C99/C99Report.cpp new file mode 100644 index 0000000000..1f630111e9 --- /dev/null +++ b/wrapper/C99/C99Report.cpp @@ -0,0 +1,39 @@ +/* + * C99Report.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT const char* llglGetReportText(LLGLReport report) +{ + if (const Report* internalReport = LLGL_PTR(Report, report)) + return internalReport->GetText(); + else + return ""; +} + +LLGL_C_EXPORT bool llglHasReportErrors(LLGLReport report) +{ + if (const Report* internalReport = LLGL_PTR(Report, report)) + return internalReport->HasErrors(); + else + return false; +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99Resource.cpp b/wrapper/C99/C99Resource.cpp new file mode 100644 index 0000000000..c9d28ad455 --- /dev/null +++ b/wrapper/C99/C99Resource.cpp @@ -0,0 +1,28 @@ +/* + * C99Resource.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT LLGLResourceType lgllGetResourceType(LLGLResource resource) +{ + return static_cast(LLGL_PTR(Resource, resource)->GetResourceType()); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99Shader.cpp b/wrapper/C99/C99Shader.cpp new file mode 100644 index 0000000000..c0b49dfc76 --- /dev/null +++ b/wrapper/C99/C99Shader.cpp @@ -0,0 +1,94 @@ +/* + * C99Shader.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include +#include "C99Internal.h" +#include +#include + + +// namespace LLGL { + + +using namespace LLGL; + +struct ShaderReflectionC99Wrapper +{ + std::vector resources; + std::vector uniforms; + std::vector names; +}; + +LLGL_C_EXPORT LLGLReport llglGetShaderReport(LLGLShader shader) +{ + return LLGLReport{ LLGL_PTR(Shader, shader)->GetReport() }; +} + +static void ConvertBindingDesc(ShaderReflectionC99Wrapper& wrapper, LLGLBindingDescriptor& dst, const BindingDescriptor& src) +{ + wrapper.names.push_back(src.name); + dst.name = wrapper.names.back().c_str(); + dst.type = static_cast(src.type); + dst.bindFlags = src.bindFlags; + dst.stageFlags = src.stageFlags; + dst.slot = { src.slot.index, src.slot.set }; + dst.arraySize = src.arraySize; +} + +static void ConvertShaderResourceReflection(ShaderReflectionC99Wrapper& wrapper, LLGLShaderResourceReflection& dst, const ShaderResourceReflection& src) +{ + ConvertBindingDesc(wrapper, dst.binding, src.binding); + dst.constantBufferSize = src.constantBufferSize; + dst.storageBufferType = static_cast(src.storageBufferType); +} + +static void ConvertUniformDesc(ShaderReflectionC99Wrapper& wrapper, LLGLUniformDescriptor& dst, const UniformDescriptor& src) +{ + wrapper.names.push_back(src.name); + dst.name = wrapper.names.back().c_str(); + dst.type = static_cast(src.type); + dst.arraySize = src.arraySize; +} + +static void ConvertShaderReflection(ShaderReflectionC99Wrapper& wrapper, LLGLShaderReflection& dst, const ShaderReflection& src) +{ + wrapper.names.reserve(src.resources.size() + src.uniforms.size()); + + wrapper.resources.resize(src.resources.size()); + for_range(i, src.resources.size()) + ConvertShaderResourceReflection(wrapper, wrapper.resources[i], src.resources[i]); + + wrapper.uniforms.resize(src.uniforms.size()); + for_range(i, src.uniforms.size()) + ConvertUniformDesc(wrapper, wrapper.uniforms[i], src.uniforms[i]); +} + +LLGL_C_EXPORT bool llglReflectShader(LLGLShader shader, LLGLShaderReflection* reflection) +{ + static thread_local ShaderReflectionC99Wrapper reflectionWrapper; + ShaderReflection internalReflection; + if (reflection != NULL && LLGL_PTR(Shader, shader)->Reflect(internalReflection)) + { + ConvertShaderReflection(reflectionWrapper, *reflection, internalReflection); + return true; + } + return false; +} + +LLGL_C_EXPORT LLGLShaderType llglGetShaderType(LLGLShader shader) +{ + return static_cast(LLGL_PTR(Shader, shader)->GetType()); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99Surface.cpp b/wrapper/C99/C99Surface.cpp new file mode 100644 index 0000000000..f3696fab32 --- /dev/null +++ b/wrapper/C99/C99Surface.cpp @@ -0,0 +1,55 @@ +/* + * C99Surface.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT bool llglGetSurfaceNativeHandle(LLGLSurface surface, void* nativeHandle, size_t nativeHandleSize) +{ + return LLGL_PTR(Surface, surface)->GetNativeHandle(nativeHandle, nativeHandleSize); +} + +LLGL_C_EXPORT void llglGetSurfaceContentSize(LLGLSurface surface, LLGLExtent2D* outSize) +{ + Extent2D internalSize = LLGL_PTR(Surface, surface)->GetContentSize(); + outSize->width = internalSize.width; + outSize->height = internalSize.height; +} + +LLGL_C_EXPORT bool llglAdaptSurfaceForVideoMode(LLGLSurface surface, LLGLExtent2D* outResolution, bool* outFullscreen) +{ + return LLGL_PTR(Surface, surface)->AdaptForVideoMode((Extent2D*)outResolution, outFullscreen); +} + +LLGL_C_EXPORT void llglResetSurfacePixelFormat(LLGLSurface surface) +{ + LLGL_PTR(Surface, surface)->ResetPixelFormat(); +} + +LLGL_C_EXPORT bool llglProcessSurfaceEvents(LLGLSurface surface) +{ + return LLGL_PTR(Surface, surface)->ProcessEvents(); +} + +LLGL_C_EXPORT LLGLDisplay llglFindSurfaceResidentDisplay(LLGLSurface surface) +{ + return LLGLDisplay{ LLGL_PTR(Surface, surface)->FindResidentDisplay() }; +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99SwapChain.cpp b/wrapper/C99/C99SwapChain.cpp new file mode 100644 index 0000000000..1e396e8884 --- /dev/null +++ b/wrapper/C99/C99SwapChain.cpp @@ -0,0 +1,68 @@ +/* + * C99SwapChain.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT void llglPresent(LLGLSwapChain swapChain) +{ + LLGL_PTR(SwapChain, swapChain)->Present(); +} + +LLGL_C_EXPORT uint32_t llglGetCurrentSwapIndex(LLGLSwapChain swapChain) +{ + return LLGL_PTR(SwapChain, swapChain)->GetCurrentSwapIndex(); +} + +LLGL_C_EXPORT uint32_t llglGetNumSwapBuffers(LLGLSwapChain swapChain) +{ + return LLGL_PTR(SwapChain, swapChain)->GetNumSwapBuffers(); +} + +LLGL_C_EXPORT LLGLFormat llglGetColorFormat(LLGLSwapChain swapChain) +{ + return (LLGLFormat)LLGL_PTR(SwapChain, swapChain)->GetColorFormat(); +} + +LLGL_C_EXPORT LLGLFormat llglGetDepthStencilFormat(LLGLSwapChain swapChain) +{ + return (LLGLFormat)LLGL_PTR(SwapChain, swapChain)->GetDepthStencilFormat(); +} + +LLGL_C_EXPORT bool llglResizeBuffers(LLGLSwapChain swapChain, const LLGLExtent2D* resolution, long flags) +{ + return LLGL_PTR(SwapChain, swapChain)->ResizeBuffers(*(const Extent2D*)resolution, flags); +} + +LLGL_C_EXPORT bool llglSetVsyncInterval(LLGLSwapChain swapChain, uint32_t vsyncInterval) +{ + return LLGL_PTR(SwapChain, swapChain)->SetVsyncInterval(vsyncInterval); +} + +LLGL_C_EXPORT bool llglSwitchFullscreen(LLGLSwapChain swapChain, bool enable) +{ + return LLGL_PTR(SwapChain, swapChain)->SwitchFullscreen(enable); +} + +LLGL_C_EXPORT LLGLSurface llglGetSurface(LLGLSwapChain swapChain) +{ + return LLGLSurface{ &(LLGL_PTR(SwapChain, swapChain)->GetSurface()) }; +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99Texture.cpp b/wrapper/C99/C99Texture.cpp new file mode 100644 index 0000000000..53b8d8b193 --- /dev/null +++ b/wrapper/C99/C99Texture.cpp @@ -0,0 +1,59 @@ +/* + * C99Texture.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT LLGLTextureType llglGetTextureType(LLGLTexture texture) +{ + return static_cast(LLGL_PTR(Texture, texture)->GetType()); +} + +LLGL_C_EXPORT long llglGetTextureBindFlags(LLGLTexture texture) +{ + return LLGL_PTR(Texture, texture)->GetBindFlags(); +} + +LLGL_C_EXPORT void llglGetTextureDesc(LLGLTexture texture, LLGLTextureDescriptor* outDesc) +{ + LLGL_ASSERT_PTR(outDesc); + const TextureDescriptor internalDesc = LLGL_PTR(Texture, texture)->GetDesc(); + *outDesc = *reinterpret_cast(&internalDesc); +} + +LLGL_C_EXPORT LLGLFormat llglGetTextureFormat(LLGLTexture texture) +{ + return static_cast(LLGL_PTR(Texture, texture)->GetFormat()); +} + +LLGL_C_EXPORT void llglGetTextureMipExtent(LLGLTexture texture, uint32_t mipLevel, LLGLExtent3D* outExtent) +{ + LLGL_ASSERT_PTR(outExtent); + const Extent3D internalExtent = LLGL_PTR(Texture, texture)->GetMipExtent(mipLevel); + *outExtent = *reinterpret_cast(&internalExtent); +} + +LLGL_C_EXPORT void llglGetTextureSubresourceFootprint(LLGLTexture texture, uint32_t mipLevel, LLGLSubresourceFootprint* outFootprint) +{ + LLGL_ASSERT_PTR(outFootprint); + const SubresourceFootprint internalFootprint = LLGL_PTR(Texture, texture)->GetSubresourceFootprint(mipLevel); + *outFootprint = *reinterpret_cast(&internalFootprint); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99Timer.cpp b/wrapper/C99/C99Timer.cpp new file mode 100644 index 0000000000..abd016a7a6 --- /dev/null +++ b/wrapper/C99/C99Timer.cpp @@ -0,0 +1,33 @@ +/* + * C99Timer.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" + + +// namespace LLGL { + + +using namespace LLGL; + +LLGL_C_EXPORT uint64_t llglTimerFrequency() +{ + return Timer::Frequency(); +} + +LLGL_C_EXPORT uint64_t llglTimerTick() +{ + return Timer::Tick(); +} + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99TypeAssertions.cpp b/wrapper/C99/C99TypeAssertions.cpp new file mode 100644 index 0000000000..ad53a60980 --- /dev/null +++ b/wrapper/C99/C99TypeAssertions.cpp @@ -0,0 +1,1112 @@ +/* + * C99TypeAssertions.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + + +#define LLGL_STATIC_ASSERT_ENUM(TYPE, VALUE) \ + static_assert(TYPE::VALUE == (TYPE)(LLGL ## TYPE ## VALUE), "LLGL" #TYPE #VALUE " does not equal enumeration value of LLGL::" #TYPE "::" #VALUE) + +#define LLGL_STATIC_ASSERT_FLAG(TYPE, VALUE) \ + static_assert(TYPE ## Flags::VALUE == LLGL ## TYPE ## VALUE, "LLGL" #TYPE #VALUE " does not equal flags value of LLGL::" #TYPE "Flags::" #VALUE) + +#define LLGL_STATIC_ASSERT_SIZE(TYPE) \ + static_assert(sizeof(LLGL::TYPE) == sizeof(LLGL ## TYPE), "LLGL" #TYPE " does not match size of LLGL::" #TYPE) + +#define LLGL_STATIC_ASSERT_OFFSET(TYPE, FIELD) \ + static_assert(offsetof(LLGL::TYPE, FIELD) == offsetof(LLGL ## TYPE, FIELD), "LLGL" #TYPE "::" #FIELD " does not match offset of LLGL::" #TYPE "::" #FIELD) + + +using namespace LLGL; + +// namespace LLGL { + + +/* ----- Enumerations ----- */ + +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_110); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_120); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_130); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_140); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_150); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_330); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_400); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_410); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_420); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_430); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_440); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_450); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, GLSL_460); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, ESSL); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, ESSL_100); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, ESSL_300); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, ESSL_310); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, ESSL_320); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_2_0); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_2_0a); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_2_0b); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_3_0); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_4_0); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_4_1); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_5_0); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_5_1); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_6_0); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_6_1); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_6_2); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_6_3); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, HLSL_6_4); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, Metal); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, Metal_1_0); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, Metal_1_1); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, Metal_1_2); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, Metal_2_0); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, Metal_2_1); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, SPIRV); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, SPIRV_100); +LLGL_STATIC_ASSERT_ENUM(ShadingLanguage, VersionBitmask); + +LLGL_STATIC_ASSERT_ENUM(ScreenOrigin, LowerLeft); +LLGL_STATIC_ASSERT_ENUM(ScreenOrigin, UpperLeft); + +LLGL_STATIC_ASSERT_ENUM(ClippingRange, MinusOneToOne); +LLGL_STATIC_ASSERT_ENUM(ClippingRange, ZeroToOne); + +LLGL_STATIC_ASSERT_ENUM(CPUAccess, ReadOnly); +LLGL_STATIC_ASSERT_ENUM(CPUAccess, WriteOnly); +LLGL_STATIC_ASSERT_ENUM(CPUAccess, WriteDiscard); +LLGL_STATIC_ASSERT_ENUM(CPUAccess, ReadWrite); + +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, PointList); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, LineList); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, LineStrip); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, LineListAdjacency); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, LineStripAdjacency); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, TriangleList); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, TriangleStrip); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, TriangleListAdjacency); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, TriangleStripAdjacency); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches1); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches2); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches3); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches4); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches5); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches6); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches7); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches8); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches9); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches10); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches11); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches12); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches13); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches14); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches15); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches16); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches17); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches18); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches19); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches20); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches21); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches22); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches23); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches24); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches25); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches26); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches27); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches28); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches29); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches30); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches31); +LLGL_STATIC_ASSERT_ENUM(PrimitiveTopology, Patches32); + +LLGL_STATIC_ASSERT_ENUM(CompareOp, NeverPass); +LLGL_STATIC_ASSERT_ENUM(CompareOp, Less); +LLGL_STATIC_ASSERT_ENUM(CompareOp, Equal); +LLGL_STATIC_ASSERT_ENUM(CompareOp, LessEqual); +LLGL_STATIC_ASSERT_ENUM(CompareOp, Greater); +LLGL_STATIC_ASSERT_ENUM(CompareOp, NotEqual); +LLGL_STATIC_ASSERT_ENUM(CompareOp, GreaterEqual); +LLGL_STATIC_ASSERT_ENUM(CompareOp, AlwaysPass); + +LLGL_STATIC_ASSERT_ENUM(StencilOp, Keep); +LLGL_STATIC_ASSERT_ENUM(StencilOp, Zero); +LLGL_STATIC_ASSERT_ENUM(StencilOp, Replace); +LLGL_STATIC_ASSERT_ENUM(StencilOp, IncClamp); +LLGL_STATIC_ASSERT_ENUM(StencilOp, DecClamp); +LLGL_STATIC_ASSERT_ENUM(StencilOp, Invert); +LLGL_STATIC_ASSERT_ENUM(StencilOp, IncWrap); +LLGL_STATIC_ASSERT_ENUM(StencilOp, DecWrap); + +LLGL_STATIC_ASSERT_ENUM(BlendOp, Zero); +LLGL_STATIC_ASSERT_ENUM(BlendOp, One); +LLGL_STATIC_ASSERT_ENUM(BlendOp, SrcColor); +LLGL_STATIC_ASSERT_ENUM(BlendOp, InvSrcColor); +LLGL_STATIC_ASSERT_ENUM(BlendOp, SrcAlpha); +LLGL_STATIC_ASSERT_ENUM(BlendOp, InvSrcAlpha); +LLGL_STATIC_ASSERT_ENUM(BlendOp, DstColor); +LLGL_STATIC_ASSERT_ENUM(BlendOp, InvDstColor); +LLGL_STATIC_ASSERT_ENUM(BlendOp, DstAlpha); +LLGL_STATIC_ASSERT_ENUM(BlendOp, InvDstAlpha); +LLGL_STATIC_ASSERT_ENUM(BlendOp, SrcAlphaSaturate); +LLGL_STATIC_ASSERT_ENUM(BlendOp, BlendFactor); +LLGL_STATIC_ASSERT_ENUM(BlendOp, InvBlendFactor); +LLGL_STATIC_ASSERT_ENUM(BlendOp, Src1Color); +LLGL_STATIC_ASSERT_ENUM(BlendOp, InvSrc1Color); +LLGL_STATIC_ASSERT_ENUM(BlendOp, Src1Alpha); +LLGL_STATIC_ASSERT_ENUM(BlendOp, InvSrc1Alpha); + +LLGL_STATIC_ASSERT_ENUM(BlendArithmetic, Add); +LLGL_STATIC_ASSERT_ENUM(BlendArithmetic, Subtract); +LLGL_STATIC_ASSERT_ENUM(BlendArithmetic, RevSubtract); +LLGL_STATIC_ASSERT_ENUM(BlendArithmetic, Min); +LLGL_STATIC_ASSERT_ENUM(BlendArithmetic, Max); + +LLGL_STATIC_ASSERT_ENUM(PolygonMode, Fill); +LLGL_STATIC_ASSERT_ENUM(PolygonMode, Wireframe); +LLGL_STATIC_ASSERT_ENUM(PolygonMode, Points); + +LLGL_STATIC_ASSERT_ENUM(CullMode, Disabled); +LLGL_STATIC_ASSERT_ENUM(CullMode, Front); +LLGL_STATIC_ASSERT_ENUM(CullMode, Back); + +LLGL_STATIC_ASSERT_ENUM(LogicOp, Disabled); +LLGL_STATIC_ASSERT_ENUM(LogicOp, Clear); +LLGL_STATIC_ASSERT_ENUM(LogicOp, Set); +LLGL_STATIC_ASSERT_ENUM(LogicOp, Copy); +LLGL_STATIC_ASSERT_ENUM(LogicOp, CopyInverted); +LLGL_STATIC_ASSERT_ENUM(LogicOp, NoOp); +LLGL_STATIC_ASSERT_ENUM(LogicOp, Invert); +LLGL_STATIC_ASSERT_ENUM(LogicOp, AND); +LLGL_STATIC_ASSERT_ENUM(LogicOp, ANDReverse); +LLGL_STATIC_ASSERT_ENUM(LogicOp, ANDInverted); +LLGL_STATIC_ASSERT_ENUM(LogicOp, NAND); +LLGL_STATIC_ASSERT_ENUM(LogicOp, OR); +LLGL_STATIC_ASSERT_ENUM(LogicOp, ORReverse); +LLGL_STATIC_ASSERT_ENUM(LogicOp, ORInverted); +LLGL_STATIC_ASSERT_ENUM(LogicOp, NOR); +LLGL_STATIC_ASSERT_ENUM(LogicOp, XOR); +LLGL_STATIC_ASSERT_ENUM(LogicOp, Equiv); + +LLGL_STATIC_ASSERT_ENUM(TessellationPartition, Undefined); +LLGL_STATIC_ASSERT_ENUM(TessellationPartition, Integer); +LLGL_STATIC_ASSERT_ENUM(TessellationPartition, Pow2); +LLGL_STATIC_ASSERT_ENUM(TessellationPartition, FractionalOdd); +LLGL_STATIC_ASSERT_ENUM(TessellationPartition, FractionalEven); + +LLGL_STATIC_ASSERT_ENUM(RenderConditionMode, Wait); +LLGL_STATIC_ASSERT_ENUM(RenderConditionMode, NoWait); +LLGL_STATIC_ASSERT_ENUM(RenderConditionMode, ByRegionWait); +LLGL_STATIC_ASSERT_ENUM(RenderConditionMode, ByRegionNoWait); +LLGL_STATIC_ASSERT_ENUM(RenderConditionMode, WaitInverted); +LLGL_STATIC_ASSERT_ENUM(RenderConditionMode, NoWaitInverted); +LLGL_STATIC_ASSERT_ENUM(RenderConditionMode, ByRegionWaitInverted); +LLGL_STATIC_ASSERT_ENUM(RenderConditionMode, ByRegionNoWaitInverted); + +LLGL_STATIC_ASSERT_ENUM(StencilFace, FrontAndBack); +LLGL_STATIC_ASSERT_ENUM(StencilFace, Front); +LLGL_STATIC_ASSERT_ENUM(StencilFace, Back); + +LLGL_STATIC_ASSERT_ENUM(Format, Undefined); +LLGL_STATIC_ASSERT_ENUM(Format, A8UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, R8UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, R8SNorm); +LLGL_STATIC_ASSERT_ENUM(Format, R8UInt); +LLGL_STATIC_ASSERT_ENUM(Format, R8SInt); +LLGL_STATIC_ASSERT_ENUM(Format, R16UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, R16SNorm); +LLGL_STATIC_ASSERT_ENUM(Format, R16UInt); +LLGL_STATIC_ASSERT_ENUM(Format, R16SInt); +LLGL_STATIC_ASSERT_ENUM(Format, R16Float); +LLGL_STATIC_ASSERT_ENUM(Format, R32UInt); +LLGL_STATIC_ASSERT_ENUM(Format, R32SInt); +LLGL_STATIC_ASSERT_ENUM(Format, R32Float); +LLGL_STATIC_ASSERT_ENUM(Format, R64Float); +LLGL_STATIC_ASSERT_ENUM(Format, RG8UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RG8SNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RG8UInt); +LLGL_STATIC_ASSERT_ENUM(Format, RG8SInt); +LLGL_STATIC_ASSERT_ENUM(Format, RG16UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RG16SNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RG16UInt); +LLGL_STATIC_ASSERT_ENUM(Format, RG16SInt); +LLGL_STATIC_ASSERT_ENUM(Format, RG16Float); +LLGL_STATIC_ASSERT_ENUM(Format, RG32UInt); +LLGL_STATIC_ASSERT_ENUM(Format, RG32SInt); +LLGL_STATIC_ASSERT_ENUM(Format, RG32Float); +LLGL_STATIC_ASSERT_ENUM(Format, RG64Float); +LLGL_STATIC_ASSERT_ENUM(Format, RGB8UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RGB8UNorm_sRGB); +LLGL_STATIC_ASSERT_ENUM(Format, RGB8SNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RGB8UInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGB8SInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGB16UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RGB16SNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RGB16UInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGB16SInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGB16Float); +LLGL_STATIC_ASSERT_ENUM(Format, RGB32UInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGB32SInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGB32Float); +LLGL_STATIC_ASSERT_ENUM(Format, RGB64Float); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA8UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA8UNorm_sRGB); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA8SNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA8UInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA8SInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA16UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA16SNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA16UInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA16SInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA16Float); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA32UInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA32SInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA32Float); +LLGL_STATIC_ASSERT_ENUM(Format, RGBA64Float); +LLGL_STATIC_ASSERT_ENUM(Format, BGRA8UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, BGRA8UNorm_sRGB); +LLGL_STATIC_ASSERT_ENUM(Format, BGRA8SNorm); +LLGL_STATIC_ASSERT_ENUM(Format, BGRA8UInt); +LLGL_STATIC_ASSERT_ENUM(Format, BGRA8SInt); +LLGL_STATIC_ASSERT_ENUM(Format, RGB10A2UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, RGB10A2UInt); +LLGL_STATIC_ASSERT_ENUM(Format, RG11B10Float); +LLGL_STATIC_ASSERT_ENUM(Format, RGB9E5Float); +LLGL_STATIC_ASSERT_ENUM(Format, D16UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, D24UNormS8UInt); +LLGL_STATIC_ASSERT_ENUM(Format, D32Float); +LLGL_STATIC_ASSERT_ENUM(Format, D32FloatS8X24UInt); +LLGL_STATIC_ASSERT_ENUM(Format, BC1UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, BC1UNorm_sRGB); +LLGL_STATIC_ASSERT_ENUM(Format, BC2UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, BC2UNorm_sRGB); +LLGL_STATIC_ASSERT_ENUM(Format, BC3UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, BC3UNorm_sRGB); +LLGL_STATIC_ASSERT_ENUM(Format, BC4UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, BC4SNorm); +LLGL_STATIC_ASSERT_ENUM(Format, BC5UNorm); +LLGL_STATIC_ASSERT_ENUM(Format, BC5SNorm); + +LLGL_STATIC_ASSERT_ENUM(ImageFormat, Alpha); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, R); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, RG); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, RGB); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, BGR); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, RGBA); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, BGRA); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, ARGB); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, ABGR); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, Depth); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, DepthStencil); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, BC1); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, BC2); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, BC3); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, BC4); +LLGL_STATIC_ASSERT_ENUM(ImageFormat, BC5); + +LLGL_STATIC_ASSERT_ENUM(DataType, Undefined); +LLGL_STATIC_ASSERT_ENUM(DataType, Int8); +LLGL_STATIC_ASSERT_ENUM(DataType, UInt8); +LLGL_STATIC_ASSERT_ENUM(DataType, Int16); +LLGL_STATIC_ASSERT_ENUM(DataType, UInt16); +LLGL_STATIC_ASSERT_ENUM(DataType, Int32); +LLGL_STATIC_ASSERT_ENUM(DataType, UInt32); +LLGL_STATIC_ASSERT_ENUM(DataType, Float16); +LLGL_STATIC_ASSERT_ENUM(DataType, Float32); +LLGL_STATIC_ASSERT_ENUM(DataType, Float64); + +LLGL_STATIC_ASSERT_ENUM(SystemValue, Undefined); +LLGL_STATIC_ASSERT_ENUM(SystemValue, ClipDistance); +LLGL_STATIC_ASSERT_ENUM(SystemValue, Color); +LLGL_STATIC_ASSERT_ENUM(SystemValue, CullDistance); +LLGL_STATIC_ASSERT_ENUM(SystemValue, Depth); +LLGL_STATIC_ASSERT_ENUM(SystemValue, DepthGreater); +LLGL_STATIC_ASSERT_ENUM(SystemValue, DepthLess); +LLGL_STATIC_ASSERT_ENUM(SystemValue, FrontFacing); +LLGL_STATIC_ASSERT_ENUM(SystemValue, InstanceID); +LLGL_STATIC_ASSERT_ENUM(SystemValue, Position); +LLGL_STATIC_ASSERT_ENUM(SystemValue, PrimitiveID); +LLGL_STATIC_ASSERT_ENUM(SystemValue, RenderTargetIndex); +LLGL_STATIC_ASSERT_ENUM(SystemValue, SampleMask); +LLGL_STATIC_ASSERT_ENUM(SystemValue, SampleID); +LLGL_STATIC_ASSERT_ENUM(SystemValue, Stencil); +LLGL_STATIC_ASSERT_ENUM(SystemValue, VertexID); +LLGL_STATIC_ASSERT_ENUM(SystemValue, ViewportIndex); + +LLGL_STATIC_ASSERT_ENUM(TextureType, Texture1D); +LLGL_STATIC_ASSERT_ENUM(TextureType, Texture2D); +LLGL_STATIC_ASSERT_ENUM(TextureType, Texture3D); +LLGL_STATIC_ASSERT_ENUM(TextureType, TextureCube); +LLGL_STATIC_ASSERT_ENUM(TextureType, Texture1DArray); +LLGL_STATIC_ASSERT_ENUM(TextureType, Texture2DArray); +LLGL_STATIC_ASSERT_ENUM(TextureType, TextureCubeArray); +LLGL_STATIC_ASSERT_ENUM(TextureType, Texture2DMS); +LLGL_STATIC_ASSERT_ENUM(TextureType, Texture2DMSArray); + +LLGL_STATIC_ASSERT_ENUM(TextureSwizzle, Zero); +LLGL_STATIC_ASSERT_ENUM(TextureSwizzle, One); +LLGL_STATIC_ASSERT_ENUM(TextureSwizzle, Red); +LLGL_STATIC_ASSERT_ENUM(TextureSwizzle, Green); +LLGL_STATIC_ASSERT_ENUM(TextureSwizzle, Blue); +LLGL_STATIC_ASSERT_ENUM(TextureSwizzle, Alpha); + +LLGL_STATIC_ASSERT_ENUM(SamplerAddressMode, Repeat); +LLGL_STATIC_ASSERT_ENUM(SamplerAddressMode, Mirror); +LLGL_STATIC_ASSERT_ENUM(SamplerAddressMode, Clamp); +LLGL_STATIC_ASSERT_ENUM(SamplerAddressMode, Border); +LLGL_STATIC_ASSERT_ENUM(SamplerAddressMode, MirrorOnce); + +LLGL_STATIC_ASSERT_ENUM(SamplerFilter, Nearest); +LLGL_STATIC_ASSERT_ENUM(SamplerFilter, Linear); + +LLGL_STATIC_ASSERT_ENUM(ShaderType, Undefined); +LLGL_STATIC_ASSERT_ENUM(ShaderType, Vertex); +LLGL_STATIC_ASSERT_ENUM(ShaderType, TessControl); +LLGL_STATIC_ASSERT_ENUM(ShaderType, TessEvaluation); +LLGL_STATIC_ASSERT_ENUM(ShaderType, Geometry); +LLGL_STATIC_ASSERT_ENUM(ShaderType, Fragment); +LLGL_STATIC_ASSERT_ENUM(ShaderType, Compute); + +LLGL_STATIC_ASSERT_ENUM(ShaderSourceType, CodeString); +LLGL_STATIC_ASSERT_ENUM(ShaderSourceType, CodeFile); +LLGL_STATIC_ASSERT_ENUM(ShaderSourceType, BinaryBuffer); +LLGL_STATIC_ASSERT_ENUM(ShaderSourceType, BinaryFile); + +LLGL_STATIC_ASSERT_ENUM(UniformType, Undefined); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float1); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float2); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float3); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float4); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double1); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double2); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double3); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double4); +LLGL_STATIC_ASSERT_ENUM(UniformType, Int1); +LLGL_STATIC_ASSERT_ENUM(UniformType, Int2); +LLGL_STATIC_ASSERT_ENUM(UniformType, Int3); +LLGL_STATIC_ASSERT_ENUM(UniformType, Int4); +LLGL_STATIC_ASSERT_ENUM(UniformType, UInt1); +LLGL_STATIC_ASSERT_ENUM(UniformType, UInt2); +LLGL_STATIC_ASSERT_ENUM(UniformType, UInt3); +LLGL_STATIC_ASSERT_ENUM(UniformType, UInt4); +LLGL_STATIC_ASSERT_ENUM(UniformType, Bool1); +LLGL_STATIC_ASSERT_ENUM(UniformType, Bool2); +LLGL_STATIC_ASSERT_ENUM(UniformType, Bool3); +LLGL_STATIC_ASSERT_ENUM(UniformType, Bool4); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float2x2); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float2x3); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float2x4); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float3x2); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float3x3); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float3x4); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float4x2); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float4x3); +LLGL_STATIC_ASSERT_ENUM(UniformType, Float4x4); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double2x2); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double2x3); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double2x4); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double3x2); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double3x3); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double3x4); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double4x2); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double4x3); +LLGL_STATIC_ASSERT_ENUM(UniformType, Double4x4); +LLGL_STATIC_ASSERT_ENUM(UniformType, Sampler); +LLGL_STATIC_ASSERT_ENUM(UniformType, Image); +LLGL_STATIC_ASSERT_ENUM(UniformType, AtomicCounter); + +LLGL_STATIC_ASSERT_ENUM(ResourceType, Undefined); +LLGL_STATIC_ASSERT_ENUM(ResourceType, Buffer); +LLGL_STATIC_ASSERT_ENUM(ResourceType, Texture); +LLGL_STATIC_ASSERT_ENUM(ResourceType, Sampler); + +LLGL_STATIC_ASSERT_ENUM(Key, LButton); +LLGL_STATIC_ASSERT_ENUM(Key, RButton); +LLGL_STATIC_ASSERT_ENUM(Key, Cancel); +LLGL_STATIC_ASSERT_ENUM(Key, MButton); +LLGL_STATIC_ASSERT_ENUM(Key, XButton1); +LLGL_STATIC_ASSERT_ENUM(Key, XButton2); +LLGL_STATIC_ASSERT_ENUM(Key, Back); +LLGL_STATIC_ASSERT_ENUM(Key, Tab); +LLGL_STATIC_ASSERT_ENUM(Key, Clear); +LLGL_STATIC_ASSERT_ENUM(Key, Return); +LLGL_STATIC_ASSERT_ENUM(Key, Shift); +LLGL_STATIC_ASSERT_ENUM(Key, Control); +LLGL_STATIC_ASSERT_ENUM(Key, Menu); +LLGL_STATIC_ASSERT_ENUM(Key, Pause); +LLGL_STATIC_ASSERT_ENUM(Key, Capital); +LLGL_STATIC_ASSERT_ENUM(Key, Escape); +LLGL_STATIC_ASSERT_ENUM(Key, Space); +LLGL_STATIC_ASSERT_ENUM(Key, PageUp); +LLGL_STATIC_ASSERT_ENUM(Key, PageDown); +LLGL_STATIC_ASSERT_ENUM(Key, End); +LLGL_STATIC_ASSERT_ENUM(Key, Home); +LLGL_STATIC_ASSERT_ENUM(Key, Left); +LLGL_STATIC_ASSERT_ENUM(Key, Up); +LLGL_STATIC_ASSERT_ENUM(Key, Right); +LLGL_STATIC_ASSERT_ENUM(Key, Down); +LLGL_STATIC_ASSERT_ENUM(Key, Select); +LLGL_STATIC_ASSERT_ENUM(Key, Print); +LLGL_STATIC_ASSERT_ENUM(Key, Exe); +LLGL_STATIC_ASSERT_ENUM(Key, Snapshot); +LLGL_STATIC_ASSERT_ENUM(Key, Insert); +LLGL_STATIC_ASSERT_ENUM(Key, Delete); +LLGL_STATIC_ASSERT_ENUM(Key, Help); +LLGL_STATIC_ASSERT_ENUM(Key, D0); +LLGL_STATIC_ASSERT_ENUM(Key, D1); +LLGL_STATIC_ASSERT_ENUM(Key, D2); +LLGL_STATIC_ASSERT_ENUM(Key, D3); +LLGL_STATIC_ASSERT_ENUM(Key, D4); +LLGL_STATIC_ASSERT_ENUM(Key, D5); +LLGL_STATIC_ASSERT_ENUM(Key, D6); +LLGL_STATIC_ASSERT_ENUM(Key, D7); +LLGL_STATIC_ASSERT_ENUM(Key, D8); +LLGL_STATIC_ASSERT_ENUM(Key, D9); +LLGL_STATIC_ASSERT_ENUM(Key, A); +LLGL_STATIC_ASSERT_ENUM(Key, B); +LLGL_STATIC_ASSERT_ENUM(Key, C); +LLGL_STATIC_ASSERT_ENUM(Key, D); +LLGL_STATIC_ASSERT_ENUM(Key, E); +LLGL_STATIC_ASSERT_ENUM(Key, F); +LLGL_STATIC_ASSERT_ENUM(Key, G); +LLGL_STATIC_ASSERT_ENUM(Key, H); +LLGL_STATIC_ASSERT_ENUM(Key, I); +LLGL_STATIC_ASSERT_ENUM(Key, J); +LLGL_STATIC_ASSERT_ENUM(Key, K); +LLGL_STATIC_ASSERT_ENUM(Key, L); +LLGL_STATIC_ASSERT_ENUM(Key, M); +LLGL_STATIC_ASSERT_ENUM(Key, N); +LLGL_STATIC_ASSERT_ENUM(Key, O); +LLGL_STATIC_ASSERT_ENUM(Key, P); +LLGL_STATIC_ASSERT_ENUM(Key, Q); +LLGL_STATIC_ASSERT_ENUM(Key, R); +LLGL_STATIC_ASSERT_ENUM(Key, S); +LLGL_STATIC_ASSERT_ENUM(Key, T); +LLGL_STATIC_ASSERT_ENUM(Key, U); +LLGL_STATIC_ASSERT_ENUM(Key, V); +LLGL_STATIC_ASSERT_ENUM(Key, W); +LLGL_STATIC_ASSERT_ENUM(Key, X); +LLGL_STATIC_ASSERT_ENUM(Key, Y); +LLGL_STATIC_ASSERT_ENUM(Key, Z); +LLGL_STATIC_ASSERT_ENUM(Key, LWin); +LLGL_STATIC_ASSERT_ENUM(Key, RWin); +LLGL_STATIC_ASSERT_ENUM(Key, Apps); +LLGL_STATIC_ASSERT_ENUM(Key, Sleep); +LLGL_STATIC_ASSERT_ENUM(Key, Keypad0); +LLGL_STATIC_ASSERT_ENUM(Key, Keypad1); +LLGL_STATIC_ASSERT_ENUM(Key, Keypad2); +LLGL_STATIC_ASSERT_ENUM(Key, Keypad3); +LLGL_STATIC_ASSERT_ENUM(Key, Keypad4); +LLGL_STATIC_ASSERT_ENUM(Key, Keypad5); +LLGL_STATIC_ASSERT_ENUM(Key, Keypad6); +LLGL_STATIC_ASSERT_ENUM(Key, Keypad7); +LLGL_STATIC_ASSERT_ENUM(Key, Keypad8); +LLGL_STATIC_ASSERT_ENUM(Key, Keypad9); +LLGL_STATIC_ASSERT_ENUM(Key, KeypadMultiply); +LLGL_STATIC_ASSERT_ENUM(Key, KeypadPlus); +LLGL_STATIC_ASSERT_ENUM(Key, KeypadSeparator); +LLGL_STATIC_ASSERT_ENUM(Key, KeypadMinus); +LLGL_STATIC_ASSERT_ENUM(Key, KeypadDecimal); +LLGL_STATIC_ASSERT_ENUM(Key, KeypadDivide); +LLGL_STATIC_ASSERT_ENUM(Key, F1); +LLGL_STATIC_ASSERT_ENUM(Key, F2); +LLGL_STATIC_ASSERT_ENUM(Key, F3); +LLGL_STATIC_ASSERT_ENUM(Key, F4); +LLGL_STATIC_ASSERT_ENUM(Key, F5); +LLGL_STATIC_ASSERT_ENUM(Key, F6); +LLGL_STATIC_ASSERT_ENUM(Key, F7); +LLGL_STATIC_ASSERT_ENUM(Key, F8); +LLGL_STATIC_ASSERT_ENUM(Key, F9); +LLGL_STATIC_ASSERT_ENUM(Key, F10); +LLGL_STATIC_ASSERT_ENUM(Key, F11); +LLGL_STATIC_ASSERT_ENUM(Key, F12); +LLGL_STATIC_ASSERT_ENUM(Key, F13); +LLGL_STATIC_ASSERT_ENUM(Key, F14); +LLGL_STATIC_ASSERT_ENUM(Key, F15); +LLGL_STATIC_ASSERT_ENUM(Key, F16); +LLGL_STATIC_ASSERT_ENUM(Key, F17); +LLGL_STATIC_ASSERT_ENUM(Key, F18); +LLGL_STATIC_ASSERT_ENUM(Key, F19); +LLGL_STATIC_ASSERT_ENUM(Key, F20); +LLGL_STATIC_ASSERT_ENUM(Key, F21); +LLGL_STATIC_ASSERT_ENUM(Key, F22); +LLGL_STATIC_ASSERT_ENUM(Key, F23); +LLGL_STATIC_ASSERT_ENUM(Key, F24); +LLGL_STATIC_ASSERT_ENUM(Key, NumLock); +LLGL_STATIC_ASSERT_ENUM(Key, ScrollLock); +LLGL_STATIC_ASSERT_ENUM(Key, LShift); +LLGL_STATIC_ASSERT_ENUM(Key, RShift); +LLGL_STATIC_ASSERT_ENUM(Key, LControl); +LLGL_STATIC_ASSERT_ENUM(Key, RControl); +LLGL_STATIC_ASSERT_ENUM(Key, LMenu); +LLGL_STATIC_ASSERT_ENUM(Key, RMenu); +LLGL_STATIC_ASSERT_ENUM(Key, BrowserBack); +LLGL_STATIC_ASSERT_ENUM(Key, BrowserForward); +LLGL_STATIC_ASSERT_ENUM(Key, BrowserRefresh); +LLGL_STATIC_ASSERT_ENUM(Key, BrowserStop); +LLGL_STATIC_ASSERT_ENUM(Key, BrowserSearch); +LLGL_STATIC_ASSERT_ENUM(Key, BrowserFavorits); +LLGL_STATIC_ASSERT_ENUM(Key, BrowserHome); +LLGL_STATIC_ASSERT_ENUM(Key, VolumeMute); +LLGL_STATIC_ASSERT_ENUM(Key, VolumeDown); +LLGL_STATIC_ASSERT_ENUM(Key, VolumeUp); +LLGL_STATIC_ASSERT_ENUM(Key, MediaNextTrack); +LLGL_STATIC_ASSERT_ENUM(Key, MediaPrevTrack); +LLGL_STATIC_ASSERT_ENUM(Key, MediaStop); +LLGL_STATIC_ASSERT_ENUM(Key, MediaPlayPause); +LLGL_STATIC_ASSERT_ENUM(Key, LaunchMail); +LLGL_STATIC_ASSERT_ENUM(Key, LaunchMediaSelect); +LLGL_STATIC_ASSERT_ENUM(Key, LaunchApp1); +LLGL_STATIC_ASSERT_ENUM(Key, LaunchApp2); +LLGL_STATIC_ASSERT_ENUM(Key, Plus); +LLGL_STATIC_ASSERT_ENUM(Key, Comma); +LLGL_STATIC_ASSERT_ENUM(Key, Minus); +LLGL_STATIC_ASSERT_ENUM(Key, Period); +LLGL_STATIC_ASSERT_ENUM(Key, Exponent); +LLGL_STATIC_ASSERT_ENUM(Key, Attn); +LLGL_STATIC_ASSERT_ENUM(Key, CrSel); +LLGL_STATIC_ASSERT_ENUM(Key, ExSel); +LLGL_STATIC_ASSERT_ENUM(Key, ErEOF); +LLGL_STATIC_ASSERT_ENUM(Key, Play); +LLGL_STATIC_ASSERT_ENUM(Key, Zoom); +LLGL_STATIC_ASSERT_ENUM(Key, NoName); +LLGL_STATIC_ASSERT_ENUM(Key, PA1); +LLGL_STATIC_ASSERT_ENUM(Key, OEMClear); +LLGL_STATIC_ASSERT_ENUM(Key, Any); + +LLGL_STATIC_ASSERT_ENUM(StorageBufferType, Undefined); +LLGL_STATIC_ASSERT_ENUM(StorageBufferType, TypedBuffer); +LLGL_STATIC_ASSERT_ENUM(StorageBufferType, StructuredBuffer); +LLGL_STATIC_ASSERT_ENUM(StorageBufferType, ByteAddressBuffer); +LLGL_STATIC_ASSERT_ENUM(StorageBufferType, RWTypedBuffer); +LLGL_STATIC_ASSERT_ENUM(StorageBufferType, RWStructuredBuffer); +LLGL_STATIC_ASSERT_ENUM(StorageBufferType, RWByteAddressBuffer); +LLGL_STATIC_ASSERT_ENUM(StorageBufferType, AppendStructuredBuffer); +LLGL_STATIC_ASSERT_ENUM(StorageBufferType, ConsumeStructuredBuffer); + +LLGL_STATIC_ASSERT_ENUM(QueryType, SamplesPassed); +LLGL_STATIC_ASSERT_ENUM(QueryType, AnySamplesPassed); +LLGL_STATIC_ASSERT_ENUM(QueryType, AnySamplesPassedConservative); +LLGL_STATIC_ASSERT_ENUM(QueryType, TimeElapsed); +LLGL_STATIC_ASSERT_ENUM(QueryType, StreamOutPrimitivesWritten); +LLGL_STATIC_ASSERT_ENUM(QueryType, StreamOutOverflow); +LLGL_STATIC_ASSERT_ENUM(QueryType, PipelineStatistics); + +LLGL_STATIC_ASSERT_ENUM(AttachmentLoadOp, Undefined); +LLGL_STATIC_ASSERT_ENUM(AttachmentLoadOp, Load); +LLGL_STATIC_ASSERT_ENUM(AttachmentLoadOp, Clear); + +LLGL_STATIC_ASSERT_ENUM(AttachmentStoreOp, Undefined); +LLGL_STATIC_ASSERT_ENUM(AttachmentStoreOp, Store); + + +/* ----- Flags ----- */ + +LLGL_STATIC_ASSERT_FLAG(CommandBuffer, Secondary); +LLGL_STATIC_ASSERT_FLAG(CommandBuffer, MultiSubmit); +LLGL_STATIC_ASSERT_FLAG(CommandBuffer, ImmediateSubmit); + +LLGL_STATIC_ASSERT_FLAG(Clear, Color); +LLGL_STATIC_ASSERT_FLAG(Clear, Depth); +LLGL_STATIC_ASSERT_FLAG(Clear, Stencil); +LLGL_STATIC_ASSERT_FLAG(Clear, ColorDepth); +LLGL_STATIC_ASSERT_FLAG(Clear, DepthStencil); +LLGL_STATIC_ASSERT_FLAG(Clear, All); + +LLGL_STATIC_ASSERT_FLAG(Format, HasDepth); +LLGL_STATIC_ASSERT_FLAG(Format, HasStencil); +LLGL_STATIC_ASSERT_FLAG(Format, IsColorSpace_sRGB); +LLGL_STATIC_ASSERT_FLAG(Format, IsCompressed); +LLGL_STATIC_ASSERT_FLAG(Format, IsNormalized); +LLGL_STATIC_ASSERT_FLAG(Format, IsInteger); +LLGL_STATIC_ASSERT_FLAG(Format, IsUnsigned); +LLGL_STATIC_ASSERT_FLAG(Format, IsPacked); +LLGL_STATIC_ASSERT_FLAG(Format, SupportsRenderTarget); +LLGL_STATIC_ASSERT_FLAG(Format, SupportsMips); +LLGL_STATIC_ASSERT_FLAG(Format, SupportsGenerateMips); +LLGL_STATIC_ASSERT_FLAG(Format, SupportsTexture1D); +LLGL_STATIC_ASSERT_FLAG(Format, SupportsTexture2D); +LLGL_STATIC_ASSERT_FLAG(Format, SupportsTexture3D); +LLGL_STATIC_ASSERT_FLAG(Format, SupportsTextureCube); +LLGL_STATIC_ASSERT_FLAG(Format, SupportsVertex); +LLGL_STATIC_ASSERT_FLAG(Format, IsUnsignedInteger); +LLGL_STATIC_ASSERT_FLAG(Format, HasDepthStencil); + +LLGL_STATIC_ASSERT_FLAG(Barrier, StorageBuffer); +LLGL_STATIC_ASSERT_FLAG(Barrier, StorageTexture); +LLGL_STATIC_ASSERT_FLAG(Barrier, Storage); + +LLGL_STATIC_ASSERT_FLAG(ShaderCompile, Debug); +LLGL_STATIC_ASSERT_FLAG(ShaderCompile, NoOptimization); +LLGL_STATIC_ASSERT_FLAG(ShaderCompile, OptimizationLevel1); +LLGL_STATIC_ASSERT_FLAG(ShaderCompile, OptimizationLevel2); +LLGL_STATIC_ASSERT_FLAG(ShaderCompile, OptimizationLevel3); +LLGL_STATIC_ASSERT_FLAG(ShaderCompile, WarningsAreErrors); +LLGL_STATIC_ASSERT_FLAG(ShaderCompile, PatchClippingOrigin); +LLGL_STATIC_ASSERT_FLAG(ShaderCompile, SeparateShader); + +LLGL_STATIC_ASSERT_FLAG(Stage, VertexStage); +LLGL_STATIC_ASSERT_FLAG(Stage, TessControlStage); +LLGL_STATIC_ASSERT_FLAG(Stage, TessEvaluationStage); +LLGL_STATIC_ASSERT_FLAG(Stage, GeometryStage); +LLGL_STATIC_ASSERT_FLAG(Stage, FragmentStage); +LLGL_STATIC_ASSERT_FLAG(Stage, ComputeStage); +LLGL_STATIC_ASSERT_FLAG(Stage, AllTessStages); +LLGL_STATIC_ASSERT_FLAG(Stage, AllGraphicsStages); +LLGL_STATIC_ASSERT_FLAG(Stage, AllStages); + +LLGL_STATIC_ASSERT_FLAG(Bind, VertexBuffer); +LLGL_STATIC_ASSERT_FLAG(Bind, IndexBuffer); +LLGL_STATIC_ASSERT_FLAG(Bind, ConstantBuffer); +LLGL_STATIC_ASSERT_FLAG(Bind, StreamOutputBuffer); +LLGL_STATIC_ASSERT_FLAG(Bind, IndirectBuffer); +LLGL_STATIC_ASSERT_FLAG(Bind, Sampled); +LLGL_STATIC_ASSERT_FLAG(Bind, Storage); +LLGL_STATIC_ASSERT_FLAG(Bind, ColorAttachment); +LLGL_STATIC_ASSERT_FLAG(Bind, DepthStencilAttachment); +LLGL_STATIC_ASSERT_FLAG(Bind, CombinedSampler); +LLGL_STATIC_ASSERT_FLAG(Bind, CopySrc); +LLGL_STATIC_ASSERT_FLAG(Bind, CopyDst); + +LLGL_STATIC_ASSERT_FLAG(CPUAccess, Read); +LLGL_STATIC_ASSERT_FLAG(CPUAccess, Write); + +LLGL_STATIC_ASSERT_FLAG(Misc, DynamicUsage); +LLGL_STATIC_ASSERT_FLAG(Misc, FixedSamples); +LLGL_STATIC_ASSERT_FLAG(Misc, GenerateMips); +LLGL_STATIC_ASSERT_FLAG(Misc, NoInitialData); +LLGL_STATIC_ASSERT_FLAG(Misc, Append); +LLGL_STATIC_ASSERT_FLAG(Misc, Counter); + + +/* ----- Structures ----- */ + +LLGL_STATIC_ASSERT_SIZE(Extent2D); +LLGL_STATIC_ASSERT_OFFSET(Extent2D, width); +LLGL_STATIC_ASSERT_OFFSET(Extent2D, height); + +LLGL_STATIC_ASSERT_SIZE(Extent3D); +LLGL_STATIC_ASSERT_OFFSET(Extent3D, width); +LLGL_STATIC_ASSERT_OFFSET(Extent3D, height); +LLGL_STATIC_ASSERT_OFFSET(Extent3D, depth); + +LLGL_STATIC_ASSERT_SIZE(Offset2D); +LLGL_STATIC_ASSERT_OFFSET(Offset2D, x); +LLGL_STATIC_ASSERT_OFFSET(Offset2D, y); + +LLGL_STATIC_ASSERT_SIZE(Offset3D); +LLGL_STATIC_ASSERT_OFFSET(Offset3D, x); +LLGL_STATIC_ASSERT_OFFSET(Offset3D, y); +LLGL_STATIC_ASSERT_OFFSET(Offset3D, z); + +LLGL_STATIC_ASSERT_SIZE(Viewport); +LLGL_STATIC_ASSERT_OFFSET(Viewport, x); +LLGL_STATIC_ASSERT_OFFSET(Viewport, y); +LLGL_STATIC_ASSERT_OFFSET(Viewport, width); +LLGL_STATIC_ASSERT_OFFSET(Viewport, height); +LLGL_STATIC_ASSERT_OFFSET(Viewport, minDepth); +LLGL_STATIC_ASSERT_OFFSET(Viewport, maxDepth); + +LLGL_STATIC_ASSERT_SIZE(Scissor); +LLGL_STATIC_ASSERT_OFFSET(Scissor, x); +LLGL_STATIC_ASSERT_OFFSET(Scissor, y); +LLGL_STATIC_ASSERT_OFFSET(Scissor, width); +LLGL_STATIC_ASSERT_OFFSET(Scissor, height); + +LLGL_STATIC_ASSERT_SIZE(DepthDescriptor); +LLGL_STATIC_ASSERT_OFFSET(DepthDescriptor, testEnabled); +LLGL_STATIC_ASSERT_OFFSET(DepthDescriptor, writeEnabled); +LLGL_STATIC_ASSERT_OFFSET(DepthDescriptor, compareOp); + +LLGL_STATIC_ASSERT_SIZE(StencilFaceDescriptor); +LLGL_STATIC_ASSERT_OFFSET(StencilFaceDescriptor, stencilFailOp); +LLGL_STATIC_ASSERT_OFFSET(StencilFaceDescriptor, depthFailOp); +LLGL_STATIC_ASSERT_OFFSET(StencilFaceDescriptor, depthPassOp); +LLGL_STATIC_ASSERT_OFFSET(StencilFaceDescriptor, compareOp); +LLGL_STATIC_ASSERT_OFFSET(StencilFaceDescriptor, readMask); +LLGL_STATIC_ASSERT_OFFSET(StencilFaceDescriptor, writeMask); +LLGL_STATIC_ASSERT_OFFSET(StencilFaceDescriptor, reference); + +LLGL_STATIC_ASSERT_SIZE(StencilDescriptor); +LLGL_STATIC_ASSERT_OFFSET(StencilDescriptor, testEnabled); +LLGL_STATIC_ASSERT_OFFSET(StencilDescriptor, referenceDynamic); +LLGL_STATIC_ASSERT_OFFSET(StencilDescriptor, front); +LLGL_STATIC_ASSERT_OFFSET(StencilDescriptor, back); + +LLGL_STATIC_ASSERT_SIZE(DepthBiasDescriptor); +LLGL_STATIC_ASSERT_OFFSET(DepthBiasDescriptor, constantFactor); +LLGL_STATIC_ASSERT_OFFSET(DepthBiasDescriptor, slopeFactor); +LLGL_STATIC_ASSERT_OFFSET(DepthBiasDescriptor, clamp); + +LLGL_STATIC_ASSERT_SIZE(RasterizerDescriptor); +LLGL_STATIC_ASSERT_OFFSET(RasterizerDescriptor, polygonMode); +LLGL_STATIC_ASSERT_OFFSET(RasterizerDescriptor, cullMode); +LLGL_STATIC_ASSERT_OFFSET(RasterizerDescriptor, depthBias); +LLGL_STATIC_ASSERT_OFFSET(RasterizerDescriptor, frontCCW); +LLGL_STATIC_ASSERT_OFFSET(RasterizerDescriptor, discardEnabled); +LLGL_STATIC_ASSERT_OFFSET(RasterizerDescriptor, depthClampEnabled); +LLGL_STATIC_ASSERT_OFFSET(RasterizerDescriptor, scissorTestEnabled); +LLGL_STATIC_ASSERT_OFFSET(RasterizerDescriptor, multiSampleEnabled); +LLGL_STATIC_ASSERT_OFFSET(RasterizerDescriptor, antiAliasedLineEnabled); +LLGL_STATIC_ASSERT_OFFSET(RasterizerDescriptor, conservativeRasterization); +LLGL_STATIC_ASSERT_OFFSET(RasterizerDescriptor, lineWidth); + +LLGL_STATIC_ASSERT_SIZE(BlendTargetDescriptor); +LLGL_STATIC_ASSERT_OFFSET(BlendTargetDescriptor, blendEnabled); +LLGL_STATIC_ASSERT_OFFSET(BlendTargetDescriptor, srcColor); +LLGL_STATIC_ASSERT_OFFSET(BlendTargetDescriptor, dstColor); +LLGL_STATIC_ASSERT_OFFSET(BlendTargetDescriptor, colorArithmetic); +LLGL_STATIC_ASSERT_OFFSET(BlendTargetDescriptor, srcAlpha); +LLGL_STATIC_ASSERT_OFFSET(BlendTargetDescriptor, dstAlpha); +LLGL_STATIC_ASSERT_OFFSET(BlendTargetDescriptor, alphaArithmetic); +LLGL_STATIC_ASSERT_OFFSET(BlendTargetDescriptor, colorMask); + +LLGL_STATIC_ASSERT_SIZE(BlendDescriptor); +LLGL_STATIC_ASSERT_OFFSET(BlendDescriptor, alphaToCoverageEnabled); +LLGL_STATIC_ASSERT_OFFSET(BlendDescriptor, independentBlendEnabled); +LLGL_STATIC_ASSERT_OFFSET(BlendDescriptor, sampleMask); +LLGL_STATIC_ASSERT_OFFSET(BlendDescriptor, logicOp); +LLGL_STATIC_ASSERT_OFFSET(BlendDescriptor, blendFactor); +LLGL_STATIC_ASSERT_OFFSET(BlendDescriptor, blendFactorDynamic); +LLGL_STATIC_ASSERT_OFFSET(BlendDescriptor, targets); + +LLGL_STATIC_ASSERT_SIZE(TessellationDescriptor); +LLGL_STATIC_ASSERT_OFFSET(TessellationDescriptor, partition); +LLGL_STATIC_ASSERT_OFFSET(TessellationDescriptor, indexFormat); +LLGL_STATIC_ASSERT_OFFSET(TessellationDescriptor, maxTessFactor); +LLGL_STATIC_ASSERT_OFFSET(TessellationDescriptor, outputWindingCCW); + +LLGL_STATIC_ASSERT_SIZE(ClearValue); +LLGL_STATIC_ASSERT_OFFSET(ClearValue, color); +LLGL_STATIC_ASSERT_OFFSET(ClearValue, depth); +LLGL_STATIC_ASSERT_OFFSET(ClearValue, stencil); + +LLGL_STATIC_ASSERT_SIZE(AttachmentClear); +LLGL_STATIC_ASSERT_OFFSET(AttachmentClear, flags); +LLGL_STATIC_ASSERT_OFFSET(AttachmentClear, colorAttachment); +LLGL_STATIC_ASSERT_OFFSET(AttachmentClear, clearValue); + +LLGL_STATIC_ASSERT_SIZE(CommandBufferDescriptor); +LLGL_STATIC_ASSERT_OFFSET(CommandBufferDescriptor, flags); +LLGL_STATIC_ASSERT_OFFSET(CommandBufferDescriptor, numNativeBuffers); +LLGL_STATIC_ASSERT_OFFSET(CommandBufferDescriptor, minStagingPoolSize); + +LLGL_STATIC_ASSERT_SIZE(FormatAttributes); +LLGL_STATIC_ASSERT_OFFSET(FormatAttributes, bitSize); +LLGL_STATIC_ASSERT_OFFSET(FormatAttributes, blockWidth); +LLGL_STATIC_ASSERT_OFFSET(FormatAttributes, blockHeight); +LLGL_STATIC_ASSERT_OFFSET(FormatAttributes, components); +LLGL_STATIC_ASSERT_OFFSET(FormatAttributes, format); +LLGL_STATIC_ASSERT_OFFSET(FormatAttributes, dataType); +LLGL_STATIC_ASSERT_OFFSET(FormatAttributes, flags); + +LLGL_STATIC_ASSERT_SIZE(TextureSwizzleRGBA); +//LLGL_STATIC_ASSERT_OFFSET(TextureSwizzleRGBA, r); +//LLGL_STATIC_ASSERT_OFFSET(TextureSwizzleRGBA, g); +//LLGL_STATIC_ASSERT_OFFSET(TextureSwizzleRGBA, b); +//LLGL_STATIC_ASSERT_OFFSET(TextureSwizzleRGBA, a); + +LLGL_STATIC_ASSERT_SIZE(TextureSubresource); +LLGL_STATIC_ASSERT_OFFSET(TextureSubresource, baseArrayLayer); +LLGL_STATIC_ASSERT_OFFSET(TextureSubresource, numArrayLayers); +LLGL_STATIC_ASSERT_OFFSET(TextureSubresource, baseMipLevel); +LLGL_STATIC_ASSERT_OFFSET(TextureSubresource, numMipLevels); + +LLGL_STATIC_ASSERT_SIZE(TextureLocation); +LLGL_STATIC_ASSERT_OFFSET(TextureLocation, offset); +LLGL_STATIC_ASSERT_OFFSET(TextureLocation, arrayLayer); +LLGL_STATIC_ASSERT_OFFSET(TextureLocation, mipLevel); + +LLGL_STATIC_ASSERT_SIZE(TextureRegion); +LLGL_STATIC_ASSERT_OFFSET(TextureRegion, subresource); +LLGL_STATIC_ASSERT_OFFSET(TextureRegion, offset); +LLGL_STATIC_ASSERT_OFFSET(TextureRegion, extent); + +LLGL_STATIC_ASSERT_SIZE(TextureDescriptor); +LLGL_STATIC_ASSERT_OFFSET(TextureDescriptor, type); +LLGL_STATIC_ASSERT_OFFSET(TextureDescriptor, bindFlags); +LLGL_STATIC_ASSERT_OFFSET(TextureDescriptor, miscFlags); +LLGL_STATIC_ASSERT_OFFSET(TextureDescriptor, format); +LLGL_STATIC_ASSERT_OFFSET(TextureDescriptor, extent); +LLGL_STATIC_ASSERT_OFFSET(TextureDescriptor, arrayLayers); +LLGL_STATIC_ASSERT_OFFSET(TextureDescriptor, mipLevels); +LLGL_STATIC_ASSERT_OFFSET(TextureDescriptor, samples); +LLGL_STATIC_ASSERT_OFFSET(TextureDescriptor, clearValue); + +LLGL_STATIC_ASSERT_SIZE(TextureViewDescriptor); +LLGL_STATIC_ASSERT_OFFSET(TextureViewDescriptor, type); +LLGL_STATIC_ASSERT_OFFSET(TextureViewDescriptor, format); +LLGL_STATIC_ASSERT_OFFSET(TextureViewDescriptor, subresource); +LLGL_STATIC_ASSERT_OFFSET(TextureViewDescriptor, swizzle); + +LLGL_STATIC_ASSERT_SIZE(SubresourceFootprint); +LLGL_STATIC_ASSERT_OFFSET(SubresourceFootprint, size); +LLGL_STATIC_ASSERT_OFFSET(SubresourceFootprint, rowAlignment); +LLGL_STATIC_ASSERT_OFFSET(SubresourceFootprint, rowSize); +LLGL_STATIC_ASSERT_OFFSET(SubresourceFootprint, rowStride); +LLGL_STATIC_ASSERT_OFFSET(SubresourceFootprint, layerSize); +LLGL_STATIC_ASSERT_OFFSET(SubresourceFootprint, layerStride); + +LLGL_STATIC_ASSERT_SIZE(SwapChainDescriptor); +LLGL_STATIC_ASSERT_OFFSET(SwapChainDescriptor, resolution); +LLGL_STATIC_ASSERT_OFFSET(SwapChainDescriptor, colorBits); +LLGL_STATIC_ASSERT_OFFSET(SwapChainDescriptor, depthBits); +LLGL_STATIC_ASSERT_OFFSET(SwapChainDescriptor, stencilBits); +LLGL_STATIC_ASSERT_OFFSET(SwapChainDescriptor, samples); +LLGL_STATIC_ASSERT_OFFSET(SwapChainDescriptor, swapBuffers); +LLGL_STATIC_ASSERT_OFFSET(SwapChainDescriptor, fullscreen); + +LLGL_STATIC_ASSERT_SIZE(RenderingFeatures); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasRenderTargets); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, has3DTextures); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasCubeTextures); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasArrayTextures); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasCubeArrayTextures); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasMultiSampleTextures); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasMultiSampleArrayTextures); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasTextureViews); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasTextureViewSwizzle); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasBufferViews); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasSamplers); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasConstantBuffers); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasStorageBuffers); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasUniforms); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasGeometryShaders); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasTessellationShaders); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasTessellatorStage); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasComputeShaders); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasInstancing); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasOffsetInstancing); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasIndirectDrawing); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasViewportArrays); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasConservativeRasterization); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasStreamOutputs); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasLogicOp); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasPipelineStatistics); +LLGL_STATIC_ASSERT_OFFSET(RenderingFeatures, hasRenderCondition); + +LLGL_STATIC_ASSERT_SIZE(RenderingLimits); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, lineWidthRange); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxTextureArrayLayers); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxColorAttachments); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxPatchVertices); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, max1DTextureSize); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, max2DTextureSize); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, max3DTextureSize); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxCubeTextureSize); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxAnisotropy); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxComputeShaderWorkGroups); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxComputeShaderWorkGroupSize); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxViewports); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxViewportSize); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxBufferSize); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxConstantBufferSize); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxStreamOutputs); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, maxTessFactor); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, minConstantBufferAlignment); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, minSampledBufferAlignment); +LLGL_STATIC_ASSERT_OFFSET(RenderingLimits, minStorageBufferAlignment); + +LLGL_STATIC_ASSERT_SIZE(SrcImageDescriptor); +LLGL_STATIC_ASSERT_OFFSET(SrcImageDescriptor, format); +LLGL_STATIC_ASSERT_OFFSET(SrcImageDescriptor, dataType); +LLGL_STATIC_ASSERT_OFFSET(SrcImageDescriptor, data); +LLGL_STATIC_ASSERT_OFFSET(SrcImageDescriptor, dataSize); + +LLGL_STATIC_ASSERT_SIZE(DstImageDescriptor); +LLGL_STATIC_ASSERT_OFFSET(DstImageDescriptor, format); +LLGL_STATIC_ASSERT_OFFSET(DstImageDescriptor, dataType); +LLGL_STATIC_ASSERT_OFFSET(DstImageDescriptor, data); +LLGL_STATIC_ASSERT_OFFSET(DstImageDescriptor, dataSize); + +LLGL_STATIC_ASSERT_SIZE(SamplerDescriptor); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, addressModeU); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, addressModeV); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, addressModeW); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, minFilter); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, magFilter); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, mipMapFilter); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, mipMapEnabled); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, mipMapLODBias); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, minLOD); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, maxLOD); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, maxAnisotropy); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, compareEnabled); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, compareOp); +LLGL_STATIC_ASSERT_OFFSET(SamplerDescriptor, borderColor); + +LLGL_STATIC_ASSERT_SIZE(ResourceViewDescriptor); +LLGL_STATIC_ASSERT_OFFSET(ResourceViewDescriptor, resource); +LLGL_STATIC_ASSERT_OFFSET(ResourceViewDescriptor, textureView); +LLGL_STATIC_ASSERT_OFFSET(ResourceViewDescriptor, bufferView); +LLGL_STATIC_ASSERT_OFFSET(ResourceViewDescriptor, initialCount); + +LLGL_STATIC_ASSERT_SIZE(ResourceHeapDescriptor); +LLGL_STATIC_ASSERT_OFFSET(ResourceHeapDescriptor, pipelineLayout); +LLGL_STATIC_ASSERT_OFFSET(ResourceHeapDescriptor, numResourceViews); +LLGL_STATIC_ASSERT_OFFSET(ResourceHeapDescriptor, barrierFlags); + +LLGL_STATIC_ASSERT_SIZE(ShaderMacro); +LLGL_STATIC_ASSERT_OFFSET(ShaderMacro, name); +LLGL_STATIC_ASSERT_OFFSET(ShaderMacro, definition); + +LLGL_STATIC_ASSERT_SIZE(ComputeShaderAttributes); +LLGL_STATIC_ASSERT_OFFSET(ComputeShaderAttributes, workGroupSize); + +LLGL_STATIC_ASSERT_SIZE(AttachmentDescriptor); +LLGL_STATIC_ASSERT_OFFSET(AttachmentDescriptor, format); +LLGL_STATIC_ASSERT_OFFSET(AttachmentDescriptor, texture); +LLGL_STATIC_ASSERT_OFFSET(AttachmentDescriptor, mipLevel); +LLGL_STATIC_ASSERT_OFFSET(AttachmentDescriptor, arrayLayer); + +LLGL_STATIC_ASSERT_SIZE(RenderTargetDescriptor); +LLGL_STATIC_ASSERT_OFFSET(RenderTargetDescriptor, renderPass); +LLGL_STATIC_ASSERT_OFFSET(RenderTargetDescriptor, resolution); +LLGL_STATIC_ASSERT_OFFSET(RenderTargetDescriptor, samples); +LLGL_STATIC_ASSERT_OFFSET(RenderTargetDescriptor, colorAttachments); +LLGL_STATIC_ASSERT_OFFSET(RenderTargetDescriptor, resolveAttachments); +LLGL_STATIC_ASSERT_OFFSET(RenderTargetDescriptor, depthStencilAttachment); + +LLGL_STATIC_ASSERT_SIZE(BindingSlot); +LLGL_STATIC_ASSERT_OFFSET(BindingSlot, index); +LLGL_STATIC_ASSERT_OFFSET(BindingSlot, set); + +LLGL_STATIC_ASSERT_SIZE(WindowBehavior); +LLGL_STATIC_ASSERT_OFFSET(WindowBehavior, disableClearOnResize); +LLGL_STATIC_ASSERT_OFFSET(WindowBehavior, moveAndResizeTimerID); + +LLGL_STATIC_ASSERT_SIZE(QueryPipelineStatistics); +LLGL_STATIC_ASSERT_OFFSET(QueryPipelineStatistics, inputAssemblyVertices); +LLGL_STATIC_ASSERT_OFFSET(QueryPipelineStatistics, inputAssemblyPrimitives); +LLGL_STATIC_ASSERT_OFFSET(QueryPipelineStatistics, vertexShaderInvocations); +LLGL_STATIC_ASSERT_OFFSET(QueryPipelineStatistics, geometryShaderInvocations); +LLGL_STATIC_ASSERT_OFFSET(QueryPipelineStatistics, geometryShaderPrimitives); +LLGL_STATIC_ASSERT_OFFSET(QueryPipelineStatistics, clippingInvocations); +LLGL_STATIC_ASSERT_OFFSET(QueryPipelineStatistics, clippingPrimitives); +LLGL_STATIC_ASSERT_OFFSET(QueryPipelineStatistics, fragmentShaderInvocations); +LLGL_STATIC_ASSERT_OFFSET(QueryPipelineStatistics, tessControlShaderInvocations); +LLGL_STATIC_ASSERT_OFFSET(QueryPipelineStatistics, tessEvaluationShaderInvocations); +LLGL_STATIC_ASSERT_OFFSET(QueryPipelineStatistics, computeShaderInvocations); + +LLGL_STATIC_ASSERT_SIZE(QueryHeapDescriptor); +LLGL_STATIC_ASSERT_OFFSET(QueryHeapDescriptor, type); +LLGL_STATIC_ASSERT_OFFSET(QueryHeapDescriptor, numQueries); +LLGL_STATIC_ASSERT_OFFSET(QueryHeapDescriptor, renderCondition); + +LLGL_STATIC_ASSERT_SIZE(AttachmentFormatDescriptor); +LLGL_STATIC_ASSERT_OFFSET(AttachmentFormatDescriptor, format); +LLGL_STATIC_ASSERT_OFFSET(AttachmentFormatDescriptor, loadOp); +LLGL_STATIC_ASSERT_OFFSET(AttachmentFormatDescriptor, storeOp); + +LLGL_STATIC_ASSERT_SIZE(RenderPassDescriptor); +LLGL_STATIC_ASSERT_OFFSET(RenderPassDescriptor, colorAttachments); +LLGL_STATIC_ASSERT_OFFSET(RenderPassDescriptor, depthAttachment); +LLGL_STATIC_ASSERT_OFFSET(RenderPassDescriptor, stencilAttachment); +LLGL_STATIC_ASSERT_OFFSET(RenderPassDescriptor, samples); + +LLGL_STATIC_ASSERT_SIZE(DisplayModeDescriptor); +LLGL_STATIC_ASSERT_OFFSET(DisplayModeDescriptor, resolution); +LLGL_STATIC_ASSERT_OFFSET(DisplayModeDescriptor, refreshRate); + +LLGL_STATIC_ASSERT_SIZE(DrawIndirectArguments); +LLGL_STATIC_ASSERT_OFFSET(DrawIndirectArguments, numVertices); +LLGL_STATIC_ASSERT_OFFSET(DrawIndirectArguments, numInstances); +LLGL_STATIC_ASSERT_OFFSET(DrawIndirectArguments, firstVertex); +LLGL_STATIC_ASSERT_OFFSET(DrawIndirectArguments, firstInstance); + +LLGL_STATIC_ASSERT_SIZE(DrawIndexedIndirectArguments); +LLGL_STATIC_ASSERT_OFFSET(DrawIndexedIndirectArguments, numIndices); +LLGL_STATIC_ASSERT_OFFSET(DrawIndexedIndirectArguments, numInstances); +LLGL_STATIC_ASSERT_OFFSET(DrawIndexedIndirectArguments, firstIndex); +LLGL_STATIC_ASSERT_OFFSET(DrawIndexedIndirectArguments, vertexOffset); +LLGL_STATIC_ASSERT_OFFSET(DrawIndexedIndirectArguments, firstInstance); + +LLGL_STATIC_ASSERT_SIZE(DrawPatchIndirectArguments); +LLGL_STATIC_ASSERT_OFFSET(DrawPatchIndirectArguments, numPatches); +LLGL_STATIC_ASSERT_OFFSET(DrawPatchIndirectArguments, numInstances); +LLGL_STATIC_ASSERT_OFFSET(DrawPatchIndirectArguments, firstPatch); +LLGL_STATIC_ASSERT_OFFSET(DrawPatchIndirectArguments, firstInstance); + +LLGL_STATIC_ASSERT_SIZE(DispatchIndirectArguments); +LLGL_STATIC_ASSERT_OFFSET(DispatchIndirectArguments, numThreadGroups); + + +// } /namespace LLGL + + + +// ================================================================================ diff --git a/wrapper/C99/C99Window.cpp b/wrapper/C99/C99Window.cpp new file mode 100644 index 0000000000..06732d189e --- /dev/null +++ b/wrapper/C99/C99Window.cpp @@ -0,0 +1,319 @@ +/* + * C99Window.cpp + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +#include +#include +#include "C99Internal.h" +#include "../sources/Core/CoreUtils.h" +#include +#include +#include +#include + + +// namespace LLGL { + + +using namespace LLGL; + +#define LLGL_CALLBACK_WRAPPER(FUNC, ...) \ + if (callbacks_.FUNC != NULL) { callbacks_.FUNC(LLGLWindow{ &sender }, __VA_ARGS__); } + +class InternalWindowEventListener final : public Window::EventListener +{ + + LLGLWindowEventListener callbacks_; + + public: + + InternalWindowEventListener(const LLGLWindowEventListener* callbacks) + { + memcpy(&callbacks_, callbacks, sizeof(LLGLWindowEventListener)); + } + + void OnProcessEvents(Window& sender) override + { + LLGL_CALLBACK_WRAPPER(onProcessEvents); + } + + void OnQuit(Window& sender, bool& veto) override + { + LLGL_CALLBACK_WRAPPER(onQuit, &veto); + } + + void OnKeyDown(Window& sender, Key keyCode) override + { + LLGL_CALLBACK_WRAPPER(onKeyDown, (LLGLKey)keyCode); + } + + void OnKeyUp(Window& sender, Key keyCode) override + { + LLGL_CALLBACK_WRAPPER(onKeyUp, (LLGLKey)keyCode); + } + + void OnDoubleClick(Window& sender, Key keyCode) override + { + LLGL_CALLBACK_WRAPPER(onDoubleClick, (LLGLKey)keyCode); + } + + void OnChar(Window& sender, wchar_t chr) override + { + LLGL_CALLBACK_WRAPPER(onChar, chr); + } + + void OnWheelMotion(Window& sender, int motion) override + { + LLGL_CALLBACK_WRAPPER(onWheelMotion, motion); + } + + void OnLocalMotion(Window& sender, const Offset2D& position) override + { + LLGL_CALLBACK_WRAPPER(onLocalMotion, (const LLGLOffset2D*)&position); + } + + void OnGlobalMotion(Window& sender, const Offset2D& motion) override + { + LLGL_CALLBACK_WRAPPER(onGlobalMotion, (const LLGLOffset2D*)&motion); + } + + void OnResize(Window& sender, const Extent2D& clientAreaSize) override + { + LLGL_CALLBACK_WRAPPER(onResize, (const LLGLExtent2D*)&clientAreaSize); + } + + void OnGetFocus(Window& sender) override + { + LLGL_CALLBACK_WRAPPER(onGetFocus); + } + + void OnLostFocus(Window& sender) override + { + LLGL_CALLBACK_WRAPPER(onLostFocus); + } + + void OnTimer(Window& sender, std::uint32_t timerID) override + { + LLGL_CALLBACK_WRAPPER(onTimer, timerID); + } + +}; + +#undef LLGL_CALLBACK_WRAPPER + +static std::vector> g_Windows; + +static void ConvertWindowDesc(WindowDescriptor& dst, const LLGLWindowDescriptor& src) +{ + dst.title = src.title; + dst.position = { src.position.x, src.position.y }; + dst.size = { src.size.width, src.size.height }; + dst.visible = src.visible; + dst.borderless = src.borderless; + dst.resizable = src.resizable; + dst.acceptDropFiles = src.acceptDropFiles; + dst.centered = src.centered; + dst.windowContext = src.windowContext; +} + +static void ConvertWindowDesc(LLGLWindowDescriptor& dst, const WindowDescriptor& src) +{ + static thread_local std::string internalTitle; + internalTitle = src.title.c_str(); + dst.title = internalTitle.c_str(); + dst.position = { src.position.x, src.position.y }; + dst.size = { src.size.width, src.size.height }; + dst.visible = src.visible; + dst.borderless = src.borderless; + dst.resizable = src.resizable; + dst.acceptDropFiles = src.acceptDropFiles; + dst.centered = src.centered; + dst.windowContext = src.windowContext; +} + +LLGL_C_EXPORT LLGLWindow llglCreateWindow(const LLGLWindowDescriptor* windowDesc) +{ + LLGL_ASSERT_PTR(windowDesc); + WindowDescriptor internalWindowDesc; + ConvertWindowDesc(internalWindowDesc, *windowDesc); + g_Windows.push_back(Window::Create(internalWindowDesc)); + return LLGLWindow{ g_Windows.back().get() }; +} + +LLGL_C_EXPORT void llglReleaseWindow(LLGLWindow window) +{ + RemoveFromListIf( + g_Windows, + [window](const std::unique_ptr& entry) -> bool + { + return (entry.get() == LLGL_PTR(Window, window)); + } + ); +} + +LLGL_C_EXPORT void llglSetWindowPosition(LLGLWindow window, const LLGLOffset2D* position) +{ + LLGL_PTR(Window, window)->SetPosition(*(const Offset2D*)position); +} + +LLGL_C_EXPORT void llglGetWindowPosition(LLGLWindow window, LLGLOffset2D* outPosition) +{ + Offset2D position = LLGL_PTR(Window, window)->GetPosition(); + outPosition->x = position.x; + outPosition->y = position.y; +} + +LLGL_C_EXPORT void llglSetWindowSize(LLGLWindow window, const LLGLExtent2D* size, bool useClientArea) +{ + LLGL_PTR(Window, window)->SetSize(*(const Extent2D*)size, useClientArea); +} + +LLGL_C_EXPORT void llglGetWindowSize(LLGLWindow window, LLGLExtent2D* outSize, bool useClientArea) +{ + Extent2D size = LLGL_PTR(Window, window)->GetSize(useClientArea); + outSize->width = size.width; + outSize->height = size.height; +} + +LLGL_C_EXPORT void llglSetWindowTitle(LLGLWindow window, const wchar_t* title) +{ + LLGL_PTR(Window, window)->SetTitle(title); +} + +LLGL_C_EXPORT size_t llglGetWindowTitle(LLGLWindow window, size_t outTitleLength, wchar_t* outTitle) +{ + UTF8String title = LLGL_PTR(Window, window)->GetTitle(); + SmallVector titleUTF16 = title.to_utf16(); + if (outTitle != nullptr) + { + outTitleLength = std::min(outTitleLength, titleUTF16.size()); + ::memcpy(outTitle, titleUTF16.data(), outTitleLength * sizeof(wchar_t)); + } + return titleUTF16.size(); +} + +LLGL_C_EXPORT void llglShowWindow(LLGLWindow window, bool show) +{ + LLGL_PTR(Window, window)->Show(show); +} + +LLGL_C_EXPORT bool llglIsWindowShown(LLGLWindow window) +{ + return LLGL_PTR(Window, window)->IsShown(); +} + +LLGL_C_EXPORT void llglSetWindowDesc(LLGLWindow window, const LLGLWindowDescriptor* windowDesc) +{ + LLGL_ASSERT_PTR(windowDesc); + WindowDescriptor internalWindowDesc; + ConvertWindowDesc(internalWindowDesc, *windowDesc); + LLGL_PTR(Window, window)->SetDesc(internalWindowDesc); +} + +LLGL_C_EXPORT void llglGetWindowDesc(LLGLWindow window, LLGLWindowDescriptor* outWindowDesc) +{ + LLGL_ASSERT_PTR(outWindowDesc); + WindowDescriptor internalWindowDesc = LLGL_PTR(Window, window)->GetDesc(); + ConvertWindowDesc(*outWindowDesc, internalWindowDesc); +} + +LLGL_C_EXPORT bool llglHasWindowFocus(LLGLWindow window) +{ + return LLGL_PTR(Window, window)->HasFocus(); +} + +LLGL_C_EXPORT bool llglHasWindowQuit(LLGLWindow window) +{ + return LLGL_PTR(Window, window)->HasQuit(); +} + +LLGL_C_EXPORT void llglSetWindowBehavior(LLGLWindow window, const LLGLWindowBehavior* behavior) +{ + LLGL_PTR(Window, window)->SetBehavior(*(const WindowBehavior*)behavior); +} + +LLGL_C_EXPORT void llglGetWindowBehavior(LLGLWindow window, LLGLWindowBehavior* outBehavior) +{ + WindowBehavior internalBehavior = LLGL_PTR(Window, window)->GetBehavior(); + memcpy(outBehavior, &internalBehavior, sizeof(LLGLWindowBehavior)); +} + +LLGL_C_EXPORT int llglAddWindowEventListener(LLGLWindow window, const LLGLWindowEventListener* eventListener) +{ + return 0; //todo +} + +LLGL_C_EXPORT void llglRemoveWindowEventListener(LLGLWindow window, int eventListenerID) +{ + //todo +} + +LLGL_C_EXPORT void llglPostWindowQuit(LLGLWindow window) +{ + LLGL_PTR(Window, window)->PostQuit(); +} + +LLGL_C_EXPORT void llglPostWindowKeyDown(LLGLWindow window, LLGLKey keyCode) +{ + LLGL_PTR(Window, window)->PostKeyDown((Key)keyCode); +} + +LLGL_C_EXPORT void llglPostWindowKeyUp(LLGLWindow window, LLGLKey keyCode) +{ + LLGL_PTR(Window, window)->PostKeyUp((Key)keyCode); +} + +LLGL_C_EXPORT void llglPostWindowDoubleClick(LLGLWindow window, LLGLKey keyCode) +{ + LLGL_PTR(Window, window)->PostDoubleClick((Key)keyCode); +} + +LLGL_C_EXPORT void llglPostWindowChar(LLGLWindow window, wchar_t chr) +{ + LLGL_PTR(Window, window)->PostChar(chr); +} + +LLGL_C_EXPORT void llglPostWindowWheelMotion(LLGLWindow window, int motion) +{ + LLGL_PTR(Window, window)->PostWheelMotion(motion); +} + +LLGL_C_EXPORT void llglPostWindowLocalMotion(LLGLWindow window, const LLGLOffset2D* position) +{ + LLGL_PTR(Window, window)->PostLocalMotion(*(const Offset2D*)position); +} + +LLGL_C_EXPORT void llglPostWindowGlobalMotion(LLGLWindow window, const LLGLOffset2D* motion) +{ + LLGL_PTR(Window, window)->PostGlobalMotion(*(const Offset2D*)motion); +} + +LLGL_C_EXPORT void llglPostWindowResize(LLGLWindow window, const LLGLExtent2D* clientAreaSize) +{ + LLGL_PTR(Window, window)->PostResize(*(const Extent2D*)clientAreaSize); +} + +LLGL_C_EXPORT void llglPostWindowGetFocus(LLGLWindow window) +{ + LLGL_PTR(Window, window)->PostGetFocus(); +} + +LLGL_C_EXPORT void llglPostWindowLostFocus(LLGLWindow window) +{ + LLGL_PTR(Window, window)->PostLostFocus(); +} + +LLGL_C_EXPORT void llglPostWindowTimer(LLGLWindow window, uint32_t timerID) +{ + LLGL_PTR(Window, window)->PostTimer(timerID); +} + + +// } /namespace LLGL + + + +// ================================================================================