Compare commits

...

63 Commits
nosrc1 ... main

Author SHA1 Message Date
cosmonaut b78d01592b memory system tweaks
continuous-integration/drone/push Build is passing Details
2024-02-11 15:56:53 -08:00
cosmonaut c99b4cdfa1 fix incorrect flag bit
continuous-integration/drone/push Build is passing Details
2024-01-31 14:47:01 -08:00
cosmonaut 2803e6d94e force ignore device-local property if allocation failed
continuous-integration/drone/push Build is passing Details
2024-01-31 14:36:02 -08:00
cosmonaut 30b5f1dd21 user-requested buffers are no longer host-visible
continuous-integration/drone/push Build is passing Details
2024-01-31 14:26:40 -08:00
cosmonaut 4ce2d80f80 Intel doesn't like 1 byte buffers
continuous-integration/drone/push Build is passing Details
2024-01-19 10:19:23 -08:00
cosmonaut 27e9c741f8 1.15.4
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-01-15 22:34:31 -08:00
cosmonaut c10ca98ccd Remove some unused variables
continuous-integration/drone/push Build is passing Details
2024-01-15 22:25:27 -08:00
cosmonaut d441424b7c Fix ANY_SHADER_READ_SAMPLED_IMAGE sync hazard
continuous-integration/drone/push Build is passing Details
2024-01-15 21:41:36 -08:00
cosmonaut 55c77def69 Revert "Fix potential sync hazards (#49)"
This reverts commit 20636ec951.
2024-01-15 21:38:37 -08:00
cosmonaut 2634359b48 Texture size calculation fixes
continuous-integration/drone/push Build is passing Details
2024-01-15 16:36:56 -08:00
cosmonaut 56e3eb2af5 1.15.3
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-01-15 12:47:49 -08:00
cosmonaut 859fc3b9fa fix UBO buffer size
continuous-integration/drone/push Build is passing Details
2024-01-13 23:45:07 -08:00
cosmonaut 05350a9332 UBO offsets should respect alignment
continuous-integration/drone/push Build is passing Details
2024-01-13 23:39:58 -08:00
cosmonaut 760c29699f 1.15.2
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-01-12 18:10:11 -08:00
cosmonaut 20636ec951 Fix potential sync hazards (#49)
We now do certain image layout transitions in the render pass instead of a barrier in EndRenderPass.

There is also an additional barrier on buffer uploads to prevent write-after-write hazard. It's a kludge on the fact that we're only tracking the most recent resource access.

Reviewed-on: MoonsideGames/Refresh#49
2024-01-12 18:10:11 -08:00
cosmonaut 7297eba889 Uniform buffers are now slices of dedicated allocs (#48)
continuous-integration/drone/push Build is passing Details
This should fix an issue where draw calls could flicker if a defrag was in progress and a uniform buffer was being used.

Uniform buffer "pools" are now just a single dedicated VulkanBuffer, and the uniform buffer objects are offsets into that buffer.

Reviewed-on: MoonsideGames/Refresh#48
2024-01-13 01:41:12 +00:00
cosmonaut b72b0b5fde fix path quotes in shadercompiler
continuous-integration/drone/push Build is passing Details
2024-01-11 16:26:08 -08:00
cosmonaut fa92e9e08a change dummy uniform buffer size to 1
continuous-integration/drone/push Build is passing Details
2023-12-08 12:49:46 -08:00
cosmonaut 483c07f3a8 Vulkan: fix dummy UBOs becoming invalid after defrag
continuous-integration/drone/push Build is passing Details
2023-12-05 12:22:40 -08:00
cosmonaut f01d5d817a Vulkan: fix some missed cleanup in DestroyDevice
continuous-integration/drone/push Build is passing Details
2023-12-04 17:28:25 -08:00
cosmonaut 17aae46eae revert OSX deployment target to 10.9
continuous-integration/drone/push Build is passing Details
2023-12-04 16:37:22 -08:00
cosmonaut 1b3e954da8 change render pass barriers to read-write
continuous-integration/drone/push Build is passing Details
2023-11-09 11:00:19 -08:00
Evan Hemsley 0989e45f88 MoltenVK support
continuous-integration/drone/push Build is passing Details
2023-10-14 22:14:00 -07:00
Evan Hemsley 6e6fec5224 bump OSX version to 10.15
continuous-integration/drone/push Build is passing Details
2023-10-14 20:46:22 -07:00
cosmonaut 34b2e437de 1.15.1
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-10-12 11:18:37 -07:00
cosmonaut d69bbbe818 fix Vulkan SDK include on Windows
continuous-integration/drone/push Build is passing Details
2023-10-12 11:11:44 -07:00
cosmonaut 54a8ff122c Fix uniform buffers not tracking correctly 2023-10-12 11:11:27 -07:00
TheSpydog a15e26b124 Update Driver Template + Window Crash Fix (#46)
continuous-integration/drone/push Build is passing Details
Some minor stuff that's cropped up from the D3D11 work so far. This PR updates the Driver_Template with the latest API, and also fixes a crash in the Vulkan driver -- if you acquired a swapchain texture from a window that had been destroyed, there was no null check before de-referencing the WindowData.

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Reviewed-on: MoonsideGames/Refresh#46
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2023-09-30 17:50:48 +00:00
cosmonaut 172fa83417 1.15.0
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-09-18 23:12:01 -07:00
cosmonaut a3949528eb Fence API (#45)
continuous-integration/drone/push Build is passing Details
Reviewed-on: MoonsideGames/Refresh#45
2023-09-19 06:11:20 +00:00
cosmonaut f55968814f 1.14.1
continuous-integration/drone/tag Build is passing Details
continuous-integration/drone/push Build is passing Details
2023-07-31 16:14:53 -07:00
cosmonaut c978df6275 remove unused variables
continuous-integration/drone/push Build is passing Details
2023-07-31 16:12:20 -07:00
cosmonaut de42163673 rework Vulkan device selection and initialization
continuous-integration/drone/push Build is passing Details
2023-07-31 16:06:47 -07:00
cosmonaut 4f412b5c15 fix refreshc breaking on file paths with spaces
continuous-integration/drone/push Build is passing Details
2023-07-03 15:35:11 -07:00
cosmonaut c3a5d9f417 enable independentBlend feature
continuous-integration/drone/push Build is passing Details
2023-06-16 15:00:47 -07:00
cosmonaut 9631dc9f83 1.14.0
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-06-07 14:13:21 -07:00
cosmonaut 5a2b07097a SetTextureDataYUV rework (#44)
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: MoonsideGames/Refresh#44
2023-06-07 20:59:55 +00:00
cosmonaut 1f9f7e0939 Memory Management Rewrite (#41)
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
continuous-integration/drone Build is passing Details
Various changes to reduce and optimize memory usage.

- Defragmenter
- Allocate 4 16MB transfer buffers for pool
- If transfer is larger than 16MB, create temporary transfer buffer
- Fixed some issues with CopyTextureToTexture

Reviewed-on: MoonsideGames/Refresh#41
2023-05-18 23:43:11 +00:00
cosmonaut 4df0459b04 1.13.0
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-04-18 23:43:59 -07:00
cosmonaut 0f29bf03e9 Remove qoi.h
continuous-integration/drone/push Build is passing Details
2023-04-18 23:43:23 -07:00
cosmonaut 74909b49c3 Redesign image API to be format agnostic (#40)
continuous-integration/drone/push Build is passing Details
2023-04-19 06:42:44 +00:00
cosmonaut 3f5fe1ff67 1.12.0
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-04-03 17:15:14 -07:00
cosmonaut 3fc743ce28 Add support for QOI format and reading images from memory (#39)
continuous-integration/drone/push Build is passing Details
Reviewed-on: MoonsideGames/Refresh#39
2023-04-04 00:14:20 +00:00
cosmonaut 153c3c3c60 add missing texture formats to size function
continuous-integration/drone/push Build is passing Details
2023-02-27 09:54:26 -08:00
cosmonaut decddae384 Fix MultipleThreads error on command buffer reset
continuous-integration/drone/push Build is passing Details
2023-02-14 12:26:39 -08:00
cosmonaut 2d66ec775b 1.11.0
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-02-07 12:26:46 -08:00
cosmonaut 8be8ce1062 shader output name includes shader type
continuous-integration/drone/push Build is passing Details
2023-02-03 15:06:14 -08:00
cosmonaut 8eebd9c744 refreshc publish AOT 2023-02-03 15:05:53 -08:00
TheSpydog 1f2aaeed9f add msaa support for depth textures (#38)
continuous-integration/drone/push Build is passing Details
Depth textures handle MSAA differently than color textures do, because there's no need for a resolve texture. This means the root VulkanTexture can have the sample count instead of needing an additional `msaaTex`.

This changeset also fixes a bug where the depth buffer wasn't getting cleared if there were MSAA color attachments.

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Reviewed-on: MoonsideGames/Refresh#38
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2023-01-31 20:30:05 +00:00
TheSpydog 6439516835 ABI break: Textures now have a sample count, not render passes (#37)
continuous-integration/drone/push Build is passing Details
This change makes Refresh behave more like FNA and other rendering APIs, where user-side textures have a sample count instead of generating MSAA RTs on the fly.

This should theoretically reduce memory consumption since subresource views no longer generate their own MSAA textures. Instead, each texture with a sample count > 1 now has a reference to an MSAA texture baked into the root texture itself, so views can just reference that.

This also simplifies VulkanRenderTarget significantly, to the point where it's just a wrapper around VkImageView. We could probably remove the abstraction entirely at this point.

Since VkRenderPass objects still require knowing the sample count, we can use the first bound texture's sample count. This means users only have to specify sample count in two places -- the graphics pipeline, and the texture. Easy enough.

I also noticed and fixed a bug with clear values with MSAA levels > 1.

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Reviewed-on: MoonsideGames/Refresh#37
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2023-01-30 18:22:16 +00:00
TheSpydog 89ba9c52ff vulkan: Fix framebuffer creation with mip levels (#36)
continuous-integration/drone/push Build is passing Details
Before this change, framebuffers were created based on the attachments' full dimensions, instead of the dimensions of the requested mip level. This fixes validation errors in the RenderTextureMipmaps test program.

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Reviewed-on: MoonsideGames/Refresh#36
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2023-01-24 00:15:02 +00:00
TheSpydog e3ab5fadf8 vulkan: Fix 3D texture creation (#35)
continuous-integration/drone/push Build is passing Details
The image type getting passed to imageCreateInfo was always VK_IMAGE_TYPE_2D, even for 3D textures. This fixes that bug, allowing Vulkan to successfully create 3D textures.

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Reviewed-on: MoonsideGames/Refresh#35
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2023-01-24 00:13:23 +00:00
TheSpydog 05900bee14 Shader cross-compiler (#34)
continuous-integration/drone/push Build is passing Details
This PR adds a shader cross-compiler program (written in C#) that uses glslc and spirv-cross to compile GLSL source files to a custom, Refresh-specific shader blob format that contains shader code for various backends.

The goal is that whenever you want to compile your shaders, you just run this program (either via `refreshc` or `dotnet run`), passing in the path to the GLSL source file. You can specify which backends you want to support via flags (`--vulkan`, for instance), and it will generate a .refresh blob file for Refresh to consume.

This can also be extended via C# defines and the `partial class` system. An example is the PS5 shader implementation, whose logic is squirreled away in the NDA'd repository but can be called in sequence with the rest of the shader cross-compile logic. This way, we don't have to run two separate programs to compile our shaders to all supported platforms.

Refresh handles all the parsing of the file format in Refresh_CreateShaderModule, so individual backends do not need to concern themselves with the particulars.

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Reviewed-on: MoonsideGames/Refresh#34
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2023-01-20 23:19:12 +00:00
TheSpydog f7250ab12a Remove fixed command buffers + minor cleanup (#33)
continuous-integration/drone/push Build is passing Details
Removes the `fixed` parameter from AcquireCommandBuffer, and removes a couple other unused bools from the VulkanCommandBuffer struct.

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Reviewed-on: MoonsideGames/Refresh#33
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2023-01-14 18:03:58 +00:00
cosmonaut 903192cb4c Descriptor validation fix (#32)
continuous-integration/drone/push Build is passing Details
The validator layer was complaining about us updating bound descriptor sets, this is technically a bug in the validator layer but resetting the command buffer in Cleanup makes more sense anyway. Also changed the wait for timeout call to a fence status query to make it easier to understand.

Reviewed-on: MoonsideGames/Refresh#32
2023-01-11 02:41:30 +00:00
cosmonaut 4cdd6a497a Fix transfer buffer alignment (#31)
continuous-integration/drone/push Build is passing Details
Reviewed-on: MoonsideGames/Refresh#31
2023-01-07 05:24:58 +00:00
cosmonaut 28b4253fdf 1.10.0
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-01-04 11:18:37 -08:00
TheSpydog e4215efe5e Enable multiDrawIndirect feature, add indirect command struct (#30)
continuous-integration/drone/push Build is passing Details
Fixes a validation error when attempting to draw multiple primitives via an indirect draw call. Adds some documentation for how indirect draw buffers should be set up.

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Reviewed-on: MoonsideGames/Refresh#30
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2023-01-04 18:44:02 +00:00
Caleb Cornett 329ffab6b8 Remove SRC1 blend factors and depthClampEnable flag
continuous-integration/drone/push Build is passing Details
2022-12-28 19:10:59 -08:00
Caleb Cornett 15b35fccfe update documentation + remove validation + misc cleanup
continuous-integration/drone/push Build is passing Details
2022-12-28 19:08:08 -08:00
TheSpydog ade74d73fe Perform pending destroys before unlocking the submit mutex (#28)
continuous-integration/drone/push Build is passing Details
This makes the order of VULKAN_Submit consistent with VULKAN_Wait.

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
Reviewed-on: MoonsideGames/Refresh#28
Co-authored-by: TheSpydog <thespydog@noreply.example.org>
Co-committed-by: TheSpydog <thespydog@noreply.example.org>
2022-12-29 03:03:35 +00:00
cosmonaut 124f202d2c Same-access-type barrier should not be a no-op
continuous-integration/drone/push Build is passing Details
2022-12-27 20:51:09 -08:00
cosmonaut 528abfad76 fix render target destroy segfault
continuous-integration/drone/push Build is passing Details
2022-12-22 17:23:11 -08:00
12 changed files with 3554 additions and 1684 deletions

View File

@ -8,8 +8,8 @@ option(BUILD_SHARED_LIBS "Build shared library" ON)
# Version # Version
SET(LIB_MAJOR_VERSION "1") SET(LIB_MAJOR_VERSION "1")
SET(LIB_MINOR_VERSION "9") SET(LIB_MINOR_VERSION "15")
SET(LIB_REVISION "0") SET(LIB_REVISION "4")
SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_REVISION}") SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_REVISION}")
# Build Type # Build Type
@ -60,6 +60,11 @@ if(NOT MSVC)
set_property(TARGET Refresh PROPERTY COMPILE_FLAGS "-std=gnu99 -Wall -Wno-strict-aliasing -pedantic") set_property(TARGET Refresh PROPERTY COMPILE_FLAGS "-std=gnu99 -Wall -Wno-strict-aliasing -pedantic")
endif() endif()
# Windows is silly and we need to manually include the Vulkan SDK
if(MSVC)
target_include_directories(Refresh PUBLIC $ENV{VULKAN_SDK}/include)
endif()
# Refresh folders as includes, for other targets to consume # Refresh folders as includes, for other targets to consume
target_include_directories(Refresh PUBLIC target_include_directories(Refresh PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>

View File

@ -55,8 +55,8 @@ extern "C" {
/* Version API */ /* Version API */
#define REFRESH_MAJOR_VERSION 1 #define REFRESH_MAJOR_VERSION 1
#define REFRESH_MINOR_VERSION 9 #define REFRESH_MINOR_VERSION 15
#define REFRESH_PATCH_VERSION 0 #define REFRESH_PATCH_VERSION 4
#define REFRESH_COMPILED_VERSION ( \ #define REFRESH_COMPILED_VERSION ( \
(REFRESH_MAJOR_VERSION * 100 * 100) + \ (REFRESH_MAJOR_VERSION * 100 * 100) + \
@ -76,6 +76,7 @@ typedef struct Refresh_ShaderModule Refresh_ShaderModule;
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;
typedef struct Refresh_Fence Refresh_Fence;
typedef enum Refresh_PresentMode typedef enum Refresh_PresentMode
{ {
@ -281,11 +282,7 @@ typedef enum Refresh_BlendFactor
REFRESH_BLENDFACTOR_ONE_MINUS_DST_ALPHA, REFRESH_BLENDFACTOR_ONE_MINUS_DST_ALPHA,
REFRESH_BLENDFACTOR_CONSTANT_COLOR, REFRESH_BLENDFACTOR_CONSTANT_COLOR,
REFRESH_BLENDFACTOR_ONE_MINUS_CONSTANT_COLOR, REFRESH_BLENDFACTOR_ONE_MINUS_CONSTANT_COLOR,
REFRESH_BLENDFACTOR_SRC_ALPHA_SATURATE, REFRESH_BLENDFACTOR_SRC_ALPHA_SATURATE
REFRESH_BLENDFACTOR_SRC1_COLOR,
REFRESH_BLENDFACTOR_ONE_MINUS_SRC1_COLOR,
REFRESH_BLENDFACTOR_SRC1_ALPHA,
REFRESH_BLENDFACTOR_ONE_MINUS_SRC1_ALPHA
} Refresh_BlendFactor; } Refresh_BlendFactor;
typedef enum Refresh_ColorComponentFlagBits typedef enum Refresh_ColorComponentFlagBits
@ -380,6 +377,14 @@ typedef struct Refresh_TextureSlice
uint32_t level; uint32_t level;
} Refresh_TextureSlice; } Refresh_TextureSlice;
typedef struct Refresh_IndirectDrawCommand
{
uint32_t vertexCount;
uint32_t instanceCount;
uint32_t firstVertex;
uint32_t firstInstance;
} Refresh_IndirectDrawCommand;
/* State structures */ /* State structures */
typedef struct Refresh_SamplerStateCreateInfo typedef struct Refresh_SamplerStateCreateInfo
@ -446,12 +451,6 @@ typedef struct Refresh_ColorAttachmentBlendState
Refresh_ColorComponentFlags colorWriteMask; Refresh_ColorComponentFlags colorWriteMask;
} Refresh_ColorAttachmentBlendState; } Refresh_ColorAttachmentBlendState;
typedef struct Refresh_ComputePipelineLayoutCreateInfo
{
uint32_t bufferBindingCount;
uint32_t imageBindingCount;
} Refresh_ComputePipelineLayoutCreateInfo;
typedef struct Refresh_ShaderModuleCreateInfo typedef struct Refresh_ShaderModuleCreateInfo
{ {
size_t codeSize; size_t codeSize;
@ -465,6 +464,7 @@ typedef struct Refresh_TextureCreateInfo
uint32_t depth; uint32_t depth;
uint8_t isCube; uint8_t isCube;
uint32_t levelCount; uint32_t levelCount;
Refresh_SampleCount sampleCount;
Refresh_TextureFormat format; Refresh_TextureFormat format;
Refresh_TextureUsageFlags usageFlags; Refresh_TextureUsageFlags usageFlags;
} Refresh_TextureCreateInfo; } Refresh_TextureCreateInfo;
@ -490,7 +490,6 @@ typedef struct Refresh_ComputeShaderInfo
typedef struct Refresh_RasterizerState typedef struct Refresh_RasterizerState
{ {
uint8_t depthClampEnable;
Refresh_FillMode fillMode; Refresh_FillMode fillMode;
Refresh_CullMode cullMode; Refresh_CullMode cullMode;
Refresh_FrontFace frontFace; Refresh_FrontFace frontFace;
@ -554,7 +553,6 @@ typedef struct Refresh_ColorAttachmentInfo
uint32_t depth; uint32_t depth;
uint32_t layer; uint32_t layer;
uint32_t level; uint32_t level;
Refresh_SampleCount sampleCount;
Refresh_Vec4 clearColor; /* Can be ignored by RenderPass */ Refresh_Vec4 clearColor; /* Can be ignored by RenderPass */
Refresh_LoadOp loadOp; Refresh_LoadOp loadOp;
Refresh_StoreOp storeOp; Refresh_StoreOp storeOp;
@ -677,6 +675,7 @@ REFRESHAPI void Refresh_DrawPrimitives(
); );
/* Similar to Refresh_DrawPrimitives, but draw parameters are set from a buffer. /* Similar to Refresh_DrawPrimitives, but draw parameters are set from a buffer.
* The buffer layout should match the layout of Refresh_IndirectDrawCommand.
* *
* buffer: A buffer containing draw parameters. * buffer: A buffer containing draw parameters.
* offsetInBytes: The offset to start reading from the draw buffer. * offsetInBytes: The offset to start reading from the draw buffer.
@ -760,6 +759,11 @@ REFRESHAPI Refresh_Buffer* Refresh_CreateBuffer(
/* Setters */ /* Setters */
/* Uploads image data to a texture object. /* Uploads image data to a texture object.
*
* NOTE:
* DO NOT expect this to execute in sequence relative to other commands!
* Calling SetTextureData in a command buffer that also references the
* texture may result in undefined behavior.
* *
* textureSlice: The texture slice to be updated. * textureSlice: The texture slice to be updated.
* data: A pointer to the image data. * data: A pointer to the image data.
@ -782,8 +786,13 @@ REFRESHAPI void Refresh_SetTextureData(
* yHeight: The height of the Y plane. * yHeight: The height of the Y plane.
* uvWidth: The width of the U/V planes. * uvWidth: The width of the U/V planes.
* uvHeight: The height of the U/V planes. * uvHeight: The height of the U/V planes.
* data: A pointer to the raw YUV image data. * yData: A pointer to the raw Y image data.
* dataLength: The size of the image data in bytes. * uData: A pointer to the raw U image data.
* vData: A pointer to the raw V image data.
* yDataLength: The size of the Y image data in bytes.
* uvDataLength: The size of the UV image data in bytes.
* yStride: The length of a Y image data row in bytes.
* uvStride: The length of a UV image data row in bytes.
*/ */
REFRESHAPI void Refresh_SetTextureDataYUV( REFRESHAPI void Refresh_SetTextureDataYUV(
Refresh_Device *driverData, Refresh_Device *driverData,
@ -795,8 +804,13 @@ REFRESHAPI void Refresh_SetTextureDataYUV(
uint32_t yHeight, uint32_t yHeight,
uint32_t uvWidth, uint32_t uvWidth,
uint32_t uvHeight, uint32_t uvHeight,
void* data, void *yDataPtr,
uint32_t dataLength void *uDataPtr,
void *vDataPtr,
uint32_t yDataLength,
uint32_t uvDataLength,
uint32_t yStride,
uint32_t uvStride
); );
/* Performs an asynchronous texture-to-texture copy. /* Performs an asynchronous texture-to-texture copy.
@ -1036,7 +1050,9 @@ REFRESHAPI void Refresh_SetScissor(
Refresh_Rect *scissor Refresh_Rect *scissor
); );
/* Binds vertex buffers for use with subsequent draw calls. */ /* Binds vertex buffers for use with subsequent draw calls.
* Note that this may only be called after binding a graphics pipeline.
*/
REFRESHAPI void Refresh_BindVertexBuffers( REFRESHAPI void Refresh_BindVertexBuffers(
Refresh_Device *device, Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
@ -1163,15 +1179,9 @@ REFRESHAPI Refresh_TextureFormat Refresh_GetSwapchainFormat(
* A command buffer may only be used on the thread that * A command buffer may only be used on the thread that
* it was acquired on. Using it on any other thread is an error. * it was acquired on. Using it on any other thread is an error.
* *
* fixed:
* If a command buffer is designated as fixed, it can be
* acquired once, have commands recorded into it, and
* be re-submitted indefinitely.
*
*/ */
REFRESHAPI Refresh_CommandBuffer* Refresh_AcquireCommandBuffer( REFRESHAPI Refresh_CommandBuffer* Refresh_AcquireCommandBuffer(
Refresh_Device *device, Refresh_Device *device
uint8_t fixed
); );
/* Acquires a texture to use for presentation. /* Acquires a texture to use for presentation.
@ -1197,15 +1207,50 @@ REFRESHAPI Refresh_Texture* Refresh_AcquireSwapchainTexture(
/* Submits all of the enqueued commands. */ /* Submits all of the enqueued commands. */
REFRESHAPI void Refresh_Submit( REFRESHAPI void Refresh_Submit(
Refresh_Device* device, Refresh_Device* device,
uint32_t commandBufferCount, Refresh_CommandBuffer *commandBuffer
Refresh_CommandBuffer **pCommandBuffers
); );
/* Waits for all submissions to complete. */ /* Submits a command buffer and acquires a fence.
* You can use the fence to check if or wait until the command buffer has finished processing.
* You are responsible for releasing this fence when you are done using it.
*/
REFRESHAPI Refresh_Fence* Refresh_SubmitAndAcquireFence(
Refresh_Device* device,
Refresh_CommandBuffer *commandBuffer
);
/* Waits for the device to become idle. */
REFRESHAPI void Refresh_Wait( REFRESHAPI void Refresh_Wait(
Refresh_Device *device Refresh_Device *device
); );
/* Waits for given fences to be signaled.
*
* waitAll: If 0, waits for any fence to be signaled. If 1, waits for all fences to be signaled.
* fenceCount: The number of fences being submitted.
* pFences: An array of fences to be waited on.
*/
REFRESHAPI void Refresh_WaitForFences(
Refresh_Device *device,
uint8_t waitAll,
uint32_t fenceCount,
Refresh_Fence **pFences
);
/* Check the status of a fence. 1 means the fence is signaled. */
REFRESHAPI int Refresh_QueryFence(
Refresh_Device *device,
Refresh_Fence *fence
);
/* Allows the fence to be reused by future command buffer submissions.
* If you do not release fences after acquiring them, you will cause unbounded resource growth.
*/
REFRESHAPI void Refresh_ReleaseFence(
Refresh_Device *device,
Refresh_Fence *fence
);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -44,44 +44,45 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/* Decodes PNG data into raw RGBA8 texture data. /* Image Read API */
/* Decodes image data into raw RGBA8 texture data.
* *
* w: Filled with the width of the image. * w: Filled with the width of the image.
* h: Filled with the height of the image. * h: Filled with the height of the image.
* numChannels: Filled with the number of channels in the image. * len: Filled with the length of pixel data in bytes.
* *
* Returns a block of memory suitable for use with Refresh_SetTextureData2D. * Returns a block of memory suitable for use with Refresh_SetTextureData2D.
* 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, uint8_t *bufferPtr,
int32_t bufferLength,
int32_t *w, int32_t *w,
int32_t *h, int32_t *h,
int32_t *numChannels int32_t *len
); );
/* 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!
* *
* mem: A pointer previously returned by Refresh_Image_Load. * mem: A pointer previously returned by Refresh_Image_LoadPNG.
*/ */
REFRESHAPI void Refresh_Image_Free(uint8_t *mem); REFRESHAPI void Refresh_Image_Free(uint8_t *mem);
/* Image Write API */ /* Image Write API */
/* Encodes 32-bit color data into PNG data. /* Returns a buffer of PNG encoded from RGBA8 color data.
* *
* filename: The filename that the image will be written to.
* w: The width of the PNG data.
* h: The height of the PNG data.
* bgra: Whether the data is in BGRA8 format. Otherwise will assume RBGA8.
* data: The raw color data. * data: The raw color data.
* w: The width of the color data.
* h: The height of the color data.
* len: Filled with the length of PNG data in bytes.
*/ */
REFRESHAPI void Refresh_Image_SavePNG( REFRESHAPI void Refresh_Image_SavePNG(
char const *filename, const char* filename,
uint8_t* data,
int32_t w, int32_t w,
int32_t h, int32_t h
uint8_t bgra,
uint8_t *data
); );
#ifdef __cplusplus #ifdef __cplusplus

268
shadercompiler/Program.cs Normal file
View File

@ -0,0 +1,268 @@
using System;
using System.IO;
using System.Diagnostics;
partial class Program
{
struct CompileShaderData
{
public string glslPath;
public string outputDir;
public bool preserveTemp;
public bool vulkan;
public bool d3d11;
public bool ps5;
}
private static void DisplayHelpText()
{
Console.WriteLine("Usage: refreshc <path-to-glsl-source | directory-with-glsl-source-files>");
Console.WriteLine("Options:");
Console.WriteLine(" --vulkan Emit shader compatible with the Refresh Vulkan backend");
Console.WriteLine(" --d3d11 Emit shader compatible with the Refresh D3D11 backend");
Console.WriteLine(" --ps5 Emit shader compatible with the Refresh PS5 backend");
Console.WriteLine(" --out dir Write output file(s) to the directory `dir`");
Console.WriteLine(" --preserve-temp Do not delete the temp directory after compilation. Useful for debugging.");
}
public static int Main(string[] args)
{
if (args.Length == 0)
{
DisplayHelpText();
return 1;
}
CompileShaderData data = new CompileShaderData();
string inputPath = null;
for (int i = 0; i < args.Length; i += 1)
{
switch (args[i])
{
case "--vulkan":
data.vulkan = true;
break;
case "--d3d11":
data.d3d11 = true;
break;
case "--ps5":
data.ps5 = true;
break;
case "--out":
i += 1;
data.outputDir = args[i];
break;
case "--preserve-temp":
data.preserveTemp = true;
break;
default:
if (inputPath == null)
{
inputPath = args[i];
}
else
{
Console.WriteLine($"refreshc: Unknown parameter {args[i]}");
return 1;
}
break;
}
}
if (!data.vulkan && !data.d3d11 && !data.ps5)
{
Console.WriteLine($"refreshc: No Refresh platforms selected!");
return 1;
}
#if !PS5
if (data.ps5)
{
Console.WriteLine($"refreshc: `PS5` must be defined in the to target the PS5 backend!");
return 1;
}
#endif
if (data.outputDir == null)
{
data.outputDir = Directory.GetCurrentDirectory();
}
else if (!Directory.Exists(data.outputDir))
{
Console.WriteLine($"refreshc: Output directory {data.outputDir} does not exist");
return 1;
}
if (Directory.Exists(inputPath))
{
// Loop over and compile each file in the directory
string[] files = Directory.GetFiles(inputPath);
foreach (string file in files)
{
Console.WriteLine($"Compiling {file}");
data.glslPath = file;
int res = CompileShader(ref data);
if (res != 0)
{
return res;
}
}
}
else
{
if (!File.Exists(inputPath))
{
Console.WriteLine($"refreshc: glsl source file or directory ({inputPath}) does not exist");
return 1;
}
data.glslPath = inputPath;
int res = CompileShader(ref data);
if (res != 0)
{
return res;
}
}
return 0;
}
static int CompileShader(ref CompileShaderData data)
{
int res = 0;
string shaderName = Path.GetFileNameWithoutExtension(data.glslPath);
string shaderType = Path.GetExtension(data.glslPath);
if (shaderType != ".vert" && shaderType != ".frag" && shaderType != ".comp")
{
Console.WriteLine("refreshc: Expected glsl source file with extension '.vert', '.frag', or '.comp'");
return 1;
}
// Create the temp directory, if needed
string tempDir = Path.Combine(Directory.GetCurrentDirectory(), "temp");
if (!Directory.Exists(tempDir))
{
Directory.CreateDirectory(tempDir);
}
// Compile to spirv
string spirvPath = Path.Combine(tempDir, $"{shaderName}.spv");
res = CompileGlslToSpirv(data.glslPath, shaderName, spirvPath);
if (res != 0)
{
goto cleanup;
}
if (data.d3d11 || data.ps5)
{
// Transpile to hlsl
string hlslPath = Path.Combine(tempDir, $"{shaderName}.hlsl");
res = TranslateSpirvToHlsl(spirvPath, hlslPath);
if (res != 0)
{
goto cleanup;
}
// FIXME: Is there a cross-platform way to compile HLSL to DXBC?
#if PS5
// Transpile to ps5, if requested
if (data.ps5)
{
res = TranslateHlslToPS5(hlslPath, shaderName, shaderType, tempDir);
if (res != 0)
{
goto cleanup;
}
}
#endif
}
// Create the output blob file
string outputFilepath = Path.Combine(data.outputDir, $"{shaderName}{shaderType}.refresh");
using (FileStream fs = File.Create(outputFilepath))
{
using (BinaryWriter writer = new BinaryWriter(fs))
{
// Magic
writer.Write(new char[] { 'R', 'F', 'S', 'H'});
if (data.vulkan)
{
string inputPath = Path.Combine(tempDir, $"{shaderName}.spv");
WriteShaderBlob(writer, inputPath, 1);
}
#if PS5
if (data.ps5)
{
string ext = GetPS5ShaderFileExtension();
string inputPath = Path.Combine(tempDir, $"{shaderName}{ext}");
WriteShaderBlob(writer, inputPath, 2);
}
#endif
if (data.d3d11)
{
string inputPath = Path.Combine(tempDir, $"{shaderName}.hlsl");
WriteShaderBlob(writer, inputPath, 3);
}
}
}
cleanup:
// Clean up the temp directory
if (!data.preserveTemp)
{
Directory.Delete(tempDir, true);
}
return res;
}
static void WriteShaderBlob(BinaryWriter writer, string inputPath, byte backend)
{
byte[] shaderBlob = File.ReadAllBytes(inputPath);
writer.Write(backend); // Corresponds to Refresh_Backend
writer.Write(shaderBlob.Length);
writer.Write(shaderBlob);
}
static int CompileGlslToSpirv(string glslPath, string shaderName, string outputPath)
{
Process glslc = Process.Start(
"glslc",
$"\"{glslPath}\" -o \"{outputPath}\""
);
glslc.WaitForExit();
if (glslc.ExitCode != 0)
{
Console.WriteLine($"refreshc: Could not compile GLSL code");
return 1;
}
return 0;
}
static int TranslateSpirvToHlsl(string spirvPath, string outputPath)
{
Process spirvcross = Process.Start(
"spirv-cross",
$"\"{spirvPath}\" --hlsl --shader-model 50 --output \"{outputPath}\""
);
spirvcross.WaitForExit();
if (spirvcross.ExitCode != 0)
{
Console.WriteLine($"refreshc: Could not translate SPIR-V to HLSL");
return 1;
}
return 0;
}
}

View File

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetName>refreshc</TargetName>
<PublishAot>true</PublishAot>
</PropertyGroup>
</Project>

View File

@ -338,10 +338,52 @@ Refresh_ShaderModule* Refresh_CreateShaderModule(
Refresh_Device *device, Refresh_Device *device,
Refresh_ShaderModuleCreateInfo *shaderModuleCreateInfo Refresh_ShaderModuleCreateInfo *shaderModuleCreateInfo
) { ) {
Refresh_ShaderModuleCreateInfo driverSpecificCreateInfo = { 0, NULL };
uint8_t *bytes;
uint32_t i, size;
NULL_RETURN_NULL(device); NULL_RETURN_NULL(device);
/* verify the magic number in the shader blob header */
bytes = (uint8_t*) shaderModuleCreateInfo->byteCode;
if (bytes[0] != 'R' || bytes[1] != 'F' || bytes[2] != 'S' || bytes[3] != 'H')
{
Refresh_LogError("Cannot parse malformed Refresh shader blob!");
return NULL;
}
/* find the code for the selected backend */
i = 4;
while (i < shaderModuleCreateInfo->codeSize)
{
size = *((uint32_t*) &bytes[i + 1]);
if (bytes[i] == (uint8_t) selectedBackend)
{
driverSpecificCreateInfo.codeSize = size;
driverSpecificCreateInfo.byteCode = (uint32_t*) &bytes[i + 1 + sizeof(uint32_t)];
break;
}
else
{
/* skip over the backend byte, the blob size, and the blob */
i += 1 + sizeof(uint32_t) + size;
}
}
/* verify the shader blob supports the selected backend */
if (driverSpecificCreateInfo.byteCode == NULL)
{
Refresh_LogError(
"Cannot create shader module that does not contain shader code for the selected backend! "
"Recompile your shader and enable this backend."
);
return NULL;
}
return device->CreateShaderModule( return device->CreateShaderModule(
device->driverData, device->driverData,
shaderModuleCreateInfo &driverSpecificCreateInfo
); );
} }
@ -396,8 +438,13 @@ void Refresh_SetTextureDataYUV(
uint32_t yHeight, uint32_t yHeight,
uint32_t uvWidth, uint32_t uvWidth,
uint32_t uvHeight, uint32_t uvHeight,
void* data, void *yDataPtr,
uint32_t dataLength void *uDataPtr,
void *vDataPtr,
uint32_t yDataLength,
uint32_t uvDataLength,
uint32_t yStride,
uint32_t uvStride
) { ) {
NULL_RETURN(device); NULL_RETURN(device);
device->SetTextureDataYUV( device->SetTextureDataYUV(
@ -410,8 +457,13 @@ void Refresh_SetTextureDataYUV(
yHeight, yHeight,
uvWidth, uvWidth,
uvHeight, uvHeight,
data, yDataPtr,
dataLength uDataPtr,
vDataPtr,
yDataLength,
uvDataLength,
yStride,
uvStride
); );
} }
@ -789,13 +841,11 @@ void Refresh_UnclaimWindow(
} }
Refresh_CommandBuffer* Refresh_AcquireCommandBuffer( Refresh_CommandBuffer* Refresh_AcquireCommandBuffer(
Refresh_Device *device, Refresh_Device *device
uint8_t fixed
) { ) {
NULL_RETURN_NULL(device); NULL_RETURN_NULL(device);
return device->AcquireCommandBuffer( return device->AcquireCommandBuffer(
device->driverData, device->driverData
fixed
); );
} }
@ -842,14 +892,23 @@ void Refresh_SetSwapchainPresentMode(
void Refresh_Submit( void Refresh_Submit(
Refresh_Device *device, Refresh_Device *device,
uint32_t commandBufferCount, Refresh_CommandBuffer *commandBuffer
Refresh_CommandBuffer **pCommandBuffers
) { ) {
NULL_RETURN(device); NULL_RETURN(device);
device->Submit( device->Submit(
device->driverData, device->driverData,
commandBufferCount, commandBuffer
pCommandBuffers );
}
Refresh_Fence* Refresh_SubmitAndAcquireFence(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer
) {
NULL_RETURN_NULL(device);
return device->SubmitAndAcquireFence(
device->driverData,
commandBuffer
); );
} }
@ -862,4 +921,44 @@ void Refresh_Wait(
); );
} }
void Refresh_WaitForFences(
Refresh_Device *device,
uint8_t waitAll,
uint32_t fenceCount,
Refresh_Fence **pFences
) {
NULL_RETURN(device);
device->WaitForFences(
device->driverData,
waitAll,
fenceCount,
pFences
);
}
int Refresh_QueryFence(
Refresh_Device *device,
Refresh_Fence *fence
) {
if (device == NULL) {
return 0;
}
return device->QueryFence(
device->driverData,
fence
);
}
void Refresh_ReleaseFence(
Refresh_Device *device,
Refresh_Fence *fence
) {
NULL_RETURN(device);
device->ReleaseFence(
device->driverData,
fence
);
}
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */ /* vim: set noexpandtab shiftwidth=8 tabstop=8: */

View File

@ -268,7 +268,7 @@ struct Refresh_Device
/* Setters */ /* Setters */
void(*SetTextureData)( void (*SetTextureData)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *textureSlice, Refresh_TextureSlice *textureSlice,
@ -276,7 +276,7 @@ struct Refresh_Device
uint32_t dataLengthInBytes uint32_t dataLengthInBytes
); );
void(*SetTextureDataYUV)( void (*SetTextureDataYUV)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer* commandBuffer, Refresh_CommandBuffer* commandBuffer,
Refresh_Texture *y, Refresh_Texture *y,
@ -286,11 +286,16 @@ struct Refresh_Device
uint32_t yHeight, uint32_t yHeight,
uint32_t uvWidth, uint32_t uvWidth,
uint32_t uvHeight, uint32_t uvHeight,
void* data, void *yDataPtr,
uint32_t dataLength void *uDataPtr,
void *vDataPtr,
uint32_t yDataLength,
uint32_t uvDataLength,
uint32_t yStride,
uint32_t uvStride
); );
void(*CopyTextureToTexture)( void (*CopyTextureToTexture)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *sourceTextureSlice, Refresh_TextureSlice *sourceTextureSlice,
@ -298,14 +303,14 @@ struct Refresh_Device
Refresh_Filter filter Refresh_Filter filter
); );
void(*CopyTextureToBuffer)( void (*CopyTextureToBuffer)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice *textureSlice, Refresh_TextureSlice *textureSlice,
Refresh_Buffer *buffer Refresh_Buffer *buffer
); );
void(*SetBufferData)( void (*SetBufferData)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Buffer *buffer, Refresh_Buffer *buffer,
@ -314,14 +319,14 @@ struct Refresh_Device
uint32_t dataLength uint32_t dataLength
); );
uint32_t(*PushVertexShaderUniforms)( uint32_t (*PushVertexShaderUniforms)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
void *data, void *data,
uint32_t dataLengthInBytes uint32_t dataLengthInBytes
); );
uint32_t(*PushFragmentShaderUniforms)( uint32_t (*PushFragmentShaderUniforms)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
void *data, void *data,
@ -335,14 +340,14 @@ struct Refresh_Device
uint32_t dataLengthInBytes uint32_t dataLengthInBytes
); );
void(*BindVertexSamplers)( void (*BindVertexSamplers)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures, Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers Refresh_Sampler **pSamplers
); );
void(*BindFragmentSamplers)( void (*BindFragmentSamplers)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures, Refresh_Texture **pTextures,
@ -351,7 +356,7 @@ struct Refresh_Device
/* Getters */ /* Getters */
void(*GetBufferData)( void (*GetBufferData)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_Buffer *buffer, Refresh_Buffer *buffer,
void *data, void *data,
@ -360,39 +365,39 @@ struct Refresh_Device
/* Disposal */ /* Disposal */
void(*QueueDestroyTexture)( void (*QueueDestroyTexture)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_Texture *texture Refresh_Texture *texture
); );
void(*QueueDestroySampler)( void (*QueueDestroySampler)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_Sampler *sampler Refresh_Sampler *sampler
); );
void(*QueueDestroyBuffer)( void (*QueueDestroyBuffer)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_Buffer *buffer Refresh_Buffer *buffer
); );
void(*QueueDestroyShaderModule)( void (*QueueDestroyShaderModule)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_ShaderModule *shaderModule Refresh_ShaderModule *shaderModule
); );
void(*QueueDestroyComputePipeline)( void (*QueueDestroyComputePipeline)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_ComputePipeline *computePipeline Refresh_ComputePipeline *computePipeline
); );
void(*QueueDestroyGraphicsPipeline)( void (*QueueDestroyGraphicsPipeline)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_GraphicsPipeline *graphicsPipeline Refresh_GraphicsPipeline *graphicsPipeline
); );
/* Graphics State */ /* Graphics State */
void(*BeginRenderPass)( void (*BeginRenderPass)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_ColorAttachmentInfo *colorAttachmentInfos, Refresh_ColorAttachmentInfo *colorAttachmentInfos,
@ -400,30 +405,30 @@ struct Refresh_Device
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
); );
void(*EndRenderPass)( void (*EndRenderPass)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer Refresh_CommandBuffer *commandBuffer
); );
void(*SetViewport)( void (*SetViewport)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Viewport *viewport Refresh_Viewport *viewport
); );
void(*SetScissor)( void (*SetScissor)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *scissor Refresh_Rect *scissor
); );
void(*BindGraphicsPipeline)( void (*BindGraphicsPipeline)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_GraphicsPipeline *graphicsPipeline Refresh_GraphicsPipeline *graphicsPipeline
); );
void(*BindVertexBuffers)( void (*BindVertexBuffers)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
uint32_t firstBinding, uint32_t firstBinding,
@ -432,7 +437,7 @@ struct Refresh_Device
uint64_t *pOffsets uint64_t *pOffsets
); );
void(*BindIndexBuffer)( void (*BindIndexBuffer)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Buffer *buffer, Refresh_Buffer *buffer,
@ -440,19 +445,19 @@ struct Refresh_Device
Refresh_IndexElementSize indexElementSize Refresh_IndexElementSize indexElementSize
); );
void(*BindComputePipeline)( void (*BindComputePipeline)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_ComputePipeline *computePipeline Refresh_ComputePipeline *computePipeline
); );
void(*BindComputeBuffers)( void (*BindComputeBuffers)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Buffer **pBuffers Refresh_Buffer **pBuffers
); );
void(*BindComputeTextures)( void (*BindComputeTextures)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures Refresh_Texture **pTextures
@ -464,14 +469,13 @@ struct Refresh_Device
Refresh_PresentMode presentMode Refresh_PresentMode presentMode
); );
void(*UnclaimWindow)( void (*UnclaimWindow)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
void *windowHandle void *windowHandle
); );
Refresh_CommandBuffer* (*AcquireCommandBuffer)( Refresh_CommandBuffer* (*AcquireCommandBuffer)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData
uint8_t fixed
); );
Refresh_Texture* (*AcquireSwapchainTexture)( Refresh_Texture* (*AcquireSwapchainTexture)(
@ -493,16 +497,37 @@ struct Refresh_Device
Refresh_PresentMode presentMode Refresh_PresentMode presentMode
); );
void(*Submit)( void (*Submit)(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
uint32_t commandBufferCount, Refresh_CommandBuffer *commandBuffer
Refresh_CommandBuffer **pCommandBuffers
); );
void(*Wait)( Refresh_Fence* (*SubmitAndAcquireFence)(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer
);
void (*Wait)(
Refresh_Renderer *driverData Refresh_Renderer *driverData
); );
void (*WaitForFences)(
Refresh_Renderer *driverData,
uint8_t waitAll,
uint32_t fenceCount,
Refresh_Fence **pFences
);
int (*QueryFence)(
Refresh_Renderer *driverData,
Refresh_Fence *fence
);
void (*ReleaseFence)(
Refresh_Renderer *driverData,
Refresh_Fence *fence
);
/* Opaque pointer for the Driver */ /* Opaque pointer for the Driver */
Refresh_Renderer *driverData; Refresh_Renderer *driverData;
}; };
@ -556,7 +581,11 @@ struct Refresh_Device
ASSIGN_DRIVER_FUNC(GetSwapchainFormat, name) \ ASSIGN_DRIVER_FUNC(GetSwapchainFormat, name) \
ASSIGN_DRIVER_FUNC(SetSwapchainPresentMode, name) \ ASSIGN_DRIVER_FUNC(SetSwapchainPresentMode, name) \
ASSIGN_DRIVER_FUNC(Submit, name) \ ASSIGN_DRIVER_FUNC(Submit, name) \
ASSIGN_DRIVER_FUNC(Wait, name) ASSIGN_DRIVER_FUNC(SubmitAndAcquireFence, name) \
ASSIGN_DRIVER_FUNC(Wait, name) \
ASSIGN_DRIVER_FUNC(WaitForFences, name) \
ASSIGN_DRIVER_FUNC(QueryFence, name) \
ASSIGN_DRIVER_FUNC(ReleaseFence, name)
typedef struct Refresh_Driver typedef struct Refresh_Driver
{ {

View File

@ -126,11 +126,7 @@ static TEMPLATE_BLEND_FACTOR_TYPE RefreshToTEMPLATE_BlendFactor[] =
0, /* ONE_MINUS_DST_ALPHA */ 0, /* ONE_MINUS_DST_ALPHA */
0, /* CONSTANT_COLOR */ 0, /* CONSTANT_COLOR */
0, /* ONE_MINUS_CONSTANT_COLOR */ 0, /* ONE_MINUS_CONSTANT_COLOR */
0, /* SRC_ALPHA_SATURATE */ 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[] = static TEMPLATE_BLEND_OP_TYPE RefreshToTEMPLATE_BlendOp[] =
@ -272,6 +268,19 @@ static void TEMPLATE_DrawPrimitives(
NOT_IMPLEMENTED NOT_IMPLEMENTED
} }
static void TEMPLATE_DrawPrimitivesIndirect(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Buffer *buffer,
uint32_t offsetInBytes,
uint32_t drawCount,
uint32_t stride,
uint32_t vertexParamOffset,
uint32_t fragmentParamOffset
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_DispatchCompute( static void TEMPLATE_DispatchCompute(
Refresh_Renderer *device, Refresh_Renderer *device,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
@ -351,8 +360,13 @@ static void TEMPLATE_SetTextureDataYUV(
uint32_t yHeight, uint32_t yHeight,
uint32_t uvWidth, uint32_t uvWidth,
uint32_t uvHeight, uint32_t uvHeight,
void* data, void *yDataPtr,
uint32_t dataLength void *uDataPtr,
void *vDataPtr,
uint32_t yDataLength,
uint32_t uvDataLength,
uint32_t yStride,
uint32_t uvStride
) { ) {
NOT_IMPLEMENTED NOT_IMPLEMENTED
} }
@ -489,10 +503,15 @@ static void TEMPLATE_QueueDestroyGraphicsPipeline(
/* Graphics State */ /* Graphics State */
static Refresh_CommandBuffer* TEMPLATE_AcquireCommandBuffer(
Refresh_Renderer *driverData
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_BeginRenderPass( static void TEMPLATE_BeginRenderPass(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Rect *renderArea,
Refresh_ColorAttachmentInfo *colorAttachmentInfos, Refresh_ColorAttachmentInfo *colorAttachmentInfos,
uint32_t colorAttachmentCount, uint32_t colorAttachmentCount,
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
@ -552,6 +571,8 @@ static void TEMPLATE_BindIndexBuffer(
NOT_IMPLEMENTED NOT_IMPLEMENTED
} }
/* Compute State */
static void TEMPLATE_BindComputePipeline( static void TEMPLATE_BindComputePipeline(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
@ -576,14 +597,24 @@ static void TEMPLATE_BindComputeTextures(
NOT_IMPLEMENTED NOT_IMPLEMENTED
} }
static Refresh_CommandBuffer* TEMPLATE_AcquireCommandBuffer( /* Window and Swapchain Management */
static uint8_t TEMPLATE_ClaimWindow(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
uint8_t fixed void *windowHandle,
Refresh_PresentMode presentMode
) { ) {
NOT_IMPLEMENTED NOT_IMPLEMENTED
} }
Refresh_Texture* TEMPLATE_AcquireSwapchainTexture( static void TEMPLATE_UnclaimWindow(
Refresh_Renderer *driverData,
void *windowHandle
) {
NOT_IMPLEMENTED
}
static Refresh_Texture* TEMPLATE_AcquireSwapchainTexture(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
void *windowHandle, void *windowHandle,
@ -593,17 +624,33 @@ Refresh_Texture* TEMPLATE_AcquireSwapchainTexture(
NOT_IMPLEMENTED NOT_IMPLEMENTED
} }
Refresh_TextureFormat TEMPLATE_GetSwapchainFormat( static Refresh_TextureFormat TEMPLATE_GetSwapchainFormat(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
void *windowHandle void *windowHandle
) { ) {
NOT_IMPLEMENTED NOT_IMPLEMENTED
} }
static void TEMPLATE_SetSwapchainPresentMode(
Refresh_Renderer *driverData,
void *windowHandle,
Refresh_PresentMode presentMode
) {
NOT_IMPLEMENTED
}
/* Submission and Fences */
static void TEMPLATE_Submit( static void TEMPLATE_Submit(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
uint32_t commandBufferCount, Refresh_CommandBuffer *commandBuffer
Refresh_CommandBuffer **pCommandBuffers ) {
NOT_IMPLEMENTED
}
static Refresh_Fence* TEMPLATE_SubmitAndAcquireFence(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer
) { ) {
NOT_IMPLEMENTED NOT_IMPLEMENTED
} }
@ -614,8 +661,38 @@ static void TEMPLATE_Wait(
NOT_IMPLEMENTED NOT_IMPLEMENTED
} }
static void TEMPLATE_WaitForFences(
Refresh_Renderer *driverData,
uint8_t waitAll,
uint32_t fenceCount,
Refresh_Fence **pFences
) {
NOT_IMPLEMENTED
}
static int TEMPLATE_QueryFence(
Refresh_Renderer *driverData,
Refresh_Fence *fence
) {
NOT_IMPLEMENTED
}
static void TEMPLATE_ReleaseFence(
Refresh_Renderer *driverData,
Refresh_Fence *fence
) {
NOT_IMPLEMENTED
}
/* Device Creation */
static uint8_t TEMPLATE_PrepareDriver(
uint32_t *flags
) {
NOT_IMPLEMENTED
}
static Refresh_Device* TEMPLATE_CreateDevice( static Refresh_Device* TEMPLATE_CreateDevice(
Refresh_PresentationParameters *presentationParameters,
uint8_t debugMode uint8_t debugMode
) { ) {
NOT_IMPLEMENTED NOT_IMPLEMENTED
@ -623,6 +700,7 @@ static Refresh_Device* TEMPLATE_CreateDevice(
Refresh_Driver TEMPLATEDriver = { Refresh_Driver TEMPLATEDriver = {
"TEMPLATE", "TEMPLATE",
TEMPLATE_PrepareDriver,
TEMPLATE_CreateDevice TEMPLATE_CreateDevice
}; };

File diff suppressed because it is too large Load Diff

View File

@ -89,6 +89,7 @@ VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdClearDepthStencilImage, (VkCommandBuff
VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdCopyBuffer, (VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)) VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdCopyBuffer, (VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions))
VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdCopyBufferToImage, (VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy *pRegions)) VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdCopyBufferToImage, (VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy *pRegions))
VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdCopyImageToBuffer, (VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions)) VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdCopyImageToBuffer, (VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions))
VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdCopyImage, (VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions))
VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdDispatch, (VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)) VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdDispatch, (VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ))
VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdDraw, (VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)) VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdDraw, (VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance))
VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdDrawIndexed, (VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)) VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdDrawIndexed, (VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance))

View File

@ -48,7 +48,6 @@
#define floorf SDL_floorf #define floorf SDL_floorf
#define ldexp SDL_scalbn #define ldexp SDL_scalbn
#define pow SDL_pow #define pow SDL_pow
#define strtol SDL_strtol
#ifdef memcmp #ifdef memcmp
#undef memcmp #undef memcmp
@ -74,13 +73,10 @@
#undef strlen #undef strlen
#endif #endif
#define strlen SDL_strlen #define strlen SDL_strlen
#ifdef strncmp
#undef strncmp
#endif
#define strncmp SDL_strncmp
/* These are per the Texture2D.FromStream spec */ /* These are per the Texture2D.FromStream spec */
#define STBI_ONLY_PNG #define STBI_ONLY_PNG
#define STBI_ONLY_QOI
/* These are per the Texture2D.SaveAs* spec */ /* These are per the Texture2D.SaveAs* spec */
#define STBIW_ONLY_PNG #define STBIW_ONLY_PNG
@ -140,6 +136,7 @@ SDL_SIMDRealloc(void *mem, const size_t len)
#endif #endif
#define STB_IMAGE_STATIC #define STB_IMAGE_STATIC
#define STBI_NO_HDR
#define STBI_ASSERT SDL_assert #define STBI_ASSERT SDL_assert
#define STBI_MALLOC SDL_SIMDAlloc #define STBI_MALLOC SDL_SIMDAlloc
#define STBI_REALLOC SDL_SIMDRealloc #define STBI_REALLOC SDL_SIMDRealloc
@ -190,51 +187,72 @@ 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, uint8_t *bufferPtr,
int32_t bufferLength,
int32_t *w, int32_t *w,
int32_t *h, int32_t *h,
int32_t *numChannels int32_t *len
) { ) {
return stbi_load(filename, w, h, numChannels, STBI_rgb_alpha); uint8_t* result;
uint8_t* pixels;
int32_t format;
int32_t i;
result = stbi_load_from_memory(
bufferPtr,
bufferLength,
w,
h,
&format,
STBI_rgb_alpha
);
if (result == NULL)
{
SDL_LogWarn(SDL_LOG_CATEGORY_ERROR, "Image loading failed: %s", stbi_failure_reason());
}
/* Ensure that the alpha pixels are... well, actual alpha.
* You think this looks stupid, but be assured: Your paint program is
* almost certainly even stupider.
* -flibit
*/
pixels = result;
*len = (*w) * (*h) *4;
for (i = 0; i < *len; i += 4, pixels += 4)
{
if (pixels[3] == 0)
{
pixels[0] = 0;
pixels[1] = 1;
pixels[2] = 2;
}
}
return result;
} }
void Refresh_Image_Free(uint8_t *mem) void Refresh_Image_Free(uint8_t *mem)
{ {
stbi_image_free(mem); SDL_SIMDFree(mem);
} }
/* Image Write API */ /* Image Write API */
void Refresh_Image_SavePNG( void Refresh_Image_SavePNG(
const char *filename, const char* filename,
uint8_t* data,
int32_t w, int32_t w,
int32_t h, int32_t h
uint8_t bgra,
uint8_t *data
) { ) {
uint32_t i; stbi_write_png(
uint8_t *bgraData; filename,
w,
if (bgra) h,
{ 4,
bgraData = SDL_malloc(w * h * 4); data,
w * 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: */

File diff suppressed because it is too large Load Diff