Skip to content

Commit cfaf721

Browse files
committed
Shader::initWithResource / initWithResourceName
1 parent 9df99bd commit cfaf721

6 files changed

Lines changed: 106 additions & 35 deletions

File tree

Sources/ObjectivelyGPU/ComputePipeline.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,29 @@ static ComputePipeline *initWithDevice(ComputePipeline *self, RenderDevice *devi
7272
}
7373

7474
/**
75-
* @fn ComputePipeline *ComputePipeline::initWithResource(ComputePipeline *self, RenderDevice *device, const char *name, const SDL_GPUComputePipelineCreateInfo *info)
75+
* @fn ComputePipeline *ComputePipeline::initWithResource(ComputePipeline *self, RenderDevice *device, const Resource *resource, SDL_GPUShaderFormat format, const SDL_GPUComputePipelineCreateInfo *info)
7676
* @memberof ComputePipeline
7777
*/
78-
static ComputePipeline *initWithResource(ComputePipeline *self, RenderDevice *device, const char *name, const SDL_GPUComputePipelineCreateInfo *info) {
78+
static ComputePipeline *initWithResource(ComputePipeline *self, RenderDevice *device, const Resource *resource, SDL_GPUShaderFormat format, const SDL_GPUComputePipelineCreateInfo *info) {
79+
80+
assert(device);
81+
assert(resource && resource->data && resource->data->length);
82+
assert(info);
83+
84+
SDL_GPUComputePipelineCreateInfo create = *info;
85+
create.code = resource->data->bytes;
86+
create.code_size = resource->data->length;
87+
create.format = format;
88+
create.entrypoint = create.entrypoint ?: (format == SDL_GPU_SHADERFORMAT_MSL) ? "main0" : "main";
89+
90+
return $(self, initWithDevice, device, &create);
91+
}
92+
93+
/**
94+
* @fn ComputePipeline *ComputePipeline::initWithResourceName(ComputePipeline *self, RenderDevice *device, const char *name, const SDL_GPUComputePipelineCreateInfo *info)
95+
* @memberof ComputePipeline
96+
*/
97+
static ComputePipeline *initWithResourceName(ComputePipeline *self, RenderDevice *device, const char *name, const SDL_GPUComputePipelineCreateInfo *info) {
7998

8099
assert(device);
81100
assert(name);
@@ -111,13 +130,7 @@ static ComputePipeline *initWithResource(ComputePipeline *self, RenderDevice *de
111130
continue;
112131
}
113132

114-
SDL_GPUComputePipelineCreateInfo create = *info;
115-
create.code = res->data->bytes;
116-
create.code_size = res->data->length;
117-
create.format = formats[i].format;
118-
create.entrypoint = create.entrypoint ?: (formats[i].format == SDL_GPU_SHADERFORMAT_MSL) ? "main0" : "main";
119-
120-
self = $(self, initWithDevice, device, &create);
133+
self = $(self, initWithResource, device, res, formats[i].format, info);
121134
release(res);
122135
return self;
123136
}
@@ -137,6 +150,7 @@ static void initialize(Class *clazz) {
137150

138151
((ComputePipelineInterface *) clazz->interface)->initWithDevice = initWithDevice;
139152
((ComputePipelineInterface *) clazz->interface)->initWithResource = initWithResource;
153+
((ComputePipelineInterface *) clazz->interface)->initWithResourceName = initWithResourceName;
140154
}
141155

142156
/**

Sources/ObjectivelyGPU/ComputePipeline.h

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <SDL3/SDL_gpu.h>
2727

2828
#include <Objectively/Object.h>
29+
#include <Objectively/Resource.h>
2930

3031
#include <ObjectivelyGPU/Types.h>
3132

@@ -87,7 +88,7 @@ struct ComputePipelineInterface {
8788
* @brief Initializes this ComputePipeline from a fully-populated `SDL_GPUComputePipelineCreateInfo`.
8889
* @details This is the designated initializer. All fields of @p info, including
8990
* `code`, `code_size`, and `format`, must be set by the caller. Prefer
90-
* `initWithResource` to load a compiled blob from the Resource system with
91+
* `initWithResourceName` to load a compiled blob from the Resource system with
9192
* automatic format selection.
9293
* @param self The ComputePipeline.
9394
* @param device The RenderDevice used to create and release the pipeline. Retained.
@@ -98,24 +99,42 @@ struct ComputePipelineInterface {
9899
ComputePipeline *(*initWithDevice)(ComputePipeline *self, RenderDevice *device, const SDL_GPUComputePipelineCreateInfo *info);
99100

100101
/**
101-
* @fn ComputePipeline *ComputePipeline::initWithResource(ComputePipeline *self, RenderDevice *device, const char *name, const SDL_GPUComputePipelineCreateInfo *info)
102+
* @fn ComputePipeline *ComputePipeline::initWithResource(ComputePipeline *self, RenderDevice *device, const Resource *resource, SDL_GPUShaderFormat format, const SDL_GPUComputePipelineCreateInfo *info)
103+
* @brief Initializes this ComputePipeline from an already-loaded compiled blob.
104+
* @details Uses @p resource's data as the pipeline `code` for the given @p format.
105+
* `entrypoint` defaults to `main0` (MSL) or `main` when not set; the `code`,
106+
* `code_size`, and `format` fields of @p info are ignored. `initWithResourceName`
107+
* resolves a name to a resource and format, then delegates here.
108+
* @param self The ComputePipeline.
109+
* @param device The RenderDevice used to create and release the pipeline. Retained.
110+
* @param resource The loaded shader blob; must have non-empty data.
111+
* @param format The shader format of @p resource's data.
112+
* @param info Compute pipeline creation parameters; `code`, `code_size`, and `format` are ignored.
113+
* @return The initialized ComputePipeline, or `NULL` on failure.
114+
* @memberof ComputePipeline
115+
*/
116+
ComputePipeline *(*initWithResource)(ComputePipeline *self, RenderDevice *device, const Resource *resource, SDL_GPUShaderFormat format, const SDL_GPUComputePipelineCreateInfo *info);
117+
118+
/**
119+
* @fn ComputePipeline *ComputePipeline::initWithResourceName(ComputePipeline *self, RenderDevice *device, const char *name, const SDL_GPUComputePipelineCreateInfo *info)
102120
* @brief Initializes this ComputePipeline from a compiled blob loaded via the Resource system.
103121
* @details Appends the platform-appropriate extension to @p name and resolves it via
104122
* Objectively's ResourceProvider chain:
105123
* - Metal (macOS/iOS): `.metal`
106124
* - Vulkan (Linux/Android): `.spv`
107125
* - D3D12 (Windows): `.dxil`
108-
* The caller fills in @c entrypoint, thread counts, and binding counts in @p info;
109-
* `code`, `code_size`, and `format` are filled in here. Shader blobs are produced
110-
* offline by @c sdl-shadercross.
126+
* The first supported, resolvable, non-empty blob is selected and passed to
127+
* `initWithResource` with its format. The caller fills in @c entrypoint, thread
128+
* counts, and binding counts in @p info; `code`, `code_size`, `format`, and a default
129+
* `entrypoint` are supplied. Shader blobs are produced offline by @c sdl-shadercross.
111130
* @param self The ComputePipeline.
112131
* @param device The RenderDevice used to create and release the pipeline. Retained.
113132
* @param name Shader base name without extension, e.g. @c "HelloCompute.comp".
114133
* @param info Compute pipeline creation parameters; `code`, `code_size`, and `format` are ignored.
115134
* @return The initialized ComputePipeline. GPU_Asserts if no supported blob is found.
116135
* @memberof ComputePipeline
117136
*/
118-
ComputePipeline *(*initWithResource)(ComputePipeline *self, RenderDevice *device, const char *name, const SDL_GPUComputePipelineCreateInfo *info);
137+
ComputePipeline *(*initWithResourceName)(ComputePipeline *self, RenderDevice *device, const char *name, const SDL_GPUComputePipelineCreateInfo *info);
119138
};
120139

121140
/**

Sources/ObjectivelyGPU/RenderDevice.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ static RenderDevice *initWithWindow(RenderDevice *self, SDL_Window *window) {
303303
*/
304304
static Shader *loadShader(RenderDevice *self, const char *name, const SDL_GPUShaderCreateInfo *info) {
305305

306-
return $(alloc(Shader), initWithResource, self, name, info);
306+
return $(alloc(Shader), initWithResourceName, self, name, info);
307307
}
308308

309309
/**
@@ -312,7 +312,7 @@ static Shader *loadShader(RenderDevice *self, const char *name, const SDL_GPUSha
312312
*/
313313
static ComputePipeline *loadComputePipeline(RenderDevice *self, const char *name, const SDL_GPUComputePipelineCreateInfo *info) {
314314

315-
return $(alloc(ComputePipeline), initWithResource, self, name, info);
315+
return $(alloc(ComputePipeline), initWithResourceName, self, name, info);
316316
}
317317

318318
/**

Sources/ObjectivelyGPU/RenderDevice.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ struct RenderDeviceInterface {
329329
/**
330330
* @fn Shader *RenderDevice::loadShader(RenderDevice *self, const char *name, const SDL_GPUShaderCreateInfo *info)
331331
* @brief Loads a compiled shader blob via the Resource system and creates a Shader.
332-
* @details Convenience factory for `Shader::initWithResource`. Appends the
332+
* @details Convenience factory for `Shader::initWithResourceName`. Appends the
333333
* platform-appropriate extension to @c name and resolves it via Objectively's
334334
* ResourceProvider chain:
335335
* - Metal (macOS/iOS): `.metal`
@@ -350,7 +350,7 @@ struct RenderDeviceInterface {
350350
/**
351351
* @fn ComputePipeline *RenderDevice::loadComputePipeline(RenderDevice *self, const char *name, const SDL_GPUComputePipelineCreateInfo *info)
352352
* @brief Loads a compiled compute shader blob via the Resource system and creates a ComputePipeline.
353-
* @details Convenience factory for `ComputePipeline::initWithResource`. Parallel to
353+
* @details Convenience factory for `ComputePipeline::initWithResourceName`. Parallel to
354354
* `loadShader` for compute stages. Appends the platform-appropriate extension to
355355
* @c name and resolves it via Objectively's ResourceProvider chain:
356356
* - Metal (macOS/iOS): `.metal`

Sources/ObjectivelyGPU/Shader.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,32 @@ static Shader *initWithDevice(Shader *self, RenderDevice *device, const SDL_GPUS
7373
}
7474

7575
/**
76-
* @fn Shader *Shader::initWithResource(Shader *self, RenderDevice *device, const char *name, const SDL_GPUShaderCreateInfo *info)
76+
* @fn Shader *Shader::initWithResource(Shader *self, RenderDevice *device, const Resource *resource, SDL_GPUShaderFormat format, const SDL_GPUShaderCreateInfo *info)
7777
* @memberof Shader
7878
*/
79-
static Shader *initWithResource(Shader *self, RenderDevice *device, const char *name, const SDL_GPUShaderCreateInfo *info) {
79+
static Shader *initWithResource(Shader *self, RenderDevice *device, const Resource *resource, SDL_GPUShaderFormat format, const SDL_GPUShaderCreateInfo *info) {
80+
81+
assert(device);
82+
assert(resource && resource->data && resource->data->length);
83+
assert(info);
84+
85+
SDL_GPUShaderCreateInfo filled = *info;
86+
filled.code = resource->data->bytes;
87+
filled.code_size = resource->data->length;
88+
filled.format = format;
89+
90+
if (!filled.entrypoint) {
91+
filled.entrypoint = (format == SDL_GPU_SHADERFORMAT_MSL) ? "main0" : "main";
92+
}
93+
94+
return $(self, initWithDevice, device, &filled);
95+
}
96+
97+
/**
98+
* @fn Shader *Shader::initWithResourceName(Shader *self, RenderDevice *device, const char *name, const SDL_GPUShaderCreateInfo *info)
99+
* @memberof Shader
100+
*/
101+
static Shader *initWithResourceName(Shader *self, RenderDevice *device, const char *name, const SDL_GPUShaderCreateInfo *info) {
80102

81103
assert(device);
82104
assert(name);
@@ -107,16 +129,12 @@ static Shader *initWithResource(Shader *self, RenderDevice *device, const char *
107129
continue;
108130
}
109131

110-
SDL_GPUShaderCreateInfo filled = *info;
111-
filled.code = res->data->bytes;
112-
filled.code_size = res->data->length;
113-
filled.format = formats[i].format;
114-
115-
if (!filled.entrypoint) {
116-
filled.entrypoint = (formats[i].format == SDL_GPU_SHADERFORMAT_MSL) ? "main0" : "main";
132+
if (!res->data || res->data->length == 0) {
133+
release(res);
134+
continue;
117135
}
118136

119-
self = $(self, initWithDevice, device, &filled);
137+
self = $(self, initWithResource, device, res, formats[i].format, info);
120138
release(res);
121139
return self;
122140
}
@@ -136,6 +154,7 @@ static void initialize(Class *clazz) {
136154

137155
((ShaderInterface *) clazz->interface)->initWithDevice = initWithDevice;
138156
((ShaderInterface *) clazz->interface)->initWithResource = initWithResource;
157+
((ShaderInterface *) clazz->interface)->initWithResourceName = initWithResourceName;
139158
}
140159

141160
/**

Sources/ObjectivelyGPU/Shader.h

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <SDL3/SDL_gpu.h>
2727

2828
#include <Objectively/Object.h>
29+
#include <Objectively/Resource.h>
2930

3031
#include <ObjectivelyGPU/Types.h>
3132

@@ -93,7 +94,7 @@ struct ShaderInterface {
9394
* @brief Initializes this Shader from a fully-populated `SDL_GPUShaderCreateInfo`.
9495
* @details This is the designated initializer. All fields of @p info, including
9596
* `code`, `code_size`, and `format`, must be set by the caller. Prefer
96-
* `initWithResource` to load a compiled blob from the Resource system with
97+
* `initWithResourceName` to load a compiled blob from the Resource system with
9798
* automatic format selection.
9899
* @param self The Shader.
99100
* @param device The RenderDevice used to create and release the shader. Retained.
@@ -104,24 +105,42 @@ struct ShaderInterface {
104105
Shader *(*initWithDevice)(Shader *self, RenderDevice *device, const SDL_GPUShaderCreateInfo *info);
105106

106107
/**
107-
* @fn Shader *Shader::initWithResource(Shader *self, RenderDevice *device, const char *name, const SDL_GPUShaderCreateInfo *info)
108+
* @fn Shader *Shader::initWithResource(Shader *self, RenderDevice *device, const Resource *resource, SDL_GPUShaderFormat format, const SDL_GPUShaderCreateInfo *info)
109+
* @brief Initializes this Shader from an already-loaded compiled shader blob.
110+
* @details Uses @p resource's data as the shader `code` for the given @p format.
111+
* `entrypoint` defaults to `main0` (MSL) or `main` when not set; the `code`,
112+
* `code_size`, and `format` fields of @p info are ignored. `initWithResourceName`
113+
* resolves a name to a resource and format, then delegates here.
114+
* @param self The Shader.
115+
* @param device The RenderDevice used to create and release the shader. Retained.
116+
* @param resource The loaded shader blob; must have non-empty data.
117+
* @param format The shader format of @p resource's data.
118+
* @param info Shader creation parameters; `code`, `code_size`, and `format` are ignored.
119+
* @return The initialized Shader, or `NULL` on failure.
120+
* @memberof Shader
121+
*/
122+
Shader *(*initWithResource)(Shader *self, RenderDevice *device, const Resource *resource, SDL_GPUShaderFormat format, const SDL_GPUShaderCreateInfo *info);
123+
124+
/**
125+
* @fn Shader *Shader::initWithResourceName(Shader *self, RenderDevice *device, const char *name, const SDL_GPUShaderCreateInfo *info)
108126
* @brief Initializes this Shader from a compiled shader blob loaded via the Resource system.
109127
* @details Appends the platform-appropriate extension to @p name and resolves it via
110128
* Objectively's ResourceProvider chain:
111129
* - Metal (macOS/iOS): `.metal`
112130
* - Vulkan (Linux/Android): `.spv`
113131
* - D3D12 (Windows): `.dxil`
114-
* The caller fills in @c stage and binding counts in @p info; `code`, `code_size`,
115-
* and `format` are filled in here, and `entrypoint` defaults to `main0` (MSL) or
116-
* `main` when not set. Shader blobs are produced offline by @c sdl-shadercross.
132+
* The first supported, resolvable, non-empty blob is selected and passed to
133+
* `initWithResource` with its format. The caller fills in @c stage and binding counts
134+
* in @p info; `code`, `code_size`, `format`, and a default `entrypoint` are supplied.
135+
* Shader blobs are produced offline by @c sdl-shadercross.
117136
* @param self The Shader.
118137
* @param device The RenderDevice used to create and release the shader. Retained.
119138
* @param name Shader base name without extension, e.g. @c "shaders/Renderer.vert".
120139
* @param info Shader creation parameters; `code`, `code_size`, and `format` are ignored.
121140
* @return The initialized Shader. GPU_Asserts if no supported blob is found.
122141
* @memberof Shader
123142
*/
124-
Shader *(*initWithResource)(Shader *self, RenderDevice *device, const char *name, const SDL_GPUShaderCreateInfo *info);
143+
Shader *(*initWithResourceName)(Shader *self, RenderDevice *device, const char *name, const SDL_GPUShaderCreateInfo *info);
125144
};
126145

127146
/**

0 commit comments

Comments
 (0)