I am on version 3.2.16 of SDL. I get the above error when targeting Direct3D12, but everything works flawlessly when targetting vulkan - this makes sense considering the error code is directx specific, but after searching online I couldn’t find much of an answer to it. The below snippet is minimal and just initializes a window and a graphics pipeline, and the error occurs on the check for whether pipeline is null (SDL_CreateGPUGraphicsPipeline returns null).
SDL_Window *instance = SDL_CreateWindow("Temp", 1280, 720, SDL_WINDOW_HIDDEN);
if (!instance) throw std::exception(std::format("Could not create window: {}.", SDL_GetError()).c_str());
SDL_GPUDevice *gpu = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV | SDL_GPU_SHADERFORMAT_DXIL, false, "direct3d12");
if (!gpu) throw std::exception(std::format("Could not create GPU device for window: {}.", SDL_GetError()).c_str());
if (!SDL_ClaimWindowForGPUDevice(gpu, instance))
throw std::exception(std::format("Could not claim window for GPU device for window: {}.", SDL_GetError()).c_str());
SDL_ShowWindow(instance);
SDL_GPUShaderFormat current_format = SDL_GPU_SHADERFORMAT_INVALID;
const SDL_GPUShaderFormat backend_formats = SDL_GetGPUShaderFormats(gpu);
if (backend_formats & SDL_GPU_SHADERFORMAT_DXIL)
current_format = SDL_GPU_SHADERFORMAT_DXIL;
else if (backend_formats & SDL_GPU_SHADERFORMAT_SPIRV)
current_format = SDL_GPU_SHADERFORMAT_SPIRV;
else
throw std::exception(std::format("Could not find supported shader format for object: {}.", SDL_GetError()).c_str());
std::string vertex_shader_path;
std::string fragment_shader_path;
if (current_format == SDL_GPU_SHADERFORMAT_DXIL)
{
vertex_shader_path = "shader/main.vert.dxil";
fragment_shader_path = "shader/main.frag.dxil";
}
else
{
vertex_shader_path = "shader/main.vert.spirv";
fragment_shader_path = "shader/main.frag.spirv";
}
std::ifstream vertex_file(vertex_shader_path, std::ios::binary);
if (!vertex_file)
throw std::exception(std::format("Could not open vertex shader file: {}.", vertex_shader_path).c_str());
std::vector<unsigned char> vertex_data((std::istreambuf_iterator<char>(vertex_file)),
std::istreambuf_iterator<char>());
vertex_file.close();
std::ifstream fragment_file(fragment_shader_path, std::ios::binary);
if (!fragment_file)
throw std::exception(std::format("Could not open fragment shader file: {}.", fragment_shader_path).c_str());
std::vector<unsigned char> fragment_data((std::istreambuf_iterator<char>(fragment_file)),
std::istreambuf_iterator<char>());
fragment_file.close();
SDL_GPUShaderCreateInfo vertex_shader_info(vertex_data.size(), vertex_data.data(), "main", current_format,
SDL_GPU_SHADERSTAGE_VERTEX, 0, 0, 0, 1);
SDL_GPUShader *vertex_shader = SDL_CreateGPUShader(gpu, &vertex_shader_info);
if (!vertex_shader) throw std::exception(std::format("Could not create vertex shader: {}.", SDL_GetError()).c_str());
SDL_GPUShaderCreateInfo fragment_shader_info(fragment_data.size(), fragment_data.data(), "main", current_format,
SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 0, 0, 0);
SDL_GPUShader *fragment_shader = SDL_CreateGPUShader(gpu, &fragment_shader_info);
if (!fragment_shader)
throw std::exception(std::format("Could not create fragment shader: {}.", SDL_GetError()).c_str());
SDL_GPUVertexBufferDescription vertex_buffer_description(0, sizeof(vertex), SDL_GPU_VERTEXINPUTRATE_VERTEX, 0);
std::array<SDL_GPUVertexAttribute, 3> vertex_attributes(
{{0, 0, SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, 0},
{1, 0, SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM, sizeof(vertex::x) + sizeof(vertex::y) + sizeof(vertex::z)},
{2, 0, SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
sizeof(vertex::x) + sizeof(vertex::y) + sizeof(vertex::z) + sizeof(vertex::r) + sizeof(vertex::g) +
sizeof(vertex::b) + sizeof(vertex::a)}});
SDL_GPUVertexInputState vertex_input_state(&vertex_buffer_description, 1, vertex_attributes.data(), 3);
SDL_GPURasterizerState rasterizer_state(SDL_GPU_FILLMODE_FILL, SDL_GPU_CULLMODE_BACK,
SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE);
SDL_GPUColorTargetDescription color_target_description(SDL_GetGPUSwapchainTextureFormat(gpu, instance));
SDL_GPUGraphicsPipelineTargetInfo target_info(&color_target_description, 1);
SDL_GPUGraphicsPipelineCreateInfo pipeline_info(vertex_shader, fragment_shader, vertex_input_state,
SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, rasterizer_state,
SDL_GPUMultisampleState(), SDL_GPUDepthStencilState(), target_info);
SDL_GPUGraphicsPipeline *pipeline = SDL_CreateGPUGraphicsPipeline(gpu, &pipeline_info);
if (!pipeline) throw std::exception(std::format("Could not create graphics pipeline: {}.", SDL_GetError()).c_str());
SDL_ReleaseGPUShader(gpu, fragment_shader);
SDL_ReleaseGPUShader(gpu, vertex_shader);
SDL_Log("Exiting normally.");
return EXIT_SUCCESS;
The shaders main.vert and main.frag are as follows:
struct Input
{
float3 position : TEXCOORD0;
float4 color : TEXCOORD1;
float2 texcoord : TEXCOORD2;
};
struct Output
{
float4 position : SV_Position;
float4 color : TEXCOORD0;
float2 texcoord : TEXCOORD1;
};
cbuffer Matrices : register(b0, space1)
{
float4x4 projection_matrix;
float4x4 view_matrix;
float4x4 model_matrix;
};
Output main(Input input)
{
Output output;
output.position = mul(projection_matrix, mul(view_matrix, mul(model_matrix, float4(input.position, 1.0f))));
output.color = input.color;
output.texcoord = input.texcoord;
return output;
}
struct Input
{
float4 color : TEXCOORD0;
float2 texture : TEXCOORD1;
};
Texture2D<float4> Texture : register(t0, space2);
SamplerState Sampler : register(s0, space2);
float4 main(Input input) : SV_Target0
{
float4 texture_color = Texture.Sample(Sampler, input.texture);
if (texture_color.a == 0.0f) discard;
return texture_color;
}
They were compiled using dxc, with the -spirv flag for testing with vulkan, and target profiles vs_6_0 and ps_6_0 accordingly.
I am lead to believe from everything I’ve seen online that it has something to do with the contents of the shaders, but there is nothing concrete, since I am new to writing HLSL help would be greatly appreciated.