CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/GPU/thin3d.h
Views: 1401
// Very thin API wrapper, suitable for porting UI code (like the native/ui framework) and similar but not real rendering.1// Does not involve context creation etc, that should be handled separately - only does drawing.23// The goals may change in the future though.4// MIT licensed, by Henrik RydgÄrd 2014.56#pragma once78#include <atomic>9#include <cstdint>10#include <cstddef>11#include <functional>12#include <string>13#include <vector>1415#include "Common/Common.h"16#include "Common/GPU/DataFormat.h"17#include "Common/GPU/Shader.h"18#include "Common/GPU/MiscTypes.h"19#include "Common/Data/Collections/Slice.h"20#include "Common/Data/Collections/FastVec.h"2122namespace Lin {23class Matrix4x4;24}2526namespace Draw {2728// Useful in UBOs29typedef int bool32;3031enum class Comparison : uint8_t {32NEVER,33LESS,34EQUAL,35LESS_EQUAL,36GREATER,37NOT_EQUAL,38GREATER_EQUAL,39ALWAYS,40};4142// Had to prefix with LOGIC, too many clashes43enum class LogicOp : uint8_t {44LOGIC_CLEAR,45LOGIC_SET,46LOGIC_COPY,47LOGIC_COPY_INVERTED,48LOGIC_NOOP,49LOGIC_INVERT,50LOGIC_AND,51LOGIC_NAND,52LOGIC_OR,53LOGIC_NOR,54LOGIC_XOR,55LOGIC_EQUIV,56LOGIC_AND_REVERSE,57LOGIC_AND_INVERTED,58LOGIC_OR_REVERSE,59LOGIC_OR_INVERTED,60};6162enum class BlendOp : uint8_t {63ADD,64SUBTRACT,65REV_SUBTRACT,66MIN,67MAX,68};6970enum class BlendFactor : uint8_t {71ZERO,72ONE,73SRC_COLOR,74ONE_MINUS_SRC_COLOR,75DST_COLOR,76ONE_MINUS_DST_COLOR,77SRC_ALPHA,78ONE_MINUS_SRC_ALPHA,79DST_ALPHA,80ONE_MINUS_DST_ALPHA,81CONSTANT_COLOR,82ONE_MINUS_CONSTANT_COLOR,83CONSTANT_ALPHA,84ONE_MINUS_CONSTANT_ALPHA,85SRC1_COLOR,86ONE_MINUS_SRC1_COLOR,87SRC1_ALPHA,88ONE_MINUS_SRC1_ALPHA,89};9091enum class StencilOp {92KEEP = 0,93ZERO = 1,94REPLACE = 2,95INCREMENT_AND_CLAMP = 3,96DECREMENT_AND_CLAMP = 4,97INVERT = 5,98INCREMENT_AND_WRAP = 6,99DECREMENT_AND_WRAP = 7,100};101102enum class TextureFilter : uint8_t {103NEAREST = 0,104LINEAR = 1,105};106107enum BufferUsageFlag : int {108VERTEXDATA = 1,109INDEXDATA = 2,110GENERIC = 4,111UNIFORM = 8,112113DYNAMIC = 16,114};115116enum Semantic : int {117SEM_POSITION,118SEM_COLOR0,119SEM_COLOR1,120SEM_TEXCOORD0,121SEM_TEXCOORD1,122SEM_NORMAL,123SEM_TANGENT,124SEM_BINORMAL, // really BITANGENT125SEM_MAX,126};127128enum class Primitive {129POINT_LIST,130LINE_LIST,131LINE_STRIP,132TRIANGLE_LIST,133TRIANGLE_STRIP,134TRIANGLE_FAN,135// Tesselation shader only136PATCH_LIST,137// These are for geometry shaders only.138LINE_LIST_ADJ,139LINE_STRIP_ADJ,140TRIANGLE_LIST_ADJ,141TRIANGLE_STRIP_ADJ,142143UNDEFINED,144PRIMITIVE_TYPE_COUNT,145};146147enum VertexShaderPreset : int {148VS_COLOR_2D,149VS_TEXTURE_COLOR_2D,150VS_MAX_PRESET,151};152153enum FragmentShaderPreset : int {154FS_COLOR_2D,155FS_TEXTURE_COLOR_2D,156FS_TEXTURE_COLOR_2D_RB_SWIZZLE,157FS_MAX_PRESET,158};159160enum class TextureType : uint8_t {161UNKNOWN,162LINEAR1D,163LINEAR2D,164LINEAR3D,165CUBE,166ARRAY1D,167ARRAY2D,168};169170enum class CullMode : uint8_t {171NONE,172FRONT,173BACK,174FRONT_AND_BACK, // Not supported on D3D9175};176177enum class Facing {178CCW,179CW,180};181182enum BorderColor {183DONT_CARE,184TRANSPARENT_BLACK,185OPAQUE_BLACK,186OPAQUE_WHITE,187};188189enum {190COLOR_MASK_R = 1,191COLOR_MASK_G = 2,192COLOR_MASK_B = 4,193COLOR_MASK_A = 8,194};195196enum class TextureAddressMode {197REPEAT = 0,198REPEAT_MIRROR,199CLAMP_TO_EDGE,200CLAMP_TO_BORDER,201};202203enum FormatSupport {204FMT_RENDERTARGET = 1,205FMT_TEXTURE = 2,206FMT_INPUTLAYOUT = 4,207FMT_DEPTHSTENCIL = 8,208FMT_AUTOGEN_MIPS = 16,209FMT_BLIT = 32,210FMT_STORAGE_IMAGE = 64,211};212213enum class InfoField {214APINAME,215APIVERSION,216VENDORSTRING,217VENDOR,218SHADELANGVERSION,219DRIVER,220DEVICE_API_VERSION, // Vulkan-only221};222223enum class GPUVendor {224VENDOR_UNKNOWN,225VENDOR_NVIDIA,226VENDOR_INTEL,227VENDOR_AMD,228VENDOR_ARM, // Mali229VENDOR_QUALCOMM,230VENDOR_IMGTEC, // PowerVR231VENDOR_BROADCOM, // Raspberry232VENDOR_VIVANTE,233VENDOR_APPLE,234VENDOR_MESA,235};236237enum class NativeObject {238CONTEXT,239CONTEXT_EX,240DEVICE,241DEVICE_EX,242BACKBUFFER_COLOR_VIEW,243BACKBUFFER_DEPTH_VIEW,244BACKBUFFER_COLOR_TEX,245BACKBUFFER_DEPTH_TEX,246FEATURE_LEVEL,247INIT_COMMANDBUFFER,248BOUND_TEXTURE0_IMAGEVIEW, // Layer etc depends on how you bound it...249BOUND_TEXTURE1_IMAGEVIEW, // Layer etc depends on how you bound it...250BOUND_FRAMEBUFFER_COLOR_IMAGEVIEW_ALL_LAYERS,251BOUND_FRAMEBUFFER_COLOR_IMAGEVIEW_RT,252RENDER_MANAGER,253TEXTURE_VIEW,254NULL_IMAGEVIEW,255NULL_IMAGEVIEW_ARRAY,256THIN3D_PIPELINE_LAYOUT,257PUSH_POOL,258};259260enum FBChannel {261FB_COLOR_BIT = 1,262FB_DEPTH_BIT = 2,263FB_STENCIL_BIT = 4,264265// Implementation specific266FB_SURFACE_BIT = 32, // Used in conjunction with the others in D3D9 to get surfaces through get_api_texture267FB_VIEW_BIT = 64, // Used in conjunction with the others in D3D11 to get shader resource views through get_api_texture268FB_FORMAT_BIT = 128, // Actually retrieves the native format instead. D3D11 only.269};270271enum FBInvalidationStage {272FB_INVALIDATION_LOAD = 1,273FB_INVALIDATION_STORE = 2,274};275276enum FBBlitFilter {277FB_BLIT_NEAREST = 0,278FB_BLIT_LINEAR = 1,279};280281enum UpdateBufferFlags {282UPDATE_DISCARD = 1,283};284285enum class Event {286// These happen on D3D resize. Only the backbuffer needs to be resized.287LOST_BACKBUFFER,288GOT_BACKBUFFER,289290// These are a bit more serious...291LOST_DEVICE,292GOT_DEVICE,293294RESIZED,295PRESENTED,296};297298enum class ReadbackMode {299BLOCK,300OLD_DATA_OK, // Lets the backend return old results that won't need any waiting to get.301};302303constexpr uint32_t MAX_TEXTURE_SLOTS = 3;304305struct FramebufferDesc {306int width;307int height;308int depth;309int numLayers;310int multiSampleLevel; // 0 = 1xaa, 1 = 2xaa, and so on.311bool z_stencil;312const char *tag; // For graphics debuggers313};314315// Binary compatible with D3D11 viewport.316struct Viewport {317float TopLeftX;318float TopLeftY;319float Width;320float Height;321float MinDepth;322float MaxDepth;323};324325class Bugs {326public:327bool Has(uint32_t bug) const {328return (flags_ & (1 << bug)) != 0;329}330void Infest(uint32_t bug) {331flags_ |= (1 << bug);332}333uint32_t MaxBugIndex() const {334return (uint32_t)MAX_BUG;335}336const char *GetBugName(uint32_t bug);337338enum : uint32_t {339NO_DEPTH_CANNOT_DISCARD_STENCIL_ADRENO = 0,340DUAL_SOURCE_BLENDING_BROKEN = 1,341ANY_MAP_BUFFER_RANGE_SLOW = 2,342PVR_GENMIPMAP_HEIGHT_GREATER = 3,343BROKEN_NAN_IN_CONDITIONAL = 4,344COLORWRITEMASK_BROKEN_WITH_DEPTHTEST = 5,345BROKEN_FLAT_IN_SHADER = 6,346EQUAL_WZ_CORRUPTS_DEPTH = 7,347RASPBERRY_SHADER_COMP_HANG = 8,348MALI_CONSTANT_LOAD_BUG = 9,349SUBPASS_FEEDBACK_BROKEN = 10,350GEOMETRY_SHADERS_SLOW_OR_BROKEN = 11,351ADRENO_RESOURCE_DEADLOCK = 12,352UNIFORM_INDEXING_BROKEN = 13, // not a properly diagnosed issue, a workaround attempt: #17386353PVR_BAD_16BIT_TEXFORMATS = 14,354NO_DEPTH_CANNOT_DISCARD_STENCIL_MALI = 15,355MAX_BUG,356};357358protected:359uint32_t flags_ = 0;360361static_assert(sizeof(flags_) * 8 > MAX_BUG, "Ran out of space for bugs.");362};363364class RefCountedObject {365public:366explicit RefCountedObject(const char *name) : name_(name) {367refcount_ = 1;368}369RefCountedObject(const RefCountedObject &other) = delete;370RefCountedObject& operator=(RefCountedObject const&) = delete;371virtual ~RefCountedObject();372373void AddRef() { refcount_++; }374bool Release();375bool ReleaseAssertLast();376377private:378std::atomic<int> refcount_;379const char * const name_;380};381382template <typename T>383struct AutoRef {384AutoRef() {}385explicit AutoRef(T *p) {386ptr = p;387if (ptr)388ptr->AddRef();389}390AutoRef(const AutoRef<T> &p) {391*this = p.ptr;392}393~AutoRef() {394if (ptr)395ptr->Release();396}397398T *operator =(T *p) {399if (ptr)400ptr->Release();401ptr = p;402if (ptr)403ptr->AddRef();404return ptr;405}406AutoRef<T> &operator =(const AutoRef<T> &p) {407*this = p.ptr;408return *this;409}410bool operator !=(const AutoRef<T> &p) const {411return ptr != p.ptr;412}413414T *operator->() const {415return ptr;416}417operator T *() {418return ptr;419}420operator bool() const {421return ptr != nullptr;422}423424// Takes over ownership over newItem, so we don't need to AddRef it, the number of owners didn't change.425void reset(T *newItem) {426if (ptr) {427ptr->Release();428}429ptr = newItem;430}431432T *ptr = nullptr;433};434435class BlendState : public RefCountedObject {436public:437BlendState() : RefCountedObject("BlendState") {}438};439440class SamplerState : public RefCountedObject {441public:442SamplerState() : RefCountedObject("SamplerState") {}443};444445class DepthStencilState : public RefCountedObject {446public:447DepthStencilState() : RefCountedObject("DepthStencilState") {}448};449450class Framebuffer : public RefCountedObject {451public:452Framebuffer() : RefCountedObject("Framebuffer") {}453int Width() const { return width_; }454int Height() const { return height_; }455int Layers() const { return layers_; }456int MultiSampleLevel() { return multiSampleLevel_; }457458virtual void UpdateTag(const char *tag) {}459protected:460int width_ = -1, height_ = -1, layers_ = 1, multiSampleLevel_ = 0;461};462463class Buffer : public RefCountedObject {464public:465Buffer() : RefCountedObject("Buffer") {}466};467468class Texture : public RefCountedObject {469public:470Texture() : RefCountedObject("Texture") {}471int Width() const { return width_; }472int Height() const { return height_; }473int Depth() const { return depth_; }474DataFormat Format() const { return format_; }475476protected:477int width_ = -1, height_ = -1, depth_ = -1;478DataFormat format_ = DataFormat::UNDEFINED;479};480481struct AttributeDesc {482int location; // corresponds to semantic483DataFormat format;484int offset;485};486487struct InputLayoutDesc {488int stride;489std::vector<AttributeDesc> attributes;490};491492class InputLayout : public RefCountedObject {493public:494InputLayout() : RefCountedObject("InputLayout") {}495};496497// Uniform types have moved to Shader.h.498499class ShaderModule : public RefCountedObject {500public:501ShaderModule() : RefCountedObject("ShaderModule") {}502virtual ShaderStage GetStage() const = 0;503};504505class Pipeline : public RefCountedObject {506public:507Pipeline() : RefCountedObject("Pipeline") {}508};509510class RasterState : public RefCountedObject {511public:512RasterState() : RefCountedObject("RasterState") {}513};514515struct StencilSetup {516StencilOp failOp;517StencilOp passOp;518StencilOp depthFailOp;519Comparison compareOp;520};521522struct DepthStencilStateDesc {523bool depthTestEnabled;524bool depthWriteEnabled;525Comparison depthCompare;526bool stencilEnabled;527StencilSetup stencil;528};529530struct BlendStateDesc {531bool enabled;532int colorMask;533BlendFactor srcCol;534BlendFactor dstCol;535BlendOp eqCol;536BlendFactor srcAlpha;537BlendFactor dstAlpha;538BlendOp eqAlpha;539bool logicEnabled;540LogicOp logicOp;541};542543struct SamplerStateDesc {544TextureFilter magFilter;545TextureFilter minFilter;546TextureFilter mipFilter;547float maxAniso;548TextureAddressMode wrapU;549TextureAddressMode wrapV;550TextureAddressMode wrapW;551bool shadowCompareEnabled;552Comparison shadowCompareFunc;553BorderColor borderColor;554};555556struct RasterStateDesc {557CullMode cull;558Facing frontFace;559};560561struct PipelineDesc {562Primitive prim;563std::vector<ShaderModule *> shaders;564InputLayout *inputLayout;565DepthStencilState *depthStencil;566BlendState *blend;567RasterState *raster;568const UniformBufferDesc *uniformDesc;569const Slice<SamplerDef> samplers;570};571572enum class PresentMode {573FIFO = 1,574IMMEDIATE = 2,575MAILBOX = 4,576};577ENUM_CLASS_BITOPS(PresentMode);578579struct DeviceCaps {580GPUVendor vendor;581uint32_t deviceID; // use caution!582583DataFormat preferredDepthBufferFormat;584DataFormat preferredShadowMapFormatLow;585DataFormat preferredShadowMapFormatHigh;586bool anisoSupported;587bool depthRangeMinusOneToOne; // OpenGL style depth588bool geometryShaderSupported;589bool tesselationShaderSupported;590bool dualSourceBlend;591bool logicOpSupported;592bool depthClampSupported;593bool clipDistanceSupported;594bool cullDistanceSupported;595bool framebufferCopySupported;596bool framebufferBlitSupported;597bool framebufferDepthCopySupported;598bool framebufferSeparateDepthCopySupported;599bool framebufferDepthBlitSupported;600bool framebufferStencilBlitSupported;601bool framebufferFetchSupported;602bool texture3DSupported;603bool fragmentShaderInt32Supported;604bool textureNPOTFullySupported;605bool fragmentShaderDepthWriteSupported;606bool fragmentShaderStencilWriteSupported;607bool textureDepthSupported;608bool blendMinMaxSupported;609bool multiViewSupported;610bool isTilingGPU; // This means that it benefits from correct store-ops, msaa without backing memory, etc.611bool sampleRateShadingSupported;612bool setMaxFrameLatencySupported;613bool textureSwizzleSupported;614bool requiresHalfPixelOffset;615bool provokingVertexLast; // GL behavior, what the PSP does616bool verySlowShaderCompiler;617618// From the other backends, we can detect if D3D9 support is known bad (like on Xe) and disable it.619bool supportsD3D9;620621// Old style, for older GL or Direct3D 9.622u32 clipPlanesSupported;623624// Presentation caps625int presentMaxInterval; // 1 on many backends626bool presentInstantModeChange;627PresentMode presentModesSupported;628629u32 multiSampleLevelsMask; // Bit n is set if (1 << n) is a valid multisample level. Bit 0 is always set.630std::string deviceName; // The device name to use when creating the thin3d context, to get the same one.631};632633// Use to write data directly to texture memory. initData is the pointer passed in TextureDesc.634// Important: only write to the provided pointer, don't read from it.635typedef std::function<bool(uint8_t *data, const uint8_t *initData, uint32_t w, uint32_t h, uint32_t d, uint32_t byteStride, uint32_t sliceByteStride)> TextureCallback;636637enum class TextureSwizzle {638DEFAULT,639R8_AS_ALPHA,640};641642struct TextureDesc {643TextureType type;644DataFormat format;645646int width;647int height;648int depth;649int mipLevels;650bool generateMips;651TextureSwizzle swizzle;652// Optional, for tracking memory usage and graphcis debuggers.653const char *tag;654// Does not take ownership over pointed-to data.655std::vector<const uint8_t *> initData;656TextureCallback initDataCallback;657};658659enum class RPAction {660KEEP = 0,661CLEAR = 1,662DONT_CARE = 2,663};664665struct RenderPassInfo {666RPAction color;667RPAction depth;668RPAction stencil;669uint32_t clearColor;670float clearDepth;671uint8_t clearStencil;672const char *tag;673};674675const int ALL_LAYERS = -1;676677enum class TextureBindFlags {678NONE = 0,679VULKAN_BIND_ARRAY = 1,680};681ENUM_CLASS_BITOPS(TextureBindFlags);682683enum class DebugFlags {684NONE = 0,685PROFILE_TIMESTAMPS = 1,686PROFILE_SCOPES = 2,687};688ENUM_CLASS_BITOPS(DebugFlags);689690struct BackendState {691u32 passes;692bool valid;693};694695class DrawContext {696public:697virtual ~DrawContext();698bool CreatePresets();699void DestroyPresets();700701Bugs GetBugs() const { return bugs_; }702703virtual void Wait() {}704705virtual const DeviceCaps &GetDeviceCaps() const = 0;706virtual uint32_t GetDataFormatSupport(DataFormat fmt) const = 0;707virtual std::vector<std::string> GetFeatureList() const { return std::vector<std::string>(); }708virtual std::vector<std::string> GetExtensionList(bool device, bool enabledOnly) const { return std::vector<std::string>(); }709virtual std::vector<std::string> GetDeviceList() const { return std::vector<std::string>(); }710virtual std::vector<std::string> GetPresentModeList(std::string_view currentMarkerString) const { return std::vector<std::string>(); }711virtual std::vector<std::string> GetSurfaceFormatList() const { return std::vector<std::string>(); }712713virtual BackendState GetCurrentBackendState() const {714return BackendState{};715}716717// Describes the primary shader language that this implementation prefers.718const ShaderLanguageDesc &GetShaderLanguageDesc() {719return shaderLanguageDesc_;720}721722virtual uint32_t GetSupportedShaderLanguages() const = 0;723724virtual void SetErrorCallback(ErrorCallbackFn callback, void *userdata) {}725726virtual void DebugAnnotate(const char *annotation) {}727728// Partial pipeline state, used to create pipelines. (in practice, in d3d11 they'll use the native state objects directly).729// TODO: Possibly ditch these and just put the descs directly in PipelineDesc since only D3D11 benefits.730virtual DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) = 0;731virtual BlendState *CreateBlendState(const BlendStateDesc &desc) = 0;732virtual SamplerState *CreateSamplerState(const SamplerStateDesc &desc) = 0;733virtual RasterState *CreateRasterState(const RasterStateDesc &desc) = 0;734virtual InputLayout *CreateInputLayout(const InputLayoutDesc &desc) = 0;735virtual ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize, const char *tag = "thin3d") = 0;736virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc, const char *tag) = 0;737738// Note that these DO NOT AddRef so you must not ->Release presets unless you manually AddRef them.739ShaderModule *GetVshaderPreset(VertexShaderPreset preset) { return vsPresets_[preset]; }740ShaderModule *GetFshaderPreset(FragmentShaderPreset preset) { return fsPresets_[preset]; }741742// Resources743virtual Buffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0;744// Does not take ownership over pointed-to initData. After this returns, can dispose of it.745virtual Texture *CreateTexture(const TextureDesc &desc) = 0;746// On some hardware, you might get a 24-bit depth buffer even though you only wanted a 16-bit one.747virtual Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) = 0;748749// Copies data from the CPU over into the buffer, at a specific offset. This does not change the size of the buffer and cannot write outside it.750virtual void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) = 0;751752// Used to optimize DrawPixels by re-using previously allocated temp textures.753// Do not try to update a texture that might be used by an in-flight command buffer! In OpenGL and D3D, this will cause stalls754// while in Vulkan this might cause various strangeness like image corruption.755virtual void UpdateTextureLevels(Texture *texture, const uint8_t **data, TextureCallback initDataCallback, int numLevels) = 0;756757virtual void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) = 0;758virtual bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) = 0;759760// If the backend doesn't support old data, it's "OK" to block.761virtual bool CopyFramebufferToMemory(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride, ReadbackMode mode, const char *tag) {762return false;763}764virtual DataFormat PreferredFramebufferReadbackFormat(Framebuffer *src) {765return DataFormat::R8G8B8A8_UNORM;766}767768// These functions should be self explanatory.769// Binding a zero render target means binding the backbuffer.770// If an fbo has two layers, we bind for stereo rendering ALWAYS. There's no rendering to one layer anymore.771virtual void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) = 0;772773// binding must be < MAX_TEXTURE_SLOTS (0, 1 are okay if it's 2).774virtual void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int layer) = 0;775776// Framebuffer fetch / input attachment support, needs to be explicit in Vulkan.777virtual void BindCurrentFramebufferForColorInput() {}778779// deprecated, only used by D3D9780virtual uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) {781return 0;782}783784virtual void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) = 0;785786// Could be useful in OpenGL ES to give hints about framebuffers on tiler GPUs787// using glInvalidateFramebuffer, although drivers are known to botch that so we currently don't use it.788// In Vulkan, this sets the LOAD_OP or the STORE_OP (depending on stage) of the current render pass instance to DONT_CARE.789// channels is a bitwise combination of FBChannel::COLOR, DEPTH and STENCIL.790virtual void InvalidateFramebuffer(FBInvalidationStage stage, uint32_t channels) {}791792// Dynamic state793virtual void SetScissorRect(int left, int top, int width, int height) = 0;794virtual void SetViewport(const Viewport &viewport) = 0;795virtual void SetBlendFactor(float color[4]) = 0;796virtual void SetStencilParams(uint8_t refValue, uint8_t writeMask, uint8_t compareMask) = 0;797798virtual void BindSamplerStates(int start, int count, SamplerState **state) = 0;799virtual void BindTextures(int start, int count, Texture **textures, TextureBindFlags flags = TextureBindFlags::NONE) = 0;800virtual void BindVertexBuffer(Buffer *vertexBuffer, int offset) = 0;801virtual void BindIndexBuffer(Buffer *indexBuffer, int offset) = 0;802803// Sometimes it's necessary to bind a texture not created by thin3d, and use with a thin3d pipeline.804// Not pretty, and one way in the future could be to create all textures through thin3d.805// Data types:806// * Vulkan: VkImageView807// * D3D11: ID3D11ShaderResourceView*808virtual void BindNativeTexture(int sampler, void *nativeTexture) = 0;809810// Only supports a single dynamic uniform buffer, for maximum compatibility with the old APIs and ease of emulation.811// More modern methods will be added later.812virtual void UpdateDynamicUniformBuffer(const void *ub, size_t size) = 0;813814void BindTexture(int stage, Texture *texture) {815Texture *textures[1] = { texture };816BindTextures(stage, 1, textures);817} // from sampler 0 and upwards818819// Clear state cached within thin3d. Must be called after directly calling API functions.820// Note that framebuffer state (which framebuffer is bounds) may not be cached.821// Must not actually perform any API calls itself since this can be called when no framebuffer is bound for rendering.822virtual void Invalidate(InvalidationFlags flags) = 0;823824virtual void BindPipeline(Pipeline *pipeline) = 0;825826virtual void Draw(int vertexCount, int offset) = 0;827virtual void DrawIndexed(int vertexCount, int offset) = 0; // Always 16-bit indices.828virtual void DrawUP(const void *vdata, int vertexCount) = 0;829830// Frame management (for the purposes of sync and resource management, necessary with modern APIs). Default implementations here.831virtual void BeginFrame(DebugFlags debugFlags) = 0;832virtual void EndFrame() = 0;833834// vblanks is only relevant in FIFO present mode.835// NOTE: Not all backends support vblanks > 1. Some backends also can't change presentation mode immediately.836virtual void Present(PresentMode presentMode, int vblanks) = 0;837838// This should be avoided as much as possible, in favor of clearing when binding a render target, which is native839// on Vulkan.840virtual void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) = 0;841842// Necessary to correctly flip scissor rectangles etc for OpenGL.843virtual void SetTargetSize(int w, int h) {844targetWidth_ = w;845targetHeight_ = h;846}847848// In Vulkan, when changing things like MSAA mode, we can't have draw commands in flight (since we only support one at a time).849virtual void StopThreads() {}850virtual void StartThreads() {}851852virtual std::string GetInfoString(InfoField info) const = 0;853virtual uint64_t GetNativeObject(NativeObject obj, void *srcObject = nullptr) = 0; // Most uses don't need an srcObject.854855virtual void HandleEvent(Event ev, int width, int height, void *param1 = nullptr, void *param2 = nullptr) = 0;856857// Flush state like scissors etc so the caller can do its own custom drawing.858virtual void FlushState() {}859860// This is called when we launch a new game, so any collected internal stats in the backends don't carry over.861virtual void ResetStats() {}862863// Used by the DrawEngines to know when they have to re-apply some state.864// Not very elegant, but more elegant than the old passId hack.865virtual void SetInvalidationCallback(InvalidationCallback callback) = 0;866867// Total amount of frames rendered. Unaffected by game pause, so more robust than gpuStats.numFlips868virtual int GetFrameCount() = 0;869870virtual std::string GetGpuProfileString() const {871return "";872}873874const HistoryBuffer<FrameTimeData, FRAME_TIME_HISTORY_LENGTH> &FrameTimeHistory() const {875return frameTimeHistory_;876}877878protected:879HistoryBuffer<FrameTimeData, FRAME_TIME_HISTORY_LENGTH> frameTimeHistory_;880881ShaderModule *vsPresets_[VS_MAX_PRESET];882ShaderModule *fsPresets_[FS_MAX_PRESET];883884ShaderLanguageDesc shaderLanguageDesc_;885886int targetWidth_;887int targetHeight_;888889Bugs bugs_;890};891892extern const UniformBufferDesc UBPresetDesc;893894// UBs for the preset shaders895896struct VsTexColUB {897float WorldViewProj[16];898float tint;899float saturation;900float pad[2];901};902extern const UniformBufferDesc vsTexColBufDesc;903struct VsColUB {904float WorldViewProj[16];905float tint;906float saturation;907float pad[2];908};909extern const UniformBufferDesc vsColBufDesc;910911// Useful utility for specifying a shader in multiple languages.912913struct ShaderSource {914ShaderLanguage lang;915const char *src;916};917918ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector<ShaderSource> &sources);919920const char *PresentModeToString(PresentMode presentMode);921922} // namespace Draw923924925