Added some more wrappers.

This commit is contained in:
Patrick 2024-09-12 00:06:10 +02:00
parent 31af297bab
commit 2f77ed5ef5
3 changed files with 396 additions and 2 deletions

View File

@ -29,8 +29,7 @@ int main(int, char**)
gpuDevice.claimWindow(window); gpuDevice.claimWindow(window);
const SDL_GPUTextureFormat texForm = SDL_GetGPUSwapchainTextureFormat(gpuDevice, window);
(void) texForm;
bool running = true; bool running = true;
while(running) while(running)

View File

@ -6,6 +6,7 @@
#include <stdexcept> #include <stdexcept>
#include <utility> #include <utility>
#include <vector>
#include <mijin/debug/assert.hpp> #include <mijin/debug/assert.hpp>
#include <mijin/util/bitflags.hpp> #include <mijin/util/bitflags.hpp>

View File

@ -74,6 +74,400 @@ public:
} }
} }
}; };
enum class GPUVertexInputRate
{
VERTEX = SDL_GPU_VERTEXINPUTRATE_VERTEX,
INSTANCE = SDL_GPU_VERTEXINPUTRATE_INSTANCE
};
struct GPUVertexBinding
{
Uint32 index;
Uint32 pitch;
GPUVertexInputRate inputRate = GPUVertexInputRate::VERTEX;
Uint32 instanceStepRate;
};
static_assert(sizeof(GPUVertexBinding) == sizeof(SDL_GPUVertexBinding)
&& alignof(GPUVertexBinding) == alignof(SDL_GPUVertexBinding));
enum class GPUVertexElementFormat
{
INT = SDL_GPU_VERTEXELEMENTFORMAT_INT,
INT2 = SDL_GPU_VERTEXELEMENTFORMAT_INT2,
INT3 = SDL_GPU_VERTEXELEMENTFORMAT_INT3,
INT4 = SDL_GPU_VERTEXELEMENTFORMAT_INT4,
UINT = SDL_GPU_VERTEXELEMENTFORMAT_UINT,
UINT2 = SDL_GPU_VERTEXELEMENTFORMAT_UINT2,
UINT3 = SDL_GPU_VERTEXELEMENTFORMAT_UINT3,
UINT4 = SDL_GPU_VERTEXELEMENTFORMAT_UINT4,
FLOAT = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT,
FLOAT2 = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
FLOAT3 = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3,
FLOAT4 = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4,
BYTE2 = SDL_GPU_VERTEXELEMENTFORMAT_BYTE2,
BYTE4 = SDL_GPU_VERTEXELEMENTFORMAT_BYTE4,
UBYTE2 = SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2,
UBYTE4 = SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4,
BYTE2_NORM = SDL_GPU_VERTEXELEMENTFORMAT_BYTE2_NORM,
BYTE4_NORM = SDL_GPU_VERTEXELEMENTFORMAT_BYTE4_NORM,
UBYTE2_NORM = SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2_NORM,
UBYTE4_NORM = SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM,
SHORT2 = SDL_GPU_VERTEXELEMENTFORMAT_SHORT2,
SHORT4 = SDL_GPU_VERTEXELEMENTFORMAT_SHORT4,
USHORT2 = SDL_GPU_VERTEXELEMENTFORMAT_USHORT2,
USHORT4 = SDL_GPU_VERTEXELEMENTFORMAT_USHORT4,
SHORT2_NORM = SDL_GPU_VERTEXELEMENTFORMAT_SHORT2_NORM,
SHORT4_NORM = SDL_GPU_VERTEXELEMENTFORMAT_SHORT4_NORM,
USHORT2_NORM = SDL_GPU_VERTEXELEMENTFORMAT_USHORT2_NORM,
USHORT4_NORM = SDL_GPU_VERTEXELEMENTFORMAT_USHORT4_NORM,
HALF2 = SDL_GPU_VERTEXELEMENTFORMAT_HALF2,
HALF4 = SDL_GPU_VERTEXELEMENTFORMAT_HALF4
};
struct GPUVertexAttribute
{
Uint32 location;
Uint32 bindingIndex;
GPUVertexElementFormat format;
Uint32 offset;
};
static_assert(sizeof(GPUVertexAttribute) == sizeof(SDL_GPUVertexAttribute)
&& alignof(GPUVertexAttribute) == alignof(SDL_GPUVertexAttribute));
struct GPUVertexInputState
{
std::vector<GPUVertexBinding> vertexBindings;
std::vector<GPUVertexAttribute> vertexAttributes;
};
enum class GPUPrimitiveType
{
POINTLIST = SDL_GPU_PRIMITIVETYPE_POINTLIST,
LINELIST = SDL_GPU_PRIMITIVETYPE_LINELIST,
LINESTRIP = SDL_GPU_PRIMITIVETYPE_LINESTRIP,
TRIANGLELIST = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
TRIANGLESTRIP = SDL_GPU_PRIMITIVETYPE_TRIANGLESTRIP
};
enum class GPUFillMode
{
FILL = SDL_GPU_FILLMODE_FILL,
LINE = SDL_GPU_FILLMODE_LINE
};
enum class GPUCullMode
{
NONE = SDL_GPU_CULLMODE_NONE,
FRONT = SDL_GPU_CULLMODE_FRONT,
BACK = SDL_GPU_CULLMODE_BACK
};
enum class GPUFrontFace
{
COUNTER_CLOCKWISE = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE,
CLOCKWISE = SDL_GPU_FRONTFACE_CLOCKWISE
};
struct GPURasterizerState
{
GPUFillMode fillMode = GPUFillMode::FILL;
GPUCullMode cullMode = GPUCullMode::NONE;
GPUFrontFace frontFace = GPUFrontFace::COUNTER_CLOCKWISE;
bool enableDepthBias = false;
float depthBiasConstantFactor;
float depthBiasClamp;
float depthBiasSlopeFactor;
};
enum class GPUSampleCount
{
ONE = SDL_GPU_SAMPLECOUNT_1,
TWO = SDL_GPU_SAMPLECOUNT_2,
FOUR = SDL_GPU_SAMPLECOUNT_4,
EIGHT = SDL_GPU_SAMPLECOUNT_8
};
struct GPUMultisampleState
{
GPUSampleCount sampleCount = GPUSampleCount::ONE;
Uint32 sampleMask = 0xFFFFFFFF;
};
enum class GPUCompareOp
{
NEVER = SDL_GPU_COMPAREOP_NEVER,
LESS = SDL_GPU_COMPAREOP_LESS,
EQUAL = SDL_GPU_COMPAREOP_EQUAL,
LESS_OR_EQUAL = SDL_GPU_COMPAREOP_LESS_OR_EQUAL,
GREATER = SDL_GPU_COMPAREOP_GREATER,
NOT_EQUAL = SDL_GPU_COMPAREOP_NOT_EQUAL,
GREATER_OR_EQUAL = SDL_GPU_COMPAREOP_GREATER_OR_EQUAL,
ALWAYS = SDL_GPU_COMPAREOP_ALWAYS
};
enum class GPUStencilOp
{
KEEP = SDL_GPU_STENCILOP_KEEP,
ZERO = SDL_GPU_STENCILOP_ZERO,
REPLACE = SDL_GPU_STENCILOP_REPLACE,
INCREMENT_AND_CLAMP = SDL_GPU_STENCILOP_INCREMENT_AND_CLAMP,
DECREMENT_AND_CLAMP = SDL_GPU_STENCILOP_DECREMENT_AND_CLAMP,
INVERT = SDL_GPU_STENCILOP_INVERT,
INCREMENT_AND_WRAP = SDL_GPU_STENCILOP_INCREMENT_AND_WRAP,
DECREMENT_AND_WRAP = SDL_GPU_STENCILOP_DECREMENT_AND_WRAP
};
struct GPUStencilOpState
{
GPUStencilOp failOp;
GPUStencilOp passOp;
GPUStencilOp depthFailOp;
GPUCompareOp compareOp;
explicit operator SDL_GPUStencilOpState() const noexcept
{
return {
.fail_op = static_cast<SDL_GPUStencilOp>(failOp),
.pass_op = static_cast<SDL_GPUStencilOp>(passOp),
.depth_fail_op = static_cast<SDL_GPUStencilOp>(depthFailOp),
.compare_op = static_cast<SDL_GPUCompareOp>(compareOp),
};
}
};
struct GPUDepthStencilState
{
bool enableDepthTest = false;
bool enableDepthWrite = false;
bool enableStencilTest = false;
GPUCompareOp compareOp = GPUCompareOp::LESS_OR_EQUAL;
GPUStencilOpState backStencilState;
GPUStencilOpState frontStencilState;
Uint8 compareMask;
Uint8 writeMask;
};
enum class GPUBlendFactor
{
ZERO = SDL_GPU_BLENDFACTOR_ZERO,
ONE = SDL_GPU_BLENDFACTOR_ONE,
SRC_COLOR = SDL_GPU_BLENDFACTOR_SRC_COLOR,
ONE_MINUS_SRC_COLOR = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_COLOR,
DST_COLOR = SDL_GPU_BLENDFACTOR_DST_COLOR,
ONE_MINUS_DST_COLOR = SDL_GPU_BLENDFACTOR_ONE_MINUS_DST_COLOR,
SRC_ALPHA = SDL_GPU_BLENDFACTOR_SRC_ALPHA,
ONE_MINUS_SRC_ALPHA = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
DST_ALPHA = SDL_GPU_BLENDFACTOR_DST_ALPHA,
ONE_MINUS_DST_ALPHA = SDL_GPU_BLENDFACTOR_ONE_MINUS_DST_ALPHA,
CONSTANT_COLOR = SDL_GPU_BLENDFACTOR_CONSTANT_COLOR,
ONE_MINUS_CONSTANT_COLOR = SDL_GPU_BLENDFACTOR_ONE_MINUS_CONSTANT_COLOR,
SRC_ALPHA_SATURATE = SDL_GPU_BLENDFACTOR_SRC_ALPHA_SATURATE
};
enum class GPUBlendOp
{
ADD = SDL_GPU_BLENDOP_ADD,
SUBTRACT = SDL_GPU_BLENDOP_SUBTRACT,
REVERSE_SUBTRACT = SDL_GPU_BLENDOP_REVERSE_SUBTRACT,
MIN = SDL_GPU_BLENDOP_MIN,
MAX = SDL_GPU_BLENDOP_MAX
};
struct GPUColorComponentFlags : mijin::BitFlags<GPUColorComponentFlags>
{
bool r : 1 = false;
bool g : 1 = false;
bool b : 1 = false;
bool a : 1 = false;
};
struct GPUColorTargetBlendState
{
bool enableBlend = false;
GPUBlendFactor srcColorBlendfactor;
GPUBlendFactor dstColorBlendfactor;
GPUBlendOp colorBlendOp;
GPUBlendFactor srcAlphaBlendfactor;
GPUBlendFactor dstAlphaBlendfactor;
GPUBlendOp alphaBlendOp;
GPUColorComponentFlags colorWriteMask = {.r = true, .g = true, .b = true, .a = true};
};
enum class GPUTextureFormat
{
INVALID = SDL_GPU_TEXTUREFORMAT_INVALID,
A8_UNORM = SDL_GPU_TEXTUREFORMAT_A8_UNORM,
R8_UNORM = SDL_GPU_TEXTUREFORMAT_R8_UNORM,
R8G8_UNORM = SDL_GPU_TEXTUREFORMAT_R8G8_UNORM,
R8G8B8A8_UNORM = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM,
R16_UNORM = SDL_GPU_TEXTUREFORMAT_R16_UNORM,
R16G16_UNORM = SDL_GPU_TEXTUREFORMAT_R16G16_UNORM,
R16G16B16A16_UNORM = SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM,
R10G10B10A2_UNORM = SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM,
B5G6R5_UNORM = SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM,
B5G5R5A1_UNORM = SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM,
B4G4R4A4_UNORM = SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM,
B8G8R8A8_UNORM = SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM,
BC1_RGBA_UNORM = SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM,
BC2_RGBA_UNORM = SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM,
BC3_RGBA_UNORM = SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM,
BC4_R_UNORM = SDL_GPU_TEXTUREFORMAT_BC4_R_UNORM,
BC5_RG_UNORM = SDL_GPU_TEXTUREFORMAT_BC5_RG_UNORM,
BC7_RGBA_UNORM = SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM,
BC6H_RGB_FLOAT = SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT,
BC6H_RGB_UFLOAT = SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT,
R8_SNORM = SDL_GPU_TEXTUREFORMAT_R8_SNORM,
R8G8_SNORM = SDL_GPU_TEXTUREFORMAT_R8G8_SNORM,
R8G8B8A8_SNORM = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM,
R16_SNORM = SDL_GPU_TEXTUREFORMAT_R16_SNORM,
R16G16_SNORM = SDL_GPU_TEXTUREFORMAT_R16G16_SNORM,
R16G16B16A16_SNORM = SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SNORM,
R16_FLOAT = SDL_GPU_TEXTUREFORMAT_R16_FLOAT,
R16G16_FLOAT = SDL_GPU_TEXTUREFORMAT_R16G16_FLOAT,
R16G16B16A16_FLOAT = SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT,
R32_FLOAT = SDL_GPU_TEXTUREFORMAT_R32_FLOAT,
R32G32_FLOAT = SDL_GPU_TEXTUREFORMAT_R32G32_FLOAT,
R32G32B32A32_FLOAT = SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT,
R11G11B10_UFLOAT = SDL_GPU_TEXTUREFORMAT_R11G11B10_UFLOAT,
R8_UINT = SDL_GPU_TEXTUREFORMAT_R8_UINT,
R8G8_UINT = SDL_GPU_TEXTUREFORMAT_R8G8_UINT,
R8G8B8A8_UINT = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT,
R16_UINT = SDL_GPU_TEXTUREFORMAT_R16_UINT,
R16G16_UINT = SDL_GPU_TEXTUREFORMAT_R16G16_UINT,
R16G16B16A16_UINT = SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT,
R8_INT = SDL_GPU_TEXTUREFORMAT_R8_INT,
R8G8_INT = SDL_GPU_TEXTUREFORMAT_R8G8_INT,
R8G8B8A8_INT = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_INT,
R16_INT = SDL_GPU_TEXTUREFORMAT_R16_INT,
R16G16_INT = SDL_GPU_TEXTUREFORMAT_R16G16_INT,
R16G16B16A16_INT = SDL_GPU_TEXTUREFORMAT_R16G16B16A16_INT,
R8G8B8A8_UNORM_SRGB = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB,
B8G8R8A8_UNORM_SRGB = SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB,
BC1_RGBA_UNORM_SRGB = SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB,
BC2_RGBA_UNORM_SRGB = SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB,
BC3_RGBA_UNORM_SRGB = SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB,
BC7_RGBA_UNORM_SRGB = SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB,
D16_UNORM = SDL_GPU_TEXTUREFORMAT_D16_UNORM,
D24_UNORM = SDL_GPU_TEXTUREFORMAT_D24_UNORM,
D32_FLOAT = SDL_GPU_TEXTUREFORMAT_D32_FLOAT,
D24_UNORM_S8_UINT = SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT,
D32_FLOAT_S8_UINT = SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT
};
struct GPUColorTargetDescription
{
GPUTextureFormat format = GPUTextureFormat::INVALID;
GPUColorTargetBlendState blendState;
};
static_assert(sizeof(GPUColorTargetDescription) == sizeof(SDL_GPUColorTargetDescription)
&& alignof(GPUColorTargetDescription) == alignof(SDL_GPUColorTargetDescription));
struct GPUGraphicsPipelineTargetInfo
{
std::vector<GPUColorTargetDescription> colorTargetDescriptions;
bool hasDepthStencilTarget = false;
GPUTextureFormat depthStencilFormat = GPUTextureFormat::INVALID;
explicit operator SDL_GpuGraphicsPipelineTargetInfo() const noexcept
{
return {
.color_target_descriptions = std::bit_cast<const SDL_GPUColorTargetDescription*>(colorTargetDescriptions.data()),
.num_color_targets = static_cast<Uint32>(colorTargetDescriptions.size()),
.has_depth_stencil_target = hasDepthStencilTarget,
.depth_stencil_format = static_cast<SDL_GPUTextureFormat>(depthStencilFormat)
};
}
};
struct GPUGraphicsPipelineCreateArgs
{
SDL_GPUShader* vertexShader;
SDL_GPUShader* fragmentShader;
GPUVertexInputState vertexInputState;
GPUPrimitiveType primitiveType = GPUPrimitiveType::TRIANGLELIST;
GPURasterizerState rasterizerState;
GPUMultisampleState multisampleState;
GPUDepthStencilState depthStencilState;
GPUGraphicsPipelineTargetInfo targetInfo;
};
class GPUGraphicsPipeline : public Base<SDL_GPUGraphicsPipeline, GPUGraphicsPipeline>
{
private:
SDL_GPUDevice* mDevice = nullptr;
public:
GPUGraphicsPipeline() noexcept = default;
GPUGraphicsPipeline(const GPUGraphicsPipeline&) = delete;
GPUGraphicsPipeline(GPUGraphicsPipeline&& other) noexcept : Base(std::move(other)) {}
GPUGraphicsPipeline& operator=(const GPUGraphicsPipeline&) = delete;
GPUGraphicsPipeline& operator=(GPUGraphicsPipeline&& other) noexcept
{
Base::operator=(std::move(other));
return *this;
}
auto operator<=>(const GPUGraphicsPipeline& other) const noexcept = default;
void create(SDL_GPUDevice* device, const GPUGraphicsPipelineCreateArgs& args)
{
MIJIN_ASSERT(mHandle == nullptr, "GPUGraphicsPipeline has already been created.");
const SDL_GPUGraphicsPipelineCreateInfo createInfo =
{
.vertex_shader = args.vertexShader,
.fragment_shader = args.fragmentShader,
.vertex_input_state = {
.vertex_bindings = std::bit_cast<SDL_GPUVertexBinding*>(args.vertexInputState.vertexBindings.data()),
.num_vertex_bindings = static_cast<Uint32>(args.vertexInputState.vertexBindings.size()),
.vertex_attributes = std::bit_cast<SDL_GPUVertexAttribute*>(args.vertexInputState.vertexAttributes.data()),
.num_vertex_attributes = static_cast<Uint32>(args.vertexInputState.vertexAttributes.size())
},
.primitive_type = static_cast<SDL_GPUPrimitiveType>(args.primitiveType),
.rasterizer_state = {
.fill_mode = static_cast<SDL_GPUFillMode>(args.rasterizerState.fillMode),
.cull_mode = static_cast<SDL_GPUCullMode>(args.rasterizerState.cullMode),
.front_face = static_cast<SDL_GPUFrontFace>(args.rasterizerState.frontFace),
.enable_depth_bias = args.rasterizerState.enableDepthBias,
.depth_bias_constant_factor = args.rasterizerState.depthBiasConstantFactor,
.depth_bias_clamp = args.rasterizerState.depthBiasClamp,
.depth_bias_slope_factor = args.rasterizerState.depthBiasSlopeFactor
},
.multisample_state = {
.sample_count = static_cast<SDL_GPUSampleCount>(args.multisampleState.sampleCount),
.sample_mask = args.multisampleState.sampleMask
},
.depth_stencil_state = {
.enable_depth_test = args.depthStencilState.enableDepthTest,
.enable_depth_write = args.depthStencilState.enableDepthWrite,
.enable_stencil_test = args.depthStencilState.enableStencilTest,
.compare_op = static_cast<SDL_GPUCompareOp>(args.depthStencilState.compareOp),
.back_stencil_state = static_cast<SDL_GPUStencilOpState>(args.depthStencilState.backStencilState),
.front_stencil_state = static_cast<SDL_GPUStencilOpState>(args.depthStencilState.frontStencilState),
.compare_mask = args.depthStencilState.compareMask,
.write_mask = args.depthStencilState.writeMask
},
.target_info = static_cast<SDL_GpuGraphicsPipelineTargetInfo>(args.targetInfo),
.props = 0
};
mHandle = SDL_CreateGPUGraphicsPipeline(device, &createInfo);
if (mHandle == nullptr)
{
throw SDLError();
}
mDevice = device;
}
void destroy() noexcept
{
if (mHandle != nullptr)
{
SDL_ReleaseGPUGraphicsPipeline(mDevice, mHandle);
mDevice = nullptr;
mHandle = nullptr;
}
}
};
} // namespace sdlpp } // namespace sdlpp
#endif // !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_GPU_HPP_INCLUDED) #endif // !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_GPU_HPP_INCLUDED)