/* SPDX-License-Identifier: GPL-2.0-or-later */ /** \file * \ingroup gpu */ #pragma once #include "BLI_utildefines.h" /** Opaque type hiding blender::gpu::Fence. */ typedef struct GPUFence GPUFence; typedef enum eGPUWriteMask { GPU_WRITE_NONE = 0, GPU_WRITE_RED = (1 << 0), GPU_WRITE_GREEN = (1 << 1), GPU_WRITE_BLUE = (1 << 2), GPU_WRITE_ALPHA = (1 << 3), GPU_WRITE_DEPTH = (1 << 4), GPU_WRITE_STENCIL = (1 << 5), GPU_WRITE_COLOR = (GPU_WRITE_RED | GPU_WRITE_GREEN | GPU_WRITE_BLUE | GPU_WRITE_ALPHA), } eGPUWriteMask; ENUM_OPERATORS(eGPUWriteMask, GPU_WRITE_COLOR) typedef enum eGPUBarrier { /* Texture Barrier. */ /** All written texture prior to this barrier can be bound as frame-buffer attachment. */ GPU_BARRIER_FRAMEBUFFER = (1 << 0), /** All written texture prior to this barrier can be bound as image. */ GPU_BARRIER_SHADER_IMAGE_ACCESS = (1 << 1), /** All written texture prior to this barrier can be bound as sampler. */ GPU_BARRIER_TEXTURE_FETCH = (1 << 2), /** All written texture prior to this barrier can be read or updated with CPU memory. */ GPU_BARRIER_TEXTURE_UPDATE = (1 << 3), /** All written texture prior to this barrier can be read or updated with PBO. */ // GPU_BARRIER_PIXEL_BUFFER = (1 << 4), /* Not implemented yet. */ /* Buffer Barrier. */ /** All written buffer prior to this barrier can be bound as indirect command buffer. */ GPU_BARRIER_COMMAND = (1 << 10), /** All written buffer prior to this barrier can be bound as SSBO. */ GPU_BARRIER_SHADER_STORAGE = (1 << 11), /** All written buffer prior to this barrier can be bound as VBO. */ GPU_BARRIER_VERTEX_ATTRIB_ARRAY = (1 << 12), /** All written buffer prior to this barrier can be bound as IBO. */ GPU_BARRIER_ELEMENT_ARRAY = (1 << 13), /** All written buffer prior to this barrier can be bound as UBO. */ GPU_BARRIER_UNIFORM = (1 << 14), /** All written buffer prior to this barrier can be read or updated with CPU memory. */ GPU_BARRIER_BUFFER_UPDATE = (1 << 15), /** All written persistent mapped buffer prior to this barrier can be read or updated. */ // GPU_BARRIER_CLIENT_MAPPED_BUFFER = (1 << 15), /* Not implemented yet. */ } eGPUBarrier; ENUM_OPERATORS(eGPUBarrier, GPU_BARRIER_UNIFORM) /* NOTE: For Metal and Vulkan only. * TODO(Metal): Update barrier calls to use stage flags. */ typedef enum eGPUStageBarrierBits { GPU_BARRIER_STAGE_VERTEX = (1 << 0), GPU_BARRIER_STAGE_FRAGMENT = (1 << 1), GPU_BARRIER_STAGE_COMPUTE = (1 << 2), GPU_BARRIER_STAGE_ANY_GRAPHICS = (GPU_BARRIER_STAGE_VERTEX | GPU_BARRIER_STAGE_FRAGMENT), GPU_BARRIER_STAGE_ANY = (GPU_BARRIER_STAGE_VERTEX | GPU_BARRIER_STAGE_FRAGMENT | GPU_BARRIER_STAGE_COMPUTE), } eGPUStageBarrierBits; ENUM_OPERATORS(eGPUStageBarrierBits, GPU_BARRIER_STAGE_COMPUTE) /** * Defines the fixed pipeline blending equation. * SRC is the output color from the shader. * DST is the color from the frame-buffer. * The blending equation is: * `(SRC * A) + (DST * B)`. * The blend mode will modify the A and B parameters. */ typedef enum eGPUBlend { GPU_BLEND_NONE = 0, /** Pre-multiply variants will _NOT_ multiply rgb output by alpha. */ GPU_BLEND_ALPHA, GPU_BLEND_ALPHA_PREMULT, GPU_BLEND_ADDITIVE, GPU_BLEND_ADDITIVE_PREMULT, GPU_BLEND_MULTIPLY, GPU_BLEND_SUBTRACT, /** Replace logic op: SRC * (1 - DST) * NOTE: Does not modify alpha. */ GPU_BLEND_INVERT, /** Order independent transparency. * NOTE: Cannot be used as is. Needs special setup (frame-buffer, shader ...). */ GPU_BLEND_OIT, /** Special blend to add color under and multiply dst color by src alpha. */ GPU_BLEND_BACKGROUND, /** Custom blend parameters using dual source blending : SRC0 + SRC1 * DST * NOTE: Can only be used with _ONE_ Draw Buffer and shader needs to be specialized. */ GPU_BLEND_CUSTOM, GPU_BLEND_ALPHA_UNDER_PREMUL, } eGPUBlend; typedef enum eGPUDepthTest { GPU_DEPTH_NONE = 0, GPU_DEPTH_ALWAYS, /* Used to draw to the depth buffer without really testing. */ GPU_DEPTH_LESS, GPU_DEPTH_LESS_EQUAL, /* Default. */ GPU_DEPTH_EQUAL, GPU_DEPTH_GREATER, GPU_DEPTH_GREATER_EQUAL, } eGPUDepthTest; typedef enum eGPUStencilTest { GPU_STENCIL_NONE = 0, GPU_STENCIL_ALWAYS, GPU_STENCIL_EQUAL, GPU_STENCIL_NEQUAL, } eGPUStencilTest; typedef enum eGPUStencilOp { GPU_STENCIL_OP_NONE = 0, GPU_STENCIL_OP_REPLACE, /** Special values for stencil shadows. */ GPU_STENCIL_OP_COUNT_DEPTH_PASS, GPU_STENCIL_OP_COUNT_DEPTH_FAIL, } eGPUStencilOp; typedef enum eGPUFaceCullTest { GPU_CULL_NONE = 0, /* Culling disabled. */ GPU_CULL_FRONT, GPU_CULL_BACK, } eGPUFaceCullTest; typedef enum eGPUProvokingVertex { GPU_VERTEX_LAST = 0, /* Default. */ GPU_VERTEX_FIRST = 1, /* Follow Blender loop order. */ } eGPUProvokingVertex; #ifdef __cplusplus extern "C" { #endif void GPU_blend(eGPUBlend blend); void GPU_face_culling(eGPUFaceCullTest culling); void GPU_depth_test(eGPUDepthTest test); void GPU_stencil_test(eGPUStencilTest test); void GPU_provoking_vertex(eGPUProvokingVertex vert); void GPU_front_facing(bool invert); void GPU_depth_range(float near, float far); void GPU_scissor_test(bool enable); void GPU_line_smooth(bool enable); /** * \note By convention, this is set as needed and not reset back to 1.0. * This means code that draws lines must always set the line width beforehand, * but is not expected to restore it's previous value. */ void GPU_line_width(float width); void GPU_logic_op_xor_set(bool enable); void GPU_point_size(float size); void GPU_polygon_smooth(bool enable); /** * Programmable point size: * - Shaders set their own point size when enabled * - Use GPU_point_size when disabled. * * TODO: remove and use program point size everywhere. */ void GPU_program_point_size(bool enable); void GPU_scissor(int x, int y, int width, int height); void GPU_scissor_get(int coords[4]); void GPU_viewport(int x, int y, int width, int height); void GPU_viewport_size_get_f(float coords[4]); void GPU_viewport_size_get_i(int coords[4]); void GPU_write_mask(eGPUWriteMask mask); void GPU_color_mask(bool r, bool g, bool b, bool a); void GPU_depth_mask(bool depth); bool GPU_depth_mask_get(void); void GPU_shadow_offset(bool enable); void GPU_clip_distances(int distances_enabled); bool GPU_mipmap_enabled(void); void GPU_state_set(eGPUWriteMask write_mask, eGPUBlend blend, eGPUFaceCullTest culling_test, eGPUDepthTest depth_test, eGPUStencilTest stencil_test, eGPUStencilOp stencil_op, eGPUProvokingVertex provoking_vert); void GPU_stencil_reference_set(uint reference); void GPU_stencil_write_mask_set(uint write_mask); void GPU_stencil_compare_mask_set(uint compare_mask); eGPUFaceCullTest GPU_face_culling_get(void); eGPUBlend GPU_blend_get(void); eGPUDepthTest GPU_depth_test_get(void); eGPUWriteMask GPU_write_mask_get(void); uint GPU_stencil_mask_get(void); eGPUStencilTest GPU_stencil_test_get(void); /** * \note Already pre-multiplied by `U.pixelsize`. */ float GPU_line_width_get(void); void GPU_flush(void); void GPU_finish(void); void GPU_apply_state(void); void GPU_bgl_start(void); /** * Just turn off the `bgl` safeguard system. Can be called even without #GPU_bgl_start. */ void GPU_bgl_end(void); bool GPU_bgl_get(void); /** * A barrier _must_ be issued _after_ a shader arbitrary write to a buffer or a * texture (i.e: using imageStore, imageAtomics, or SSBO). Otherwise, the written value may not * appear updated to the next user of this resource. * * The type of barrier must be chosen depending on the _future_ use of the memory that was written * by the shader. */ void GPU_memory_barrier(eGPUBarrier barrier); GPUFence *GPU_fence_create(void); void GPU_fence_free(GPUFence *fence); void GPU_fence_signal(GPUFence *fence); void GPU_fence_wait(GPUFence *fence); #ifdef __cplusplus } #endif