Compare commits

...

48 Commits

Author SHA1 Message Date
Caleb Cornett f5b3e466a8 Prep for PS5Driver 2022-08-13 21:28:41 -04:00
cosmonaut 2fb9a6931b fix SetTextureDataYUV image transitions 2022-07-29 18:15:02 -07:00
Hazel Stagner c01ff21359 Fix blit destination layer and level 2022-07-22 20:59:01 -07:00
cosmonaut e5da75d33a fix exponential growth when submitting multiple command buffers 2022-06-27 10:21:40 -07:00
cosmonaut 99e9dc5b8c fix framebuffer size miscalculation with depth attachment 2022-06-17 14:47:12 -07:00
cosmonaut 0e7720ccf6 D16 fallback when unsupported 2022-06-17 00:41:27 -07:00
cosmonaut 488cb8c535 add format to render pass hash 2022-06-06 11:46:08 -07:00
cosmonaut 3007b4c989 1.5.0 2022-05-11 21:18:54 -07:00
cosmonaut 163adfb5cd add BC7 support 2022-05-11 21:16:24 -07:00
cosmonaut f0b970496e vertex format changes 2022-03-17 14:41:16 -07:00
cosmonaut 38d14fd99d 1.4.0 2022-03-14 10:54:32 -07:00
cosmonaut 4bba0f99f9 remove lineWidth from RasterizerState 2022-03-14 10:43:01 -07:00
cosmonaut acefc530fd 1.3.0 2022-03-10 10:28:00 -08:00
cosmonaut 3820d458fe remove Clear and add pWidth and pHeight to AcquireSwapchainTexture 2022-03-10 10:21:49 -08:00
cosmonaut 7a0b0f5709 suboptimal on recreate is still technically fine 2022-03-08 11:21:36 -08:00
cosmonaut ce34f4a435 fix deadlock on multi window swapchain resize 2022-03-08 10:47:07 -08:00
TheSpydog eb5617f40e Update template for latest ABI breaks (#16)
Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Co-authored-by: cosmonaut <evan@moonside.games>
Reviewed-on: MoonsideGames/Refresh#16
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2022-03-07 08:05:58 +00:00
cosmonaut 0380a96817 Swapchain resize fixes (#18)
Fixes various errors related to the swapchain being recreated.

Additionally, `BeginRenderPass` now allows a NULL `renderArea` parameter. If NULL, Refresh will select a sensible default render area.
Co-authored-by: cosmonaut <evan@moonside.games>
Co-committed-by: cosmonaut <evan@moonside.games>
2022-03-07 06:31:39 +00:00
cosmonaut 22236607f7 1.2.1 2022-03-04 13:39:31 -08:00
cosmonaut 715ca591f6 fix compute pipeline create bug 2022-03-04 13:37:45 -08:00
cosmonaut 7b91c5a140 1.2.0 2022-03-04 13:18:58 -08:00
cosmonaut 2731d47419 rename viewport and scissor set functions 2022-03-04 12:47:36 -08:00
cosmonaut 0fbf1b2546 fix erroneous stack free 2022-03-04 12:36:02 -08:00
cosmonaut f6b96fe34b viewport and scissor ABI break 2022-03-04 12:30:33 -08:00
cosmonaut 9422d4975f 1.1.0 2022-03-03 17:32:21 -08:00
cosmonaut 435f56f6b7 move API defines to the top 2022-03-03 17:31:33 -08:00
cosmonaut 6302603b08 add some missing frees 2022-03-03 17:30:26 -08:00
cosmonaut 5fe4c8dbf3 remove command buffer from QueueDestroy calls 2022-03-03 17:07:07 -08:00
cosmonaut 67e3a8799c 1.0.0 2022-03-02 15:55:56 -08:00
cosmonaut ee50c04428 remove interop structs 2022-03-02 15:49:40 -08:00
cosmonaut 9eae69f96b remove unused enum 2022-03-02 11:46:41 -08:00
cosmonaut 057a48e96f separate shader types 2022-03-02 11:22:52 -08:00
cosmonaut 61e83cfba8 D3D compatibility ABI break 2022-03-02 11:10:28 -08:00
cosmonaut e4ea104a88 remove swapchain log spam 2022-03-02 10:27:03 -08:00
cosmonaut 83c2372499 only mark swapchain as needing recreate if it exists 2022-03-02 10:02:07 -08:00
cosmonaut cb99489b3c Rework Presentation Flow (#15)
Removes `Refresh_RenderTarget`, `Refresh_CreateRenderTarget` and `Refresh_QueueDestroyRenderTarget`. Render targets are now managed by the implementation.

Adds `REFRESH_TEXTUREFORMAT_B8G8R8A8`.

Adds `Refresh_AcquireSwapchainTexture`. Returns a swapchain texture for the requested window.

Removes `Refresh_QueuePresent`. It is now assumed that the texture returned by `Refresh_AcquireSwapchainTexture` will be presented. This texture can be manipulated like any other texture.

Adds `Refresh_GetSwapchainFormat`. Returns the swapchain format for the requested window.

Reviewed-on: MoonsideGames/Refresh#15
Co-authored-by: cosmonaut <evan@moonside.games>
Co-committed-by: cosmonaut <evan@moonside.games>
2022-03-02 06:33:57 +00:00
cosmonaut d22bed8b76 transition entire images + rework swapchain image management 2022-02-28 12:02:39 -08:00
cosmonaut 436b990d45 Fix intro message formatting 2022-02-25 23:13:17 -08:00
cosmonaut a26d3e3689 move color blend state to AttachmentInfo 2022-02-25 17:37:42 -08:00
cosmonaut a38a9d461d fix right alignment spacing 2022-02-25 13:51:29 -08:00
cosmonaut 517399f5d9 convert all spaces to tabs 2022-02-25 13:42:11 -08:00
cosmonaut 5187093ddc reset command buffers on the thread they were spawned 2022-02-24 22:06:00 -08:00
cosmonaut 336468cc31 fix some invalid accesses 2022-02-24 21:29:52 -08:00
cosmonaut 26a5ea91ba change colorAttachmentDescriptions to a const pointer 2022-02-24 21:20:55 -08:00
cosmonaut a531fb8593 Render Pass API Streamlining (#14)
Removes `Refresh_RenderPass` and `Refresh_Framebuffer` objects.

`Refresh_BeginRenderPass` now takes a set of `Refresh_ColorAttachmentInfo` structs and an optional `Refresh_DepthStencilAttachmentInfo` struct that describe the render pass. The render pass and framebuffer objects are now managed by the implementation instead of the application.

Accordingly, `Refresh_GraphicsPipelineCreateInfo` now takes a `Refresh_GraphicsPipelineAttachmentInfo` struct that describes render passes that may be used with the pipeline. It is an error to bind a pipeline during an incompatible render pass.

Reviewed-on: MoonsideGames/Refresh#14
Co-authored-by: cosmonaut <evan@moonside.games>
Co-committed-by: cosmonaut <evan@moonside.games>
2022-02-24 22:01:37 +00:00
cosmonaut a3aea0f796 Reset fence as late as possible 2022-02-22 21:54:32 -08:00
cosmonaut 0319c26f6a Submission rewrite (#13)
Rework submission flow to reduce waiting and improve the resource cleanup process.

This patch also gets rid of descriptor set caching.
Co-authored-by: cosmonaut <evan@moonside.games>
Co-committed-by: cosmonaut <evan@moonside.games>
2022-02-23 00:49:45 +00:00
TheSpydog 1d72fdb995 Added a Refresh driver template file (#12)
This allows us to avoid monotonous boilerplate when bringing up new backends.
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2022-02-22 03:28:31 +00:00
9 changed files with 5521 additions and 4525 deletions

13
.editorconfig Normal file
View File

@ -0,0 +1,13 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true
[*.{c,h}]
charset = utf-8-bom
max_line_length = 100

View File

@ -7,8 +7,8 @@ project(Refresh C)
option(BUILD_SHARED_LIBS "Build shared library" ON) option(BUILD_SHARED_LIBS "Build shared library" ON)
# Version # Version
SET(LIB_MAJOR_VERSION "0") SET(LIB_MAJOR_VERSION "1")
SET(LIB_MINOR_VERSION "1") SET(LIB_MINOR_VERSION "5")
SET(LIB_REVISION "0") SET(LIB_REVISION "0")
SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_REVISION}") SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_REVISION}")

View File

@ -1,4 +1,4 @@
/* Refresh - XNA-inspired 3D Graphics Library with modern capabilities /* Refresh - XNA-inspired 3D Graphics Library with modern capabilities
* *
* Copyright (c) 2020 Evan Hemsley * Copyright (c) 2020 Evan Hemsley
* *
@ -52,16 +52,27 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/* Version API */
#define REFRESH_MAJOR_VERSION 1
#define REFRESH_MINOR_VERSION 5
#define REFRESH_PATCH_VERSION 0
#define REFRESH_COMPILED_VERSION ( \
(REFRESH_MAJOR_VERSION * 100 * 100) + \
(REFRESH_MINOR_VERSION * 100) + \
(REFRESH_PATCH_VERSION) \
)
REFRESHAPI uint32_t Refresh_LinkedVersion(void);
/* Type Declarations */ /* Type Declarations */
typedef struct Refresh_Device Refresh_Device; typedef struct Refresh_Device Refresh_Device;
typedef struct Refresh_Buffer Refresh_Buffer; typedef struct Refresh_Buffer Refresh_Buffer;
typedef struct Refresh_Texture Refresh_Texture; typedef struct Refresh_Texture Refresh_Texture;
typedef struct Refresh_Sampler Refresh_Sampler; typedef struct Refresh_Sampler Refresh_Sampler;
typedef struct Refresh_RenderTarget Refresh_RenderTarget;
typedef struct Refresh_Framebuffer Refresh_Framebuffer;
typedef struct Refresh_ShaderModule Refresh_ShaderModule; typedef struct Refresh_ShaderModule Refresh_ShaderModule;
typedef struct Refresh_RenderPass Refresh_RenderPass;
typedef struct Refresh_ComputePipeline Refresh_ComputePipeline; typedef struct Refresh_ComputePipeline Refresh_ComputePipeline;
typedef struct Refresh_GraphicsPipeline Refresh_GraphicsPipeline; typedef struct Refresh_GraphicsPipeline Refresh_GraphicsPipeline;
typedef struct Refresh_CommandBuffer Refresh_CommandBuffer; typedef struct Refresh_CommandBuffer Refresh_CommandBuffer;
@ -76,7 +87,7 @@ typedef enum Refresh_PresentMode
typedef enum Refresh_PrimitiveType typedef enum Refresh_PrimitiveType
{ {
REFRESH_PRIMITIVETYPE_POINTLIST, REFRESH_PRIMITIVETYPE_POINTLIST,
REFRESH_PRIMITIVETYPE_LINELIST, REFRESH_PRIMITIVETYPE_LINELIST,
REFRESH_PRIMITIVETYPE_LINESTRIP, REFRESH_PRIMITIVETYPE_LINESTRIP,
REFRESH_PRIMITIVETYPE_TRIANGLELIST, REFRESH_PRIMITIVETYPE_TRIANGLELIST,
@ -85,59 +96,52 @@ typedef enum Refresh_PrimitiveType
typedef enum Refresh_LoadOp typedef enum Refresh_LoadOp
{ {
REFRESH_LOADOP_LOAD, REFRESH_LOADOP_LOAD,
REFRESH_LOADOP_CLEAR, REFRESH_LOADOP_CLEAR,
REFRESH_LOADOP_DONT_CARE REFRESH_LOADOP_DONT_CARE
} Refresh_LoadOp; } Refresh_LoadOp;
typedef enum Refresh_StoreOp typedef enum Refresh_StoreOp
{ {
REFRESH_STOREOP_STORE, REFRESH_STOREOP_STORE,
REFRESH_STOREOP_DONT_CARE REFRESH_STOREOP_DONT_CARE
} Refresh_StoreOp; } Refresh_StoreOp;
typedef enum Refresh_ClearOptionsBits
{
REFRESH_CLEAROPTIONS_COLOR = 0x00000001,
REFRESH_CLEAROPTIONS_DEPTH = 0x00000002,
REFRESH_CLEAROPTIONS_STENCIL = 0x00000004,
} Refresh_ClearOptionsBits;
typedef uint32_t Refresh_ClearOptions;
typedef enum Refresh_IndexElementSize typedef enum Refresh_IndexElementSize
{ {
REFRESH_INDEXELEMENTSIZE_16BIT, REFRESH_INDEXELEMENTSIZE_16BIT,
REFRESH_INDEXELEMENTSIZE_32BIT REFRESH_INDEXELEMENTSIZE_32BIT
} Refresh_IndexElementSize; } Refresh_IndexElementSize;
typedef enum Refresh_TextureFormat typedef enum Refresh_TextureFormat
{ {
/* Color Formats */ /* Color Formats */
REFRESH_TEXTUREFORMAT_R8G8B8A8, REFRESH_TEXTUREFORMAT_R8G8B8A8,
REFRESH_TEXTUREFORMAT_R5G6B5, REFRESH_TEXTUREFORMAT_B8G8R8A8,
REFRESH_TEXTUREFORMAT_A1R5G5B5, REFRESH_TEXTUREFORMAT_R5G6B5,
REFRESH_TEXTUREFORMAT_B4G4R4A4, REFRESH_TEXTUREFORMAT_A1R5G5B5,
REFRESH_TEXTUREFORMAT_BC1, REFRESH_TEXTUREFORMAT_B4G4R4A4,
REFRESH_TEXTUREFORMAT_BC2, REFRESH_TEXTUREFORMAT_BC1,
REFRESH_TEXTUREFORMAT_BC3, REFRESH_TEXTUREFORMAT_BC2,
REFRESH_TEXTUREFORMAT_R8G8_SNORM, REFRESH_TEXTUREFORMAT_BC3,
REFRESH_TEXTUREFORMAT_R8G8B8A8_SNORM, REFRESH_TEXTUREFORMAT_BC7,
REFRESH_TEXTUREFORMAT_A2R10G10B10, REFRESH_TEXTUREFORMAT_R8G8_SNORM,
REFRESH_TEXTUREFORMAT_R16G16, REFRESH_TEXTUREFORMAT_R8G8B8A8_SNORM,
REFRESH_TEXTUREFORMAT_R16G16B16A16, REFRESH_TEXTUREFORMAT_A2R10G10B10,
REFRESH_TEXTUREFORMAT_R8, REFRESH_TEXTUREFORMAT_R16G16,
REFRESH_TEXTUREFORMAT_R32_SFLOAT, REFRESH_TEXTUREFORMAT_R16G16B16A16,
REFRESH_TEXTUREFORMAT_R32G32_SFLOAT, REFRESH_TEXTUREFORMAT_R8,
REFRESH_TEXTUREFORMAT_R32G32B32A32_SFLOAT, REFRESH_TEXTUREFORMAT_R32_SFLOAT,
REFRESH_TEXTUREFORMAT_R16_SFLOAT, REFRESH_TEXTUREFORMAT_R32G32_SFLOAT,
REFRESH_TEXTUREFORMAT_R16G16_SFLOAT, REFRESH_TEXTUREFORMAT_R32G32B32A32_SFLOAT,
REFRESH_TEXTUREFORMAT_R16G16B16A16_SFLOAT, REFRESH_TEXTUREFORMAT_R16_SFLOAT,
REFRESH_TEXTUREFORMAT_R16G16_SFLOAT,
REFRESH_TEXTUREFORMAT_R16G16B16A16_SFLOAT,
/* Depth Formats */ /* Depth Formats */
REFRESH_TEXTUREFORMAT_D16_UNORM, REFRESH_TEXTUREFORMAT_D16_UNORM,
REFRESH_TEXTUREFORMAT_D32_SFLOAT, REFRESH_TEXTUREFORMAT_D32_SFLOAT,
REFRESH_TEXTUREFORMAT_D16_UNORM_S8_UINT, REFRESH_TEXTUREFORMAT_D16_UNORM_S8_UINT,
REFRESH_TEXTUREFORMAT_D32_SFLOAT_S8_UINT REFRESH_TEXTUREFORMAT_D32_SFLOAT_S8_UINT
} Refresh_TextureFormat; } Refresh_TextureFormat;
typedef enum Refresh_TextureUsageFlagBits typedef enum Refresh_TextureUsageFlagBits
@ -162,12 +166,12 @@ typedef enum Refresh_SampleCount
typedef enum Refresh_CubeMapFace typedef enum Refresh_CubeMapFace
{ {
REFRESH_CUBEMAPFACE_POSITIVEX, REFRESH_CUBEMAPFACE_POSITIVEX,
REFRESH_CUBEMAPFACE_NEGATIVEX, REFRESH_CUBEMAPFACE_NEGATIVEX,
REFRESH_CUBEMAPFACE_POSITIVEY, REFRESH_CUBEMAPFACE_POSITIVEY,
REFRESH_CUBEMAPFACE_NEGATIVEY, REFRESH_CUBEMAPFACE_NEGATIVEY,
REFRESH_CUBEMAPFACE_POSITIVEZ, REFRESH_CUBEMAPFACE_POSITIVEZ,
REFRESH_CUBEMAPFACE_NEGATIVEZ REFRESH_CUBEMAPFACE_NEGATIVEZ
} Refresh_CubeMapFace; } Refresh_CubeMapFace;
typedef enum Refresh_BufferUsageFlagBits typedef enum Refresh_BufferUsageFlagBits
@ -181,7 +185,8 @@ typedef uint32_t Refresh_BufferUsageFlags;
typedef enum Refresh_VertexElementFormat typedef enum Refresh_VertexElementFormat
{ {
REFRESH_VERTEXELEMENTFORMAT_SINGLE, REFRESH_VERTEXELEMENTFORMAT_UINT,
REFRESH_VERTEXELEMENTFORMAT_FLOAT,
REFRESH_VERTEXELEMENTFORMAT_VECTOR2, REFRESH_VERTEXELEMENTFORMAT_VECTOR2,
REFRESH_VERTEXELEMENTFORMAT_VECTOR3, REFRESH_VERTEXELEMENTFORMAT_VECTOR3,
REFRESH_VERTEXELEMENTFORMAT_VECTOR4, REFRESH_VERTEXELEMENTFORMAT_VECTOR4,
@ -204,16 +209,14 @@ typedef enum Refresh_VertexInputRate
typedef enum Refresh_FillMode typedef enum Refresh_FillMode
{ {
REFRESH_FILLMODE_FILL, REFRESH_FILLMODE_FILL,
REFRESH_FILLMODE_LINE, REFRESH_FILLMODE_LINE
REFRESH_FILLMODE_POINT
} Refresh_FillMode; } Refresh_FillMode;
typedef enum Refresh_CullMode typedef enum Refresh_CullMode
{ {
REFRESH_CULLMODE_NONE, REFRESH_CULLMODE_NONE,
REFRESH_CULLMODE_FRONT, REFRESH_CULLMODE_FRONT,
REFRESH_CULLMODE_BACK, REFRESH_CULLMODE_BACK
REFRESH_CULLMODE_FRONT_AND_BACK
} Refresh_CullMode; } Refresh_CullMode;
typedef enum Refresh_FrontFace typedef enum Refresh_FrontFace
@ -255,70 +258,41 @@ typedef enum Refresh_BlendOp
REFRESH_BLENDOP_MAX REFRESH_BLENDOP_MAX
} Refresh_BlendOp; } Refresh_BlendOp;
typedef enum Refresh_LogicOp
{
REFRESH_LOGICOP_CLEAR = 0,
REFRESH_LOGICOP_AND = 1,
REFRESH_LOGICOP_AND_REVERSE = 2,
REFRESH_LOGICOP_COPY = 3,
REFRESH_LOGICOP_AND_INVERTED = 4,
REFRESH_LOGICOP_NO_OP = 5,
REFRESH_LOGICOP_XOR = 6,
REFRESH_LOGICOP_OR = 7,
REFRESH_LOGICOP_NOR = 8,
REFRESH_LOGICOP_EQUIVALENT = 9,
REFRESH_LOGICOP_INVERT = 10,
REFRESH_LOGICOP_OR_REVERSE = 11,
REFRESH_LOGICOP_COPY_INVERTED = 12,
REFRESH_LOGICOP_OR_INVERTED = 13,
REFRESH_LOGICOP_NAND = 14,
REFRESH_LOGICOP_SET = 15
} Refresh_LogicOp;
typedef enum Refresh_BlendFactor typedef enum Refresh_BlendFactor
{ {
REFRESH_BLENDFACTOR_ZERO = 0, REFRESH_BLENDFACTOR_ZERO,
REFRESH_BLENDFACTOR_ONE = 1, REFRESH_BLENDFACTOR_ONE,
REFRESH_BLENDFACTOR_SRC_COLOR = 2, REFRESH_BLENDFACTOR_SRC_COLOR,
REFRESH_BLENDFACTOR_ONE_MINUS_SRC_COLOR = 3, REFRESH_BLENDFACTOR_ONE_MINUS_SRC_COLOR,
REFRESH_BLENDFACTOR_DST_COLOR = 4, REFRESH_BLENDFACTOR_DST_COLOR,
REFRESH_BLENDFACTOR_ONE_MINUS_DST_COLOR = 5, REFRESH_BLENDFACTOR_ONE_MINUS_DST_COLOR,
REFRESH_BLENDFACTOR_SRC_ALPHA = 6, REFRESH_BLENDFACTOR_SRC_ALPHA,
REFRESH_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = 7, REFRESH_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
REFRESH_BLENDFACTOR_DST_ALPHA = 8, REFRESH_BLENDFACTOR_DST_ALPHA,
REFRESH_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 9, REFRESH_BLENDFACTOR_ONE_MINUS_DST_ALPHA,
REFRESH_BLENDFACTOR_CONSTANT_COLOR = 10, REFRESH_BLENDFACTOR_CONSTANT_COLOR,
REFRESH_BLENDFACTOR_ONE_MINUS_CONSTANT_COLOR = 11, REFRESH_BLENDFACTOR_ONE_MINUS_CONSTANT_COLOR,
REFRESH_BLENDFACTOR_CONSTANT_ALPHA = 12, REFRESH_BLENDFACTOR_SRC_ALPHA_SATURATE,
REFRESH_BLENDFACTOR_ONE_MINUS_CONSTANT_ALPHA = 13, REFRESH_BLENDFACTOR_SRC1_COLOR,
REFRESH_BLENDFACTOR_SRC_ALPHA_SATURATE = 14, REFRESH_BLENDFACTOR_ONE_MINUS_SRC1_COLOR,
REFRESH_BLENDFACTOR_SRC1_COLOR = 15, REFRESH_BLENDFACTOR_SRC1_ALPHA,
REFRESH_BLENDFACTOR_ONE_MINUS_SRC1_COLOR = 16, REFRESH_BLENDFACTOR_ONE_MINUS_SRC1_ALPHA
REFRESH_BLENDFACTOR_SRC1_ALPHA = 17,
REFRESH_BLENDFACTOR_ONE_MINUS_SRC1_ALPHA = 18
} Refresh_BlendFactor; } Refresh_BlendFactor;
typedef enum Refresh_ColorComponentFlagBits typedef enum Refresh_ColorComponentFlagBits
{ {
REFRESH_COLORCOMPONENT_R_BIT = 0x00000001, REFRESH_COLORCOMPONENT_R_BIT = 0x00000001,
REFRESH_COLORCOMPONENT_G_BIT = 0x00000002, REFRESH_COLORCOMPONENT_G_BIT = 0x00000002,
REFRESH_COLORCOMPONENT_B_BIT = 0x00000004, REFRESH_COLORCOMPONENT_B_BIT = 0x00000004,
REFRESH_COLORCOMPONENT_A_BIT = 0x00000008 REFRESH_COLORCOMPONENT_A_BIT = 0x00000008
} Refresh_ColorComponentFlagBits; } Refresh_ColorComponentFlagBits;
typedef uint32_t Refresh_ColorComponentFlags; typedef uint32_t Refresh_ColorComponentFlags;
typedef enum Refresh_ShaderStageType
{
REFRESH_SHADERSTAGE_VERTEX,
REFRESH_SHADERSTAGE_FRAGMENT
} Refresh_ShaderStageType;
typedef enum Refresh_Filter typedef enum Refresh_Filter
{ {
REFRESH_FILTER_NEAREST, REFRESH_FILTER_NEAREST,
REFRESH_FILTER_LINEAR, REFRESH_FILTER_LINEAR
REFRESH_FILTER_CUBIC
} Refresh_Filter; } Refresh_Filter;
typedef enum Refresh_SamplerMipmapMode typedef enum Refresh_SamplerMipmapMode
@ -338,12 +312,12 @@ typedef enum Refresh_SamplerAddressMode
/* FIXME: we should probably make a library-level decision about color types */ /* FIXME: we should probably make a library-level decision about color types */
typedef enum Refresh_BorderColor typedef enum Refresh_BorderColor
{ {
REFRESH_BORDERCOLOR_FLOAT_TRANSPARENT_BLACK = 0, REFRESH_BORDERCOLOR_FLOAT_TRANSPARENT_BLACK,
REFRESH_BORDERCOLOR_INT_TRANSPARENT_BLACK = 1, REFRESH_BORDERCOLOR_INT_TRANSPARENT_BLACK,
REFRESH_BORDERCOLOR_FLOAT_OPAQUE_BLACK = 2, REFRESH_BORDERCOLOR_FLOAT_OPAQUE_BLACK,
REFRESH_BORDERCOLOR_INT_OPAQUE_BLACK = 3, REFRESH_BORDERCOLOR_INT_OPAQUE_BLACK,
REFRESH_BORDERCOLOR_FLOAT_OPAQUE_WHITE = 4, REFRESH_BORDERCOLOR_FLOAT_OPAQUE_WHITE,
REFRESH_BORDERCOLOR_INT_OPAQUE_WHITE = 5 REFRESH_BORDERCOLOR_INT_OPAQUE_WHITE
} Refresh_BorderColor; } Refresh_BorderColor;
/* Structures */ /* Structures */
@ -449,7 +423,7 @@ typedef struct Refresh_StencilOpState
uint32_t reference; uint32_t reference;
} Refresh_StencilOpState; } Refresh_StencilOpState;
typedef struct Refresh_ColorTargetBlendState typedef struct Refresh_ColorAttachmentBlendState
{ {
uint8_t blendEnable; uint8_t blendEnable;
Refresh_BlendFactor srcColorBlendFactor; Refresh_BlendFactor srcColorBlendFactor;
@ -459,7 +433,7 @@ typedef struct Refresh_ColorTargetBlendState
Refresh_BlendFactor dstAlphaBlendFactor; Refresh_BlendFactor dstAlphaBlendFactor;
Refresh_BlendOp alphaBlendOp; Refresh_BlendOp alphaBlendOp;
Refresh_ColorComponentFlags colorWriteMask; Refresh_ColorComponentFlags colorWriteMask;
} Refresh_ColorTargetBlendState; } Refresh_ColorAttachmentBlendState;
typedef struct Refresh_ComputePipelineLayoutCreateInfo typedef struct Refresh_ComputePipelineLayoutCreateInfo
{ {
@ -467,36 +441,6 @@ typedef struct Refresh_ComputePipelineLayoutCreateInfo
uint32_t imageBindingCount; uint32_t imageBindingCount;
} Refresh_ComputePipelineLayoutCreateInfo; } Refresh_ComputePipelineLayoutCreateInfo;
typedef struct Refresh_GraphicsPipelineLayoutCreateInfo
{
uint32_t vertexSamplerBindingCount;
uint32_t fragmentSamplerBindingCount;
} Refresh_GraphicsPipelineLayoutCreateInfo;
typedef struct Refresh_ColorTargetDescription
{
Refresh_TextureFormat format;
Refresh_SampleCount multisampleCount;
Refresh_LoadOp loadOp;
Refresh_StoreOp storeOp;
} Refresh_ColorTargetDescription;
typedef struct Refresh_DepthStencilTargetDescription
{
Refresh_TextureFormat depthStencilFormat;
Refresh_LoadOp loadOp;
Refresh_StoreOp storeOp;
Refresh_LoadOp stencilLoadOp;
Refresh_StoreOp stencilStoreOp;
} Refresh_DepthStencilTargetDescription;
typedef struct Refresh_RenderPassCreateInfo
{
const Refresh_ColorTargetDescription *colorTargetDescriptions;
uint32_t colorTargetCount;
const Refresh_DepthStencilTargetDescription *depthTargetDescription; /* can be NULL */
} Refresh_RenderPassCreateInfo;
typedef struct Refresh_ShaderModuleCreateInfo typedef struct Refresh_ShaderModuleCreateInfo
{ {
size_t codeSize; size_t codeSize;
@ -517,20 +461,22 @@ typedef struct Refresh_TextureCreateInfo
/* Pipeline state structures */ /* Pipeline state structures */
typedef struct Refresh_ShaderStageState typedef struct Refresh_GraphicsShaderInfo
{ {
Refresh_ShaderModule *shaderModule; Refresh_ShaderModule *shaderModule;
const char* entryPointName; const char* entryPointName;
uint64_t uniformBufferSize; uint64_t uniformBufferSize;
} Refresh_ShaderStageState; uint32_t samplerBindingCount;
} Refresh_GraphicsShaderInfo;
typedef struct Refresh_ViewportState typedef struct Refresh_ComputeShaderInfo
{ {
const Refresh_Viewport *viewports; Refresh_ShaderModule* shaderModule;
uint32_t viewportCount; const char* entryPointName;
const Refresh_Rect *scissors; uint64_t uniformBufferSize;
uint32_t scissorCount; uint32_t bufferBindingCount;
} Refresh_ViewportState; uint32_t imageBindingCount;
} Refresh_ComputeShaderInfo;
typedef struct Refresh_RasterizerState typedef struct Refresh_RasterizerState
{ {
@ -542,7 +488,6 @@ typedef struct Refresh_RasterizerState
float depthBiasConstantFactor; float depthBiasConstantFactor;
float depthBiasClamp; float depthBiasClamp;
float depthBiasSlopeFactor; float depthBiasSlopeFactor;
float lineWidth;
} Refresh_RasterizerState; } Refresh_RasterizerState;
typedef struct Refresh_MultisampleState typedef struct Refresh_MultisampleState
@ -564,111 +509,60 @@ typedef struct Refresh_DepthStencilState
float maxDepthBounds; float maxDepthBounds;
} Refresh_DepthStencilState; } Refresh_DepthStencilState;
typedef struct Refresh_ColorBlendState typedef struct Refresh_ColorAttachmentDescription
{ {
uint8_t logicOpEnable; Refresh_TextureFormat format;
Refresh_LogicOp logicOp; Refresh_SampleCount sampleCount;
const Refresh_ColorTargetBlendState *blendStates; Refresh_ColorAttachmentBlendState blendState;
uint32_t blendStateCount; } Refresh_ColorAttachmentDescription;
float blendConstants[4];
} Refresh_ColorBlendState;
typedef struct Refresh_ComputePipelineCreateInfo typedef struct Refresh_GraphicsPipelineAttachmentInfo
{ {
Refresh_ShaderStageState computeShaderState; Refresh_ColorAttachmentDescription *colorAttachmentDescriptions;
Refresh_ComputePipelineLayoutCreateInfo pipelineLayoutCreateInfo; uint32_t colorAttachmentCount;
} Refresh_ComputePipelineCreateInfo; uint8_t hasDepthStencilAttachment;
Refresh_TextureFormat depthStencilFormat;
} Refresh_GraphicsPipelineAttachmentInfo;
typedef struct Refresh_GraphicsPipelineCreateInfo typedef struct Refresh_GraphicsPipelineCreateInfo
{ {
Refresh_ShaderStageState vertexShaderState; Refresh_GraphicsShaderInfo vertexShaderInfo;
Refresh_ShaderStageState fragmentShaderState; Refresh_GraphicsShaderInfo fragmentShaderInfo;
Refresh_VertexInputState vertexInputState; Refresh_VertexInputState vertexInputState;
Refresh_PrimitiveType primitiveType; Refresh_PrimitiveType primitiveType;
Refresh_ViewportState viewportState;
Refresh_RasterizerState rasterizerState; Refresh_RasterizerState rasterizerState;
Refresh_MultisampleState multisampleState; Refresh_MultisampleState multisampleState;
Refresh_DepthStencilState depthStencilState; Refresh_DepthStencilState depthStencilState;
Refresh_ColorBlendState colorBlendState; Refresh_GraphicsPipelineAttachmentInfo attachmentInfo;
Refresh_GraphicsPipelineLayoutCreateInfo pipelineLayoutCreateInfo; float blendConstants[4];
Refresh_RenderPass *renderPass;
} Refresh_GraphicsPipelineCreateInfo; } Refresh_GraphicsPipelineCreateInfo;
typedef struct Refresh_FramebufferCreateInfo /* Render pass structures */
typedef struct Refresh_ColorAttachmentInfo
{ {
Refresh_RenderPass *renderPass; Refresh_Texture *texture; /* We can't use TextureSlice because render passes take a single rectangle. */
Refresh_RenderTarget **pColorTargets; uint32_t depth;
uint32_t colorTargetCount; uint32_t layer;
Refresh_RenderTarget *pDepthStencilTarget; uint32_t level;
uint32_t width; Refresh_SampleCount sampleCount;
uint32_t height; Refresh_Vec4 clearColor; /* Can be ignored by RenderPass */
} Refresh_FramebufferCreateInfo; Refresh_LoadOp loadOp;
Refresh_StoreOp storeOp;
} Refresh_ColorAttachmentInfo;
/* Interop Structs */ typedef struct Refresh_DepthStencilAttachmentInfo
typedef enum Refresh_SysRendererType
{ {
REFRESH_RENDERER_TYPE_VULKAN Refresh_Texture *texture; /* We can't use TextureSlice because render passes take a single rectangle. */
} Refresh_SysRendererType; uint32_t depth;
uint32_t layer;
typedef struct Refresh_SysRenderer uint32_t level;
{ Refresh_DepthStencilValue depthStencilClearValue; /* Can be ignored by RenderPass */
Refresh_SysRendererType rendererType; Refresh_LoadOp loadOp;
Refresh_StoreOp storeOp;
union Refresh_LoadOp stencilLoadOp;
{ Refresh_StoreOp stencilStoreOp;
#if REFRESH_DRIVER_VULKAN } Refresh_DepthStencilAttachmentInfo;
struct
{
void* instance;
void* physicalDevice;
void* logicalDevice;
uint32_t queueFamilyIndex;
} vulkan;
#endif /* REFRESH_DRIVER_VULKAN */
uint8_t filler[64];
} renderer;
} Refresh_SysRenderer;
typedef struct Refresh_TextureHandles
{
Refresh_SysRendererType rendererType;
union
{
#if REFRESH_DRIVER_VULKAN
#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
#define REFRESH_VULKAN_HANDLE_TYPE void*
#else
#define REFRESH_VULKAN_HANDLE_TYPE uint64_t
#endif
struct
{
REFRESH_VULKAN_HANDLE_TYPE image; /* VkImage */
REFRESH_VULKAN_HANDLE_TYPE view; /* VkImageView */
} vulkan;
#endif /* REFRESH_DRIVER_VULKAN */
uint8_t filler[64];
} texture;
} Refresh_TextureHandles;
/* Version API */
#define REFRESH_ABI_VERSION 0
#define REFRESH_MAJOR_VERSION 0
#define REFRESH_MINOR_VERSION 1
#define REFRESH_PATCH_VERSION 0
#define REFRESH_COMPILED_VERSION ( \
(REFRESH_ABI_VERSION * 100 * 100 * 100) + \
(REFRESH_MAJOR_VERSION * 100 * 100) + \
(REFRESH_MINOR_VERSION * 100) + \
(REFRESH_PATCH_VERSION) \
)
REFRESHAPI uint32_t Refresh_LinkedVersion(void);
/* Functions */ /* Functions */
@ -692,8 +586,7 @@ REFRESHAPI void Refresh_HookLogFunctions(
/* Create a rendering context for use on the calling thread. /* Create a rendering context for use on the calling thread.
* *
* presentationParameters: * presentationParameters: A window handle and presentation mode.
* If the windowHandle is NULL, Refresh will run in headless mode.
* debugMode: Enable debug mode properties. * debugMode: Enable debug mode properties.
*/ */
REFRESHAPI Refresh_Device* Refresh_CreateDevice( REFRESHAPI Refresh_Device* Refresh_CreateDevice(
@ -706,30 +599,6 @@ REFRESHAPI void Refresh_DestroyDevice(Refresh_Device *device);
/* Drawing */ /* Drawing */
/* Clears the targets of the currently bound framebuffer.
* If fewer colors are passed than the number of color targets in the
* framebuffer, this function will clear the first n color targets.
*
* NOTE:
* It is generally recommended to clear in BeginRenderPass
* rather than by calling this function unless necessary.
*
* clearRect: Area to clear.
* options: Bitflags to specify color/depth/stencil buffers for clearing.
* colors: An array of color values for the cleared color buffers.
* colorCount: The number of colors in the above array.
* depthStencil: Depth and stencil values for the cleared depth stencil buffer.
*/
REFRESHAPI void Refresh_Clear(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *clearRect,
Refresh_ClearOptions options,
Refresh_Vec4 *colors,
uint32_t colorCount,
Refresh_DepthStencilValue depthStencil
);
/* Draws data from vertex/index buffers with instancing enabled. /* Draws data from vertex/index buffers with instancing enabled.
* *
* baseVertex: The starting offset to read from the vertex buffer. * baseVertex: The starting offset to read from the vertex buffer.
@ -802,16 +671,10 @@ REFRESHAPI void Refresh_DispatchCompute(
/* State Creation */ /* State Creation */
/* Returns an allocated RenderPass* object. */
REFRESHAPI Refresh_RenderPass* Refresh_CreateRenderPass(
Refresh_Device *device,
Refresh_RenderPassCreateInfo *renderPassCreateInfo
);
/* Returns an allocated ComputePipeline* object. */ /* Returns an allocated ComputePipeline* object. */
REFRESHAPI Refresh_ComputePipeline* Refresh_CreateComputePipeline( REFRESHAPI Refresh_ComputePipeline* Refresh_CreateComputePipeline(
Refresh_Device *device, Refresh_Device *device,
Refresh_ComputePipelineCreateInfo *pipelineCreateInfo Refresh_ComputeShaderInfo *computeShaderInfo
); );
/* Returns an allocated GraphicsPipeline* object. */ /* Returns an allocated GraphicsPipeline* object. */
@ -826,12 +689,6 @@ REFRESHAPI Refresh_Sampler* Refresh_CreateSampler(
Refresh_SamplerStateCreateInfo *samplerStateCreateInfo Refresh_SamplerStateCreateInfo *samplerStateCreateInfo
); );
/* Returns an allocated Framebuffer* object. */
REFRESHAPI Refresh_Framebuffer* Refresh_CreateFramebuffer(
Refresh_Device *device,
Refresh_FramebufferCreateInfo *framebufferCreateInfo
);
/* Returns an allocated ShaderModule* object. */ /* Returns an allocated ShaderModule* object. */
REFRESHAPI Refresh_ShaderModule* Refresh_CreateShaderModule( REFRESHAPI Refresh_ShaderModule* Refresh_CreateShaderModule(
Refresh_Device *device, Refresh_Device *device,
@ -846,17 +703,6 @@ REFRESHAPI Refresh_Texture* Refresh_CreateTexture(
Refresh_TextureCreateInfo *textureCreateInfo Refresh_TextureCreateInfo *textureCreateInfo
); );
/* Creates a color target.
*
* textureSlice: The texture slice that the color target will resolve to.
* multisampleCount: The MSAA value for the color target.
*/
REFRESHAPI Refresh_RenderTarget* Refresh_CreateRenderTarget(
Refresh_Device *device,
Refresh_TextureSlice *textureSlice,
Refresh_SampleCount multisampleCount
);
/* Creates a buffer. /* Creates a buffer.
* *
* usageFlags: Specifies how the buffer will be used. * usageFlags: Specifies how the buffer will be used.
@ -1065,30 +911,6 @@ REFRESHAPI void Refresh_QueueDestroyBuffer(
Refresh_Buffer *buffer Refresh_Buffer *buffer
); );
/* Sends a color target to be destroyed by the renderer. Note that we call it
* "QueueDestroy" because it may not be immediately destroyed by the renderer if
* this is not called from the main thread (for example, if a garbage collector
* deletes the resource instead of the programmer).
*
* renderTarget: The Refresh_ColorTarget to be destroyed.
*/
REFRESHAPI void Refresh_QueueDestroyRenderTarget(
Refresh_Device *device,
Refresh_RenderTarget *renderTarget
);
/* Sends a framebuffer to be destroyed by the renderer. Note that we call it
* "QueueDestroy" because it may not be immediately destroyed by the renderer if
* this is not called from the main thread (for example, if a garbage collector
* deletes the resource instead of the programmer).
*
* framebuffer: The Refresh_Framebuffer to be destroyed.
*/
REFRESHAPI void Refresh_QueueDestroyFramebuffer(
Refresh_Device *device,
Refresh_Framebuffer *frameBuffer
);
/* Sends a shader module to be destroyed by the renderer. Note that we call it /* Sends a shader module to be destroyed by the renderer. Note that we call it
* "QueueDestroy" because it may not be immediately destroyed by the renderer if * "QueueDestroy" because it may not be immediately destroyed by the renderer if
* this is not called from the main thread (for example, if a garbage collector * this is not called from the main thread (for example, if a garbage collector
@ -1101,18 +923,6 @@ REFRESHAPI void Refresh_QueueDestroyShaderModule(
Refresh_ShaderModule *shaderModule Refresh_ShaderModule *shaderModule
); );
/* Sends a render pass to be destroyed by the renderer. Note that we call it
* "QueueDestroy" because it may not be immediately destroyed by the renderer if
* this is not called from the main thread (for example, if a garbage collector
* deletes the resource instead of the programmer).
*
* renderPass: The Refresh_RenderPass to be destroyed.
*/
REFRESHAPI void Refresh_QueueDestroyRenderPass(
Refresh_Device *device,
Refresh_RenderPass *renderPass
);
/* Sends a compute pipeline to be destroyed by the renderer. Note that we call it /* Sends a compute pipeline to be destroyed by the renderer. Note that we call it
* "QueueDestroy" because it may not be immediately destroyed by the renderer if * "QueueDestroy" because it may not be immediately destroyed by the renderer if
* this is not called from the main thread (for example, if a garbage collector * this is not called from the main thread (for example, if a garbage collector
@ -1140,29 +950,26 @@ REFRESHAPI void Refresh_QueueDestroyGraphicsPipeline(
/* Graphics State */ /* Graphics State */
/* Begins a render pass. /* Begins a render pass.
* This will also set a default viewport and scissor state.
* *
* renderPass: The renderpass to begin.
* framebuffer: The framebuffer to bind for the render pass.
* renderArea: * renderArea:
* The area affected by the render pass. * The area affected by the render pass.
* All load, store and resolve operations are restricted * All load, store and resolve operations are restricted
* to the given rectangle. * to the given rectangle.
* clearValues: * If NULL, a sensible default will be chosen.
* A pointer to an array of Refresh_Color structures * colorAttachmentInfos:
* that contains clear values for each color target in the * A pointer to an array of Refresh_ColorAttachmentInfo structures
* framebuffer. May be NULL. * that contains render targets and clear values. May be NULL.
* clearCount: The amount of color structs in the above array. * colorAttachmentCount: The amount of structs in the above array.
* depthStencilClearValue: The depth/stencil clear value. May be NULL. * depthStencilAttachmentInfo: The depth/stencil render target and clear value. May be NULL.
*/ */
REFRESHAPI void Refresh_BeginRenderPass( REFRESHAPI void Refresh_BeginRenderPass(
Refresh_Device *device, Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_RenderPass *renderPass,
Refresh_Framebuffer *framebuffer,
Refresh_Rect *renderArea, Refresh_Rect *renderArea,
Refresh_Vec4 *pColorClearValues, Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorClearCount, uint32_t colorAttachmentCount,
Refresh_DepthStencilValue *depthStencilClearValue Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
); );
/* Ends the current render pass. */ /* Ends the current render pass. */
@ -1178,6 +985,20 @@ REFRESHAPI void Refresh_BindGraphicsPipeline(
Refresh_GraphicsPipeline *graphicsPipeline Refresh_GraphicsPipeline *graphicsPipeline
); );
/* Sets the current viewport state. */
REFRESHAPI void Refresh_SetViewport(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_Viewport *viewport
);
/* Sets the current scissor state. */
REFRESHAPI void Refresh_SetScissor(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *scissor
);
/* Binds vertex buffers for use with subsequent draw calls. */ /* Binds vertex buffers for use with subsequent draw calls. */
REFRESHAPI void Refresh_BindVertexBuffers( REFRESHAPI void Refresh_BindVertexBuffers(
Refresh_Device *device, Refresh_Device *device,
@ -1281,23 +1102,29 @@ REFRESHAPI Refresh_CommandBuffer* Refresh_AcquireCommandBuffer(
uint8_t fixed uint8_t fixed
); );
/* Queues an image to be presented to a window. /* Acquires a texture to use for presentation.
* The image will be presented upon the next Refresh_Submit call. * May return NULL under certain conditions.
* If NULL, the user must ensure to not use the texture.
* Once a swapchain texture is acquired,
* it will automatically be presented on command buffer submission.
* *
* NOTE: * NOTE:
* It is an error to call this function in headless mode. * It is not recommended to hold a reference to this texture long term.
* *
* textureSlice: The texture slice to present. * pWidth: A pointer to a uint32 that will be filled with the texture width.
* destinationRectangle: The region of the window to update. Can be NULL. * pHeight: A pointer to a uint32 that will be filled with the texture height.
* filter: The filter to use if scaling is required.
* windowHandle: The window to present to.
*/ */
REFRESHAPI void Refresh_QueuePresent( REFRESHAPI Refresh_Texture* Refresh_AcquireSwapchainTexture(
Refresh_Device *device, Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *textureSlice, void *windowHandle,
Refresh_Rect *destinationRectangle, uint32_t *pWidth,
Refresh_Filter filter, uint32_t *pHeight
);
/* Returns the format of the swapchain for the given window. */
REFRESHAPI Refresh_TextureFormat Refresh_GetSwapchainFormat(
Refresh_Device *device,
void *windowHandle void *windowHandle
); );
@ -1308,7 +1135,7 @@ REFRESHAPI void Refresh_Submit(
Refresh_CommandBuffer **pCommandBuffers Refresh_CommandBuffer **pCommandBuffers
); );
/* Waits for the previous submission to complete. */ /* Waits for all submissions to complete. */
REFRESHAPI void Refresh_Wait( REFRESHAPI void Refresh_Wait(
Refresh_Device *device Refresh_Device *device
); );

View File

@ -54,10 +54,10 @@ extern "C" {
* Be sure to free the memory with Refresh_Image_Free after use! * Be sure to free the memory with Refresh_Image_Free after use!
*/ */
REFRESHAPI uint8_t* Refresh_Image_Load( REFRESHAPI uint8_t* Refresh_Image_Load(
char const *filename, char const *filename,
int32_t *w, int32_t *w,
int32_t *h, int32_t *h,
int32_t *numChannels int32_t *numChannels
); );
/* Frees memory returned by Refresh_Image_Load. (Do NOT free the memory yourself!) /* Frees memory returned by Refresh_Image_Load. (Do NOT free the memory yourself!)
@ -68,17 +68,19 @@ REFRESHAPI void Refresh_Image_Free(uint8_t *mem);
/* Image Write API */ /* Image Write API */
/* Encodes RGBA8 image data into PNG data. /* Encodes 32-bit color data into PNG data.
* *
* filename: The filename that the image will be written to. * filename: The filename that the image will be written to.
* w: The width of the PNG data. * w: The width of the PNG data.
* h: The height of the PNG data. * h: The height of the PNG data.
* data: The raw RGBA8 image data. * bgra: Whether the data is in BGRA8 format. Otherwise will assume RBGA8.
* data: The raw color data.
*/ */
REFRESHAPI void Refresh_Image_SavePNG( REFRESHAPI void Refresh_Image_SavePNG(
char const *filename, char const *filename,
int32_t w, int32_t w,
int32_t h, int32_t h,
uint8_t bgra,
uint8_t *data uint8_t *data
); );

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* Refresh - XNA-inspired 3D Graphics Library with modern capabilities /* Refresh - XNA-inspired 3D Graphics Library with modern capabilities
* *
* Copyright (c) 2020 Evan Hemsley * Copyright (c) 2020 Evan Hemsley
* *
@ -36,9 +36,15 @@
/* Logging */ /* Logging */
extern void Refresh_LogInfo(const char *fmt, ...); #ifdef __cplusplus
extern void Refresh_LogWarn(const char *fmt, ...); extern "C" {
extern void Refresh_LogError(const char *fmt, ...); #endif
void Refresh_LogInfo(const char *fmt, ...);
void Refresh_LogWarn(const char *fmt, ...);
void Refresh_LogError(const char *fmt, ...);
#ifdef __cplusplus
}
#endif
/* Internal Helper Utilities */ /* Internal Helper Utilities */
@ -51,6 +57,7 @@ static inline uint32_t Texture_GetFormatSize(
return 8; return 8;
case REFRESH_TEXTUREFORMAT_BC2: case REFRESH_TEXTUREFORMAT_BC2:
case REFRESH_TEXTUREFORMAT_BC3: case REFRESH_TEXTUREFORMAT_BC3:
case REFRESH_TEXTUREFORMAT_BC7:
return 16; return 16;
case REFRESH_TEXTUREFORMAT_R8: case REFRESH_TEXTUREFORMAT_R8:
return 1; return 1;
@ -117,7 +124,8 @@ static inline uint32_t BytesPerRow(
if ( format == REFRESH_TEXTUREFORMAT_BC1 || if ( format == REFRESH_TEXTUREFORMAT_BC1 ||
format == REFRESH_TEXTUREFORMAT_BC2 || format == REFRESH_TEXTUREFORMAT_BC2 ||
format == REFRESH_TEXTUREFORMAT_BC3 ) format == REFRESH_TEXTUREFORMAT_BC3 ||
format == REFRESH_TEXTUREFORMAT_BC7 )
{ {
blocksPerRow = (width + 3) / 4; blocksPerRow = (width + 3) / 4;
} }
@ -135,7 +143,8 @@ static inline int32_t BytesPerImage(
if ( format == REFRESH_TEXTUREFORMAT_BC1 || if ( format == REFRESH_TEXTUREFORMAT_BC1 ||
format == REFRESH_TEXTUREFORMAT_BC2 || format == REFRESH_TEXTUREFORMAT_BC2 ||
format == REFRESH_TEXTUREFORMAT_BC3 ) format == REFRESH_TEXTUREFORMAT_BC3 ||
format == REFRESH_TEXTUREFORMAT_BC7 )
{ {
blocksPerRow = (width + 3) / 4; blocksPerRow = (width + 3) / 4;
blocksPerColumn = (height + 3) / 4; blocksPerColumn = (height + 3) / 4;
@ -151,9 +160,10 @@ static inline int32_t BytesPerImage(
#define MAX_VERTEXTEXTURE_SAMPLERS 4 #define MAX_VERTEXTEXTURE_SAMPLERS 4
#define MAX_TOTAL_SAMPLERS (MAX_TEXTURE_SAMPLERS + MAX_VERTEXTEXTURE_SAMPLERS) #define MAX_TOTAL_SAMPLERS (MAX_TEXTURE_SAMPLERS + MAX_VERTEXTEXTURE_SAMPLERS)
#define MAX_BUFFER_BINDINGS 16 #define MAX_BUFFER_BINDINGS 16
#define MAX_COLOR_TARGET_BINDINGS 4 #define MAX_COLOR_TARGET_BINDINGS 4
#define MAX_PRESENT_COUNT 16
/* Refresh_Device Definition */ /* Refresh_Device Definition */
@ -167,325 +177,298 @@ struct Refresh_Device
/* Drawing */ /* Drawing */
void (*Clear)(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *clearRect,
Refresh_ClearOptions options,
Refresh_Vec4 *colors,
uint32_t colorCount,
Refresh_DepthStencilValue depthStencil
);
void (*DrawInstancedPrimitives)( void (*DrawInstancedPrimitives)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
uint32_t baseVertex, uint32_t baseVertex,
uint32_t startIndex, uint32_t startIndex,
uint32_t primitiveCount, uint32_t primitiveCount,
uint32_t instanceCount, uint32_t instanceCount,
uint32_t vertexParamOffset, uint32_t vertexParamOffset,
uint32_t fragmentParamOffset uint32_t fragmentParamOffset
); );
void (*DrawIndexedPrimitives)( void (*DrawIndexedPrimitives)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
uint32_t baseVertex, uint32_t baseVertex,
uint32_t startIndex, uint32_t startIndex,
uint32_t primitiveCount, uint32_t primitiveCount,
uint32_t vertexParamOffset, uint32_t vertexParamOffset,
uint32_t fragmentParamOffset uint32_t fragmentParamOffset
); );
void (*DrawPrimitives)( void (*DrawPrimitives)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
uint32_t vertexStart, uint32_t vertexStart,
uint32_t primitiveCount, uint32_t primitiveCount,
uint32_t vertexParamOffset, uint32_t vertexParamOffset,
uint32_t fragmentParamOffset uint32_t fragmentParamOffset
); );
void (*DispatchCompute)( void (*DispatchCompute)(
Refresh_Renderer *device, Refresh_Renderer *device,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
uint32_t groupCountX, uint32_t groupCountX,
uint32_t groupCountY, uint32_t groupCountY,
uint32_t groupCountZ, uint32_t groupCountZ,
uint32_t computeParamOffset uint32_t computeParamOffset
); );
/* State Creation */ /* State Creation */
Refresh_RenderPass* (*CreateRenderPass)( Refresh_ComputePipeline* (*CreateComputePipeline)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_RenderPassCreateInfo *renderPassCreateInfo Refresh_ComputeShaderInfo *computeShaderInfo
); );
Refresh_ComputePipeline* (*CreateComputePipeline)( Refresh_GraphicsPipeline* (*CreateGraphicsPipeline)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_ComputePipelineCreateInfo *pipelineCreateInfo Refresh_GraphicsPipelineCreateInfo *pipelineCreateInfo
); );
Refresh_GraphicsPipeline* (*CreateGraphicsPipeline)( Refresh_Sampler* (*CreateSampler)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_GraphicsPipelineCreateInfo *pipelineCreateInfo Refresh_SamplerStateCreateInfo *samplerStateCreateInfo
); );
Refresh_Sampler* (*CreateSampler)( Refresh_ShaderModule* (*CreateShaderModule)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_SamplerStateCreateInfo *samplerStateCreateInfo Refresh_ShaderModuleCreateInfo *shaderModuleCreateInfo
); );
Refresh_Framebuffer* (*CreateFramebuffer)( Refresh_Texture* (*CreateTexture)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_FramebufferCreateInfo *framebufferCreateInfo Refresh_TextureCreateInfo *textureCreateInfo
); );
Refresh_ShaderModule* (*CreateShaderModule)( Refresh_Buffer* (*CreateBuffer)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_ShaderModuleCreateInfo *shaderModuleCreateInfo Refresh_BufferUsageFlags usageFlags,
); uint32_t sizeInBytes
);
Refresh_Texture* (*CreateTexture)( /* Setters */
Refresh_Renderer *driverData,
Refresh_TextureCreateInfo *textureCreateInfo
);
Refresh_RenderTarget* (*CreateRenderTarget)( void(*SetTextureData)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_TextureSlice *textureSlice, Refresh_CommandBuffer *commandBuffer,
Refresh_SampleCount multisampleCount Refresh_TextureSlice *textureSlice,
); void *data,
uint32_t dataLengthInBytes
);
Refresh_Buffer* (*CreateBuffer)( void(*SetTextureDataYUV)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_BufferUsageFlags usageFlags, Refresh_CommandBuffer* commandBuffer,
uint32_t sizeInBytes Refresh_Texture *y,
); Refresh_Texture *u,
Refresh_Texture *v,
uint32_t yWidth,
uint32_t yHeight,
uint32_t uvWidth,
uint32_t uvHeight,
void* data,
uint32_t dataLength
);
/* Setters */ void(*CopyTextureToTexture)(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *sourceTextureSlice,
Refresh_TextureSlice *destinationTextureSlice,
Refresh_Filter filter
);
void(*SetTextureData)( void(*CopyTextureToBuffer)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *textureSlice, Refresh_TextureSlice *textureSlice,
void *data, Refresh_Buffer *buffer
uint32_t dataLengthInBytes );
);
void(*SetTextureDataYUV)( void(*SetBufferData)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer* commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Texture *y, Refresh_Buffer *buffer,
Refresh_Texture *u, uint32_t offsetInBytes,
Refresh_Texture *v, void* data,
uint32_t yWidth, uint32_t dataLength
uint32_t yHeight, );
uint32_t uvWidth,
uint32_t uvHeight,
void* data,
uint32_t dataLength
);
void(*CopyTextureToTexture)( uint32_t(*PushVertexShaderUniforms)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *sourceTextureSlice, void *data,
Refresh_TextureSlice *destinationTextureSlice, uint32_t dataLengthInBytes
Refresh_Filter filter );
);
void(*CopyTextureToBuffer)( uint32_t(*PushFragmentShaderUniforms)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *textureSlice, void *data,
Refresh_Buffer *buffer uint32_t dataLengthInBytes
); );
void(*SetBufferData)( uint32_t (*PushComputeShaderUniforms)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Buffer *buffer, void *data,
uint32_t offsetInBytes, uint32_t dataLengthInBytes
void* data, );
uint32_t dataLength
);
uint32_t(*PushVertexShaderUniforms)( void(*BindVertexSamplers)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
void *data, Refresh_Texture **pTextures,
uint32_t dataLengthInBytes Refresh_Sampler **pSamplers
); );
uint32_t(*PushFragmentShaderUniforms)( void(*BindFragmentSamplers)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
void *data, Refresh_Texture **pTextures,
uint32_t dataLengthInBytes Refresh_Sampler **pSamplers
); );
uint32_t (*PushComputeShaderUniforms)( /* Getters */
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
void *data,
uint32_t dataLengthInBytes
);
void(*BindVertexSamplers)( void(*GetBufferData)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_Buffer *buffer,
Refresh_Texture **pTextures, void *data,
Refresh_Sampler **pSamplers uint32_t dataLengthInBytes
); );
void(*BindFragmentSamplers)( /* Disposal */
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers
);
/* Getters */ void(*QueueDestroyTexture)(
Refresh_Renderer *driverData,
Refresh_Texture *texture
);
void(*GetBufferData)( void(*QueueDestroySampler)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_Buffer *buffer, Refresh_Sampler *sampler
void *data, );
uint32_t dataLengthInBytes
);
/* Disposal */ void(*QueueDestroyBuffer)(
Refresh_Renderer *driverData,
Refresh_Buffer *buffer
);
void(*QueueDestroyTexture)( void(*QueueDestroyShaderModule)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_Texture *texture Refresh_ShaderModule *shaderModule
); );
void(*QueueDestroySampler)( void(*QueueDestroyComputePipeline)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_Sampler *sampler Refresh_ComputePipeline *computePipeline
); );
void(*QueueDestroyBuffer)( void(*QueueDestroyGraphicsPipeline)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_Buffer *buffer Refresh_GraphicsPipeline *graphicsPipeline
); );
void(*QueueDestroyRenderTarget)( /* Graphics State */
Refresh_Renderer *driverData,
Refresh_RenderTarget *renderTarget
);
void(*QueueDestroyFramebuffer)( void(*BeginRenderPass)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_Framebuffer *frameBuffer Refresh_CommandBuffer *commandBuffer,
); Refresh_Rect *renderArea,
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorAttachmentCount,
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
);
void(*QueueDestroyShaderModule)( void(*EndRenderPass)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_ShaderModule *shaderModule Refresh_CommandBuffer *commandBuffer
); );
void(*QueueDestroyRenderPass)( void(*SetViewport)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_RenderPass *renderPass Refresh_CommandBuffer *commandBuffer,
); Refresh_Viewport *viewport
);
void(*QueueDestroyComputePipeline)( void(*SetScissor)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_ComputePipeline *computePipeline Refresh_CommandBuffer *commandBuffer,
); Refresh_Rect *scissor
);
void(*QueueDestroyGraphicsPipeline)( void(*BindGraphicsPipeline)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_GraphicsPipeline *graphicsPipeline Refresh_CommandBuffer *commandBuffer,
); Refresh_GraphicsPipeline *graphicsPipeline
);
/* Graphics State */ void(*BindVertexBuffers)(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
Refresh_Buffer **pBuffers,
uint64_t *pOffsets
);
void(*BeginRenderPass)( void(*BindIndexBuffer)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_RenderPass *renderPass, Refresh_Buffer *buffer,
Refresh_Framebuffer *framebuffer, uint64_t offset,
Refresh_Rect *renderArea, Refresh_IndexElementSize indexElementSize
Refresh_Vec4 *pColorClearValues, );
uint32_t colorClearCount,
Refresh_DepthStencilValue *depthStencilClearValue
);
void(*EndRenderPass)( void(*BindComputePipeline)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer Refresh_CommandBuffer *commandBuffer,
); Refresh_ComputePipeline *computePipeline
);
void(*BindGraphicsPipeline)( void(*BindComputeBuffers)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_GraphicsPipeline *graphicsPipeline Refresh_Buffer **pBuffers
); );
void(*BindVertexBuffers)( void(*BindComputeTextures)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
uint32_t firstBinding, Refresh_Texture **pTextures
uint32_t bindingCount, );
Refresh_Buffer **pBuffers,
uint64_t *pOffsets
);
void(*BindIndexBuffer)( Refresh_CommandBuffer* (*AcquireCommandBuffer)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, uint8_t fixed
Refresh_Buffer *buffer, );
uint64_t offset,
Refresh_IndexElementSize indexElementSize
);
void(*BindComputePipeline)( Refresh_Texture* (*AcquireSwapchainTexture)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_ComputePipeline *computePipeline void *windowHandle,
); uint32_t *pWidth,
uint32_t *pHeight
);
void(*BindComputeBuffers)( Refresh_TextureFormat (*GetSwapchainFormat)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Buffer **pBuffers
);
void(*BindComputeTextures)(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures
);
Refresh_CommandBuffer* (*AcquireCommandBuffer)(
Refresh_Renderer *driverData,
uint8_t fixed
);
void(*QueuePresent)(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *textureSlice,
Refresh_Rect *destinationRectangle,
Refresh_Filter filter,
void *windowHandle void *windowHandle
); );
void(*Submit)( void(*Submit)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
uint32_t commandBufferCount, uint32_t commandBufferCount,
Refresh_CommandBuffer **pCommandBuffers Refresh_CommandBuffer **pCommandBuffers
); );
void(*Wait)( void(*Wait)(
Refresh_Renderer *driverData Refresh_Renderer *driverData
); );
/* Opaque pointer for the Driver */ /* Opaque pointer for the Driver */
Refresh_Renderer *driverData; Refresh_Renderer *driverData;
@ -495,63 +478,60 @@ struct Refresh_Device
result->func = name##_##func; result->func = name##_##func;
#define ASSIGN_DRIVER(name) \ #define ASSIGN_DRIVER(name) \
ASSIGN_DRIVER_FUNC(DestroyDevice, name) \ ASSIGN_DRIVER_FUNC(DestroyDevice, name) \
ASSIGN_DRIVER_FUNC(Clear, name) \
ASSIGN_DRIVER_FUNC(DrawIndexedPrimitives, name) \ ASSIGN_DRIVER_FUNC(DrawIndexedPrimitives, name) \
ASSIGN_DRIVER_FUNC(DrawInstancedPrimitives, name) \ ASSIGN_DRIVER_FUNC(DrawInstancedPrimitives, name) \
ASSIGN_DRIVER_FUNC(DrawPrimitives, name) \ ASSIGN_DRIVER_FUNC(DrawPrimitives, name) \
ASSIGN_DRIVER_FUNC(DispatchCompute, name) \ ASSIGN_DRIVER_FUNC(DispatchCompute, name) \
ASSIGN_DRIVER_FUNC(CreateRenderPass, name) \ ASSIGN_DRIVER_FUNC(CreateComputePipeline, name) \
ASSIGN_DRIVER_FUNC(CreateComputePipeline, name) \ ASSIGN_DRIVER_FUNC(CreateGraphicsPipeline, name) \
ASSIGN_DRIVER_FUNC(CreateGraphicsPipeline, name) \ ASSIGN_DRIVER_FUNC(CreateSampler, name) \
ASSIGN_DRIVER_FUNC(CreateSampler, name) \ ASSIGN_DRIVER_FUNC(CreateShaderModule, name) \
ASSIGN_DRIVER_FUNC(CreateFramebuffer, name) \ ASSIGN_DRIVER_FUNC(CreateTexture, name) \
ASSIGN_DRIVER_FUNC(CreateShaderModule, name) \ ASSIGN_DRIVER_FUNC(CreateBuffer, name) \
ASSIGN_DRIVER_FUNC(CreateTexture, name) \ ASSIGN_DRIVER_FUNC(SetTextureData, name) \
ASSIGN_DRIVER_FUNC(CreateRenderTarget, name) \ ASSIGN_DRIVER_FUNC(SetTextureDataYUV, name) \
ASSIGN_DRIVER_FUNC(CreateBuffer, name) \ ASSIGN_DRIVER_FUNC(CopyTextureToTexture, name) \
ASSIGN_DRIVER_FUNC(SetTextureData, name) \ ASSIGN_DRIVER_FUNC(CopyTextureToBuffer, name) \
ASSIGN_DRIVER_FUNC(SetTextureDataYUV, name) \ ASSIGN_DRIVER_FUNC(SetBufferData, name) \
ASSIGN_DRIVER_FUNC(CopyTextureToTexture, name) \ ASSIGN_DRIVER_FUNC(PushVertexShaderUniforms, name) \
ASSIGN_DRIVER_FUNC(CopyTextureToBuffer, name) \ ASSIGN_DRIVER_FUNC(PushFragmentShaderUniforms, name) \
ASSIGN_DRIVER_FUNC(SetBufferData, name) \ ASSIGN_DRIVER_FUNC(PushComputeShaderUniforms, name) \
ASSIGN_DRIVER_FUNC(PushVertexShaderUniforms, name) \ ASSIGN_DRIVER_FUNC(BindVertexSamplers, name) \
ASSIGN_DRIVER_FUNC(PushFragmentShaderUniforms, name) \ ASSIGN_DRIVER_FUNC(BindFragmentSamplers, name) \
ASSIGN_DRIVER_FUNC(PushComputeShaderUniforms, name) \ ASSIGN_DRIVER_FUNC(GetBufferData, name) \
ASSIGN_DRIVER_FUNC(BindVertexSamplers, name) \ ASSIGN_DRIVER_FUNC(QueueDestroyTexture, name) \
ASSIGN_DRIVER_FUNC(BindFragmentSamplers, name) \ ASSIGN_DRIVER_FUNC(QueueDestroySampler, name) \
ASSIGN_DRIVER_FUNC(GetBufferData, name) \ ASSIGN_DRIVER_FUNC(QueueDestroyBuffer, name) \
ASSIGN_DRIVER_FUNC(QueueDestroyTexture, name) \ ASSIGN_DRIVER_FUNC(QueueDestroyShaderModule, name) \
ASSIGN_DRIVER_FUNC(QueueDestroySampler, name) \ ASSIGN_DRIVER_FUNC(QueueDestroyComputePipeline, name) \
ASSIGN_DRIVER_FUNC(QueueDestroyBuffer, name) \ ASSIGN_DRIVER_FUNC(QueueDestroyGraphicsPipeline, name) \
ASSIGN_DRIVER_FUNC(QueueDestroyRenderTarget, name) \ ASSIGN_DRIVER_FUNC(BeginRenderPass, name) \
ASSIGN_DRIVER_FUNC(QueueDestroyFramebuffer, name) \ ASSIGN_DRIVER_FUNC(EndRenderPass, name) \
ASSIGN_DRIVER_FUNC(QueueDestroyShaderModule, name) \ ASSIGN_DRIVER_FUNC(SetViewport, name) \
ASSIGN_DRIVER_FUNC(QueueDestroyRenderPass, name) \ ASSIGN_DRIVER_FUNC(SetScissor, name) \
ASSIGN_DRIVER_FUNC(QueueDestroyComputePipeline, name) \ ASSIGN_DRIVER_FUNC(BindGraphicsPipeline, name) \
ASSIGN_DRIVER_FUNC(QueueDestroyGraphicsPipeline, name) \ ASSIGN_DRIVER_FUNC(BindVertexBuffers, name) \
ASSIGN_DRIVER_FUNC(BeginRenderPass, name) \ ASSIGN_DRIVER_FUNC(BindIndexBuffer, name) \
ASSIGN_DRIVER_FUNC(EndRenderPass, name) \ ASSIGN_DRIVER_FUNC(BindComputePipeline, name) \
ASSIGN_DRIVER_FUNC(BindGraphicsPipeline, name) \ ASSIGN_DRIVER_FUNC(BindComputeBuffers, name) \
ASSIGN_DRIVER_FUNC(BindVertexBuffers, name) \ ASSIGN_DRIVER_FUNC(BindComputeTextures, name) \
ASSIGN_DRIVER_FUNC(BindIndexBuffer, name) \ ASSIGN_DRIVER_FUNC(AcquireCommandBuffer, name) \
ASSIGN_DRIVER_FUNC(BindComputePipeline, name) \ ASSIGN_DRIVER_FUNC(AcquireSwapchainTexture, name) \
ASSIGN_DRIVER_FUNC(BindComputeBuffers, name) \ ASSIGN_DRIVER_FUNC(GetSwapchainFormat, name) \
ASSIGN_DRIVER_FUNC(BindComputeTextures, name) \ ASSIGN_DRIVER_FUNC(Submit, name) \
ASSIGN_DRIVER_FUNC(AcquireCommandBuffer, name) \ ASSIGN_DRIVER_FUNC(Wait, name)
ASSIGN_DRIVER_FUNC(QueuePresent, name) \
ASSIGN_DRIVER_FUNC(Submit, name) \
ASSIGN_DRIVER_FUNC(Wait, name)
typedef struct Refresh_Driver typedef struct Refresh_Driver
{ {
const char *Name; const char *Name;
Refresh_Device* (*CreateDevice)( Refresh_Device* (*CreateDevice)(
Refresh_PresentationParameters *presentationParameters, Refresh_PresentationParameters *presentationParameters,
uint8_t debugMode uint8_t debugMode
); );
} Refresh_Driver; } Refresh_Driver;
extern Refresh_Driver VulkanDriver; extern Refresh_Driver VulkanDriver;
extern Refresh_Driver PS5Driver;
#endif /* REFRESH_DRIVER_H */ #endif /* REFRESH_DRIVER_H */

View File

@ -0,0 +1,629 @@
/* Refresh - XNA-inspired 3D Graphics Library with modern capabilities
*
* Copyright (c) 2020 Evan Hemsley
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in a
* product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
* Evan "cosmonaut" Hemsley <evan@moonside.games>
*
*/
#if REFRESH_DRIVER_TEMPLATE
#include "Refresh_Driver.h"
#include <SDL.h>
#define NOT_IMPLEMENTED SDL_assert(0 && "Not implemented!");
/* Conversions */
static TEMPLATE_SURFACE_FORMAT_TYPE RefreshToTEMPLATE_SurfaceFormat[] =
{
0, /* R8G8B8A8 */
0, /* B8G8R8A8 */
0, /* R5G6B5 */
0, /* A1R5G5B5 */
0, /* B4G4R4A4 */
0, /* BC1 */
0, /* BC3 */
0, /* BC5 */
0, /* R8G8_SNORM */
0, /* R8G8B8A8_SNORM */
0, /* A2R10G10B10 */
0, /* R16G16 */
0, /* R16G16B16A16 */
0, /* R8 */
0, /* R32_SFLOAT */
0, /* R32G32_SFLOAT */
0, /* R32G32B32A32_SFLOAT */
0, /* R16_SFLOAT */
0, /* R16G16_SFLOAT */
0, /* R16G16B16A16_SFLOAT */
0, /* D16 */
0, /* D32 */
0, /* D16S8 */
0 /* D32S8 */
};
static TEMPLATE_VERTEX_FORMAT_TYPE RefreshToTEMPLATE_VertexFormat[] =
{
0, /* SINGLE */
0, /* VECTOR2 */
0, /* VECTOR3 */
0, /* VECTOR4 */
0, /* COLOR */
0, /* BYTE4 */
0, /* SHORT2 */
0, /* SHORT4 */
0, /* NORMALIZEDSHORT2 */
0, /* NORMALIZEDSHORT4 */
0, /* HALFVECTOR2 */
0 /* HALFVECTOR4 */
};
static TEMPLATE_INDEX_TYPE RefreshToTEMPLATE_IndexType[] =
{
0, /* 16BIT */
0 /* 32BIT */
};
static TEMPLATE_PRIMITIVE_TYPE RefreshToTEMPLATE_PrimitiveType[] =
{
0, /* POINTLIST */
0, /* LINELIST */
0, /* LINESTRIP */
0, /* TRIANGLELIST */
0 /* TRIANGLESTRIP */
};
static TEMPLATE_POLYGON_MODE_TYPE RefreshToTEMPLATE_PolygonMode[] =
{
0, /* FILL */
0, /* LINE */
};
static TEMPLATE_CULL_MODE_TYPE RefreshToTEMPLATE_CullMode[] =
{
0, /* NONE */
0, /* FRONT */
0, /* BACK */
};
static TEMPLATE_FRONT_FACE_TYPE RefreshToTEMPLATE_FrontFace[] =
{
0, /* COUNTER_CLOCKWISE */
0 /* CLOCKWISE */
};
static TEMPLATE_BLEND_FACTOR_TYPE RefreshToTEMPLATE_BlendFactor[] =
{
0, /* ZERO */
0, /* ONE */
0, /* SRC_COLOR */
0, /* ONE_MINUS_SRC_COLOR */
0, /* DST_COLOR */
0, /* ONE_MINUS_DST_COLOR */
0, /* SRC_ALPHA */
0, /* ONE_MINUS_SRC_ALPHA */
0, /* DST_ALPHA */
0, /* ONE_MINUS_DST_ALPHA */
0, /* CONSTANT_COLOR */
0, /* ONE_MINUS_CONSTANT_COLOR */
0, /* SRC_ALPHA_SATURATE */
0, /* SRC1_COLOR */
0, /* ONE_MINUS_SRC1_COLOR */
0, /* SRC1_ALPHA */
0 /* ONE_MINUS_SRC1_ALPHA */
};
static TEMPLATE_BLEND_OP_TYPE RefreshToTEMPLATE_BlendOp[] =
{
0, /* ADD */
0, /* SUBTRACT */
0, /* REVERSE_SUBTRACT */
0, /* MIN */
0 /* MAX */
};
static TEMPLATE_COMPARE_OP_TYPE RefreshToTEMPLATE_CompareOp[] =
{
0, /* NEVER */
0, /* LESS */
0, /* EQUAL */
0, /* LESS_OR_EQUAL */
0, /* GREATER */
0, /* NOT_EQUAL */
0, /* GREATER_OR_EQUAL */
0 /* ALWAYS */
};
static TEMPLATE_STENCIL_OP_TYPE RefreshToTEMPLATE_StencilOp[] =
{
0, /* KEEP */
0, /* ZERO */
0, /* REPLACE */
0, /* INCREMENT_AND_CLAMP */
0, /* DECREMENT_AND_CLAMP */
0, /* INVERT */
0, /* INCREMENT_AND_WRAP */
0 /* DECREMENT_AND_WRAP */
};
static TEMPLATE_ATTACHMENT_LOAD_OP_TYPE RefreshToTEMPLATE_LoadOp[] =
{
0, /* LOAD */
0, /* CLEAR */
0 /* DONT_CARE */
};
static TEMPLATE_ATTACHMENT_STORE_OP_TYPE RefreshToTEMPLATE_StoreOp[] =
{
0, /* STORE */
0 /* DONT_CARE */
};
static TEMPLATE_SAMPLE_COUNT_TYPE RefreshToTEMPLATE_SampleCount[] =
{
0, /* 1 */
0, /* 2 */
0, /* 4 */
0, /* 8 */
0, /* 16 */
0, /* 32 */
0 /* 64 */
};
static TEMPLATE_VERTEX_INPUT_RATE_TYPE RefreshToTEMPLATE_VertexInputRate[] =
{
0, /* VERTEX */
0 /* INSTANCE */
};
static TEMPLATE_FILTER_TYPE RefreshToTEMPLATE_Filter[] =
{
0, /* NEAREST */
0, /* LINEAR */
};
static TEMPLATE_SAMPLER_MIPMAP_MODE_TYPE RefreshToTEMPLATE_SamplerMipmapMode[] =
{
0, /* NEAREST */
0 /* LINEAR */
};
static TEMPLATE_SAMPLER_ADDRESS_MODE_TYPE RefreshToTEMPLATE_SamplerAddressMode[] =
{
0, /* REPEAT */
0, /* MIRRORED_REPEAT */
0, /* CLAMP_TO_EDGE */
0 /* CLAMP_TO_BORDER */
};
static TEMPLATE_BORDER_COLOR_TYPE RefreshToTEMPLATE_BorderColor[] =
{
0, /* FLOAT_TRANSPARENT_BLACK */
0, /* INT_TRANSPARENT_BLACK */
0, /* FLOAT_OPAQUE_BLACK */
0, /* INT_OPAQUE_BLACK */
0, /* FLOAT_OPAQUE_WHITE */
0 /* INT_OPAQUE_WHITE */
};
/* Quit */
static void TEMPLATE_DestroyDevice(
Refresh_Device *device
) {
NOT_IMPLEMENTED
}
/* Drawing */
static void TEMPLATE_DrawInstancedPrimitives(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
uint32_t baseVertex,
uint32_t startIndex,
uint32_t primitiveCount,
uint32_t instanceCount,
uint32_t vertexParamOffset,
uint32_t fragmentParamOffset
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_DrawIndexedPrimitives(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
uint32_t baseVertex,
uint32_t startIndex,
uint32_t primitiveCount,
uint32_t vertexParamOffset,
uint32_t fragmentParamOffset
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_DrawPrimitives(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
uint32_t vertexStart,
uint32_t primitiveCount,
uint32_t vertexParamOffset,
uint32_t fragmentParamOffset
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_DispatchCompute(
Refresh_Renderer *device,
Refresh_CommandBuffer *commandBuffer,
uint32_t groupCountX,
uint32_t groupCountY,
uint32_t groupCountZ,
uint32_t computeParamOffset
) {
NOT_IMPLEMENTED
}
/* State Creation */
static Refresh_ComputePipeline* TEMPLATE_CreateComputePipeline(
Refresh_Renderer *driverData,
Refresh_ComputeShaderInfo *computeShaderInfo
) {
NOT_IMPLEMENTED
}
static Refresh_GraphicsPipeline* TEMPLATE_CreateGraphicsPipeline(
Refresh_Renderer *driverData,
Refresh_GraphicsPipelineCreateInfo *pipelineCreateInfo
) {
NOT_IMPLEMENTED
}
static Refresh_Sampler* TEMPLATE_CreateSampler(
Refresh_Renderer *driverData,
Refresh_SamplerStateCreateInfo *samplerStateCreateInfo
) {
NOT_IMPLEMENTED
}
static Refresh_ShaderModule* TEMPLATE_CreateShaderModule(
Refresh_Renderer *driverData,
Refresh_ShaderModuleCreateInfo *shaderModuleCreateInfo
) {
NOT_IMPLEMENTED
}
static Refresh_Texture* TEMPLATE_CreateTexture(
Refresh_Renderer *driverData,
Refresh_TextureCreateInfo *textureCreateInfo
) {
NOT_IMPLEMENTED
}
static Refresh_Buffer* TEMPLATE_CreateBuffer(
Refresh_Renderer *driverData,
Refresh_BufferUsageFlags usageFlags,
uint32_t sizeInBytes
) {
NOT_IMPLEMENTED
}
/* Setters */
static void TEMPLATE_SetTextureData(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *textureSlice,
void *data,
uint32_t dataLengthInBytes
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_SetTextureDataYUV(
Refresh_Renderer *driverData,
Refresh_CommandBuffer* commandBuffer,
Refresh_Texture *y,
Refresh_Texture *u,
Refresh_Texture *v,
uint32_t yWidth,
uint32_t yHeight,
uint32_t uvWidth,
uint32_t uvHeight,
void* data,
uint32_t dataLength
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_CopyTextureToTexture(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *sourceTextureSlice,
Refresh_TextureSlice *destinationTextureSlice,
Refresh_Filter filter
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_CopyTextureToBuffer(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *textureSlice,
Refresh_Buffer *buffer
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_SetBufferData(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Buffer *buffer,
uint32_t offsetInBytes,
void* data,
uint32_t dataLength
) {
NOT_IMPLEMENTED
}
static uint32_t TEMPLATE_PushVertexShaderUniforms(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
void *data,
uint32_t dataLengthInBytes
) {
NOT_IMPLEMENTED
}
static uint32_t TEMPLATE_PushFragmentShaderUniforms(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
void *data,
uint32_t dataLengthInBytes
) {
NOT_IMPLEMENTED
}
static uint32_t TEMPLATE_PushComputeShaderUniforms(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
void *data,
uint32_t dataLengthInBytes
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_BindVertexSamplers(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_BindFragmentSamplers(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers
) {
NOT_IMPLEMENTED
}
/* Getters */
static void TEMPLATE_GetBufferData(
Refresh_Renderer *driverData,
Refresh_Buffer *buffer,
void *data,
uint32_t dataLengthInBytes
) {
NOT_IMPLEMENTED
}
/* Disposal */
static void TEMPLATE_QueueDestroyTexture(
Refresh_Renderer *driverData,
Refresh_Texture *texture
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_QueueDestroySampler(
Refresh_Renderer *driverData,
Refresh_Sampler *sampler
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_QueueDestroyBuffer(
Refresh_Renderer *driverData,
Refresh_Buffer *buffer
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_QueueDestroyShaderModule(
Refresh_Renderer *driverData,
Refresh_ShaderModule *shaderModule
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_QueueDestroyComputePipeline(
Refresh_Renderer *driverData,
Refresh_ComputePipeline *computePipeline
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_QueueDestroyGraphicsPipeline(
Refresh_Renderer *driverData,
Refresh_GraphicsPipeline *graphicsPipeline
) {
NOT_IMPLEMENTED
}
/* Graphics State */
static void TEMPLATE_BeginRenderPass(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *renderArea,
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorAttachmentCount,
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_EndRenderPass(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_BindGraphicsPipeline(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_GraphicsPipeline *graphicsPipeline
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_SetViewport(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Viewport *viewport
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_SetScissor(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *scissor
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_BindVertexBuffers(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
Refresh_Buffer **pBuffers,
uint64_t *pOffsets
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_BindIndexBuffer(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Buffer *buffer,
uint64_t offset,
Refresh_IndexElementSize indexElementSize
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_BindComputePipeline(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_ComputePipeline *computePipeline
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_BindComputeBuffers(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Buffer **pBuffers
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_BindComputeTextures(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures
) {
NOT_IMPLEMENTED
}
static Refresh_CommandBuffer* TEMPLATE_AcquireCommandBuffer(
Refresh_Renderer *driverData,
uint8_t fixed
) {
NOT_IMPLEMENTED
}
Refresh_Texture* TEMPLATE_AcquireSwapchainTexture(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
void *windowHandle,
uint32_t *pWidth,
uint32_t *pHeight
) {
NOT_IMPLEMENTED
}
Refresh_TextureFormat TEMPLATE_GetSwapchainFormat(
Refresh_Renderer *driverData,
void *windowHandle
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_Submit(
Refresh_Renderer *driverData,
uint32_t commandBufferCount,
Refresh_CommandBuffer **pCommandBuffers
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_Wait(
Refresh_Renderer *driverData
) {
NOT_IMPLEMENTED
}
static Refresh_Device* TEMPLATE_CreateDevice(
Refresh_PresentationParameters *presentationParameters,
uint8_t debugMode
) {
NOT_IMPLEMENTED
}
Refresh_Driver TEMPLATEDriver = {
"TEMPLATE",
TEMPLATE_CreateDevice
};
#endif //REFRESH_DRIVER_TEMPLATE

File diff suppressed because it is too large Load Diff

View File

@ -89,53 +89,53 @@
static void * static void *
SDL_SIMDRealloc(void *mem, const size_t len) SDL_SIMDRealloc(void *mem, const size_t len)
{ {
const size_t alignment = SDL_SIMDGetAlignment(); const size_t alignment = SDL_SIMDGetAlignment();
const size_t padding = alignment - (len % alignment); const size_t padding = alignment - (len % alignment);
const size_t padded = (padding != alignment) ? (len + padding) : len; const size_t padded = (padding != alignment) ? (len + padding) : len;
Uint8 *retval = (Uint8*) mem; Uint8 *retval = (Uint8*) mem;
void *oldmem = mem; void *oldmem = mem;
size_t memdiff, ptrdiff; size_t memdiff, ptrdiff;
Uint8 *ptr; Uint8 *ptr;
if (mem) { if (mem) {
void **realptr = (void **) mem; void **realptr = (void **) mem;
realptr--; realptr--;
mem = *(((void **) mem) - 1); mem = *(((void **) mem) - 1);
/* Check the delta between the real pointer and user pointer */ /* Check the delta between the real pointer and user pointer */
memdiff = ((size_t) oldmem) - ((size_t) mem); memdiff = ((size_t) oldmem) - ((size_t) mem);
} }
ptr = (Uint8 *) SDL_realloc(mem, padded + alignment + sizeof (void *)); ptr = (Uint8 *) SDL_realloc(mem, padded + alignment + sizeof (void *));
if (ptr == mem) { if (ptr == mem) {
return retval; /* Pointer didn't change, nothing to do */ return retval; /* Pointer didn't change, nothing to do */
} }
if (ptr == NULL) { if (ptr == NULL) {
return NULL; /* Out of memory, bail! */ return NULL; /* Out of memory, bail! */
} }
/* Store the actual malloc pointer right before our aligned pointer. */ /* Store the actual malloc pointer right before our aligned pointer. */
retval = ptr + sizeof (void *); retval = ptr + sizeof (void *);
retval += alignment - (((size_t) retval) % alignment); retval += alignment - (((size_t) retval) % alignment);
/* Make sure the delta is the same! */ /* Make sure the delta is the same! */
if (mem) { if (mem) {
ptrdiff = ((size_t) retval) - ((size_t) ptr); ptrdiff = ((size_t) retval) - ((size_t) ptr);
if (memdiff != ptrdiff) { /* Delta has changed, copy to new offset! */ if (memdiff != ptrdiff) { /* Delta has changed, copy to new offset! */
oldmem = (void*) (((size_t) ptr) + memdiff); oldmem = (void*) (((size_t) ptr) + memdiff);
/* Even though the data past the old `len` is undefined, this is the /* Even though the data past the old `len` is undefined, this is the
* only length value we have, and it guarantees that we copy all the * only length value we have, and it guarantees that we copy all the
* previous memory anyhow. * previous memory anyhow.
*/ */
SDL_memmove(retval, oldmem, len); SDL_memmove(retval, oldmem, len);
} }
} }
/* Actually store the malloc pointer, finally. */ /* Actually store the malloc pointer, finally. */
*(((void **) retval) - 1) = ptr; *(((void **) retval) - 1) = ptr;
return retval; return retval;
} }
#endif #endif
@ -190,28 +190,51 @@ static unsigned char* dgibson_stbi_zlib_compress(
/* Image Read API */ /* Image Read API */
uint8_t* Refresh_Image_Load( uint8_t* Refresh_Image_Load(
char const *filename, char const *filename,
int32_t *w, int32_t *w,
int32_t *h, int32_t *h,
int32_t *numChannels int32_t *numChannels
) { ) {
return stbi_load(filename, w, h, numChannels, STBI_rgb_alpha); return stbi_load(filename, w, h, numChannels, STBI_rgb_alpha);
} }
void Refresh_Image_Free(uint8_t *mem) void Refresh_Image_Free(uint8_t *mem)
{ {
stbi_image_free(mem); stbi_image_free(mem);
} }
/* Image Write API */ /* Image Write API */
void Refresh_Image_SavePNG( void Refresh_Image_SavePNG(
const char *filename, const char *filename,
int32_t w, int32_t w,
int32_t h, int32_t h,
uint8_t bgra,
uint8_t *data uint8_t *data
) { ) {
stbi_write_png(filename, w, h, 4, data, w * 4); uint32_t i;
uint8_t *bgraData;
if (bgra)
{
bgraData = SDL_malloc(w * h * 4);
for (i = 0; i < w * h * 4; i += 4)
{
bgraData[i] = data[i + 2];
bgraData[i + 1] = data[i + 1];
bgraData[i + 2] = data[i];
bgraData[i + 3] = data[i + 3];
}
stbi_write_png(filename, w, h, 4, bgraData, w * 4);
SDL_free(bgraData);
}
else
{
stbi_write_png(filename, w, h, 4, data, w * 4);
}
} }
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */ /* vim: set noexpandtab shiftwidth=8 tabstop=8: */