|
@@ -3974,9 +3974,12 @@ typedef struct sg_frame_stats {
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_BEGINPASS_SWAPCHAIN_WGPU_EXPECT_DEPTHSTENCILVIEW, "sg_begin_pass: expected pass.swapchain.wgpu.depth_stencil_view != 0") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_BEGINPASS_SWAPCHAIN_WGPU_EXPECT_DEPTHSTENCILVIEW_NOTSET, "sg_begin_pass: expected pass.swapchain.wgpu.depth_stencil_view == 0") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_BEGINPASS_SWAPCHAIN_GL_EXPECT_FRAMEBUFFER_NOTSET, "sg_begin_pass: expected pass.swapchain.gl.framebuffer == 0") \
|
|
|
+ _SG_LOGITEM_XMACRO(VALIDATE_AVP_RENDERPASS_EXPECTED, "sg_apply_viewport: must be called in a render pass") \
|
|
|
+ _SG_LOGITEM_XMACRO(VALIDATE_ASR_RENDERPASS_EXPECTED, "sg_apply_scissor_rect: must be called in a render pass") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_APIP_PIPELINE_VALID_ID, "sg_apply_pipeline: invalid pipeline id provided") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_APIP_PIPELINE_EXISTS, "sg_apply_pipeline: pipeline object no longer alive") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_APIP_PIPELINE_VALID, "sg_apply_pipeline: pipeline object not in valid state") \
|
|
|
+ _SG_LOGITEM_XMACRO(VALIDATE_APIP_PASS_EXPECTED, "sg_apply_pipeline: must be called in a pass") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_APIP_SHADER_EXISTS, "sg_apply_pipeline: shader object no longer alive") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_APIP_SHADER_VALID, "sg_apply_pipeline: shader object not in valid state") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_APIP_COMPUTEPASS_EXPECTED, "sg_apply_pipeline: trying to apply compute pipeline in render pass") \
|
|
@@ -3987,6 +3990,7 @@ typedef struct sg_frame_stats {
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_APIP_COLOR_FORMAT, "sg_apply_pipeline: pipeline color attachment pixel format doesn't match pass color attachment pixel format") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_APIP_DEPTH_FORMAT, "sg_apply_pipeline: pipeline depth pixel_format doesn't match pass depth attachment pixel format") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_APIP_SAMPLE_COUNT, "sg_apply_pipeline: pipeline MSAA sample count doesn't match render pass attachment sample count") \
|
|
|
+ _SG_LOGITEM_XMACRO(VALIDATE_ABND_PASS_EXPECTED, "sg_apply_bindings: must be called in a pass") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_ABND_PIPELINE, "sg_apply_bindings: must be called after sg_apply_pipeline") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_ABND_PIPELINE_EXISTS, "sg_apply_bindings: currently applied pipeline object no longer alive") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_ABND_PIPELINE_VALID, "sg_apply_bindings: currently applied pipeline object not in valid state") \
|
|
@@ -4016,15 +4020,16 @@ typedef struct sg_frame_stats {
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_ABND_EXPECTED_STORAGEBUFFER_BINDING, "sg_apply_bindings: storage buffer binding is missing or the buffer handle is invalid") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_ABND_STORAGEBUFFER_EXISTS, "sg_apply_bindings: bound storage buffer no longer alive") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_ABND_STORAGEBUFFER_BINDING_BUFFERTYPE, "sg_apply_bindings: buffer bound storage buffer slot is not of type storage buffer") \
|
|
|
- _SG_LOGITEM_XMACRO(VALIDATE_AUB_NO_PIPELINE, "sg_apply_uniforms: must be called after sg_apply_pipeline()") \
|
|
|
- _SG_LOGITEM_XMACRO(VALIDATE_AUB_NO_UNIFORMBLOCK_AT_SLOT, "sg_apply_uniforms: no uniform block declaration at this shader stage UB slot") \
|
|
|
- _SG_LOGITEM_XMACRO(VALIDATE_AUB_SIZE, "sg_apply_uniforms: data size doesn't match declared uniform block size") \
|
|
|
- _SG_LOGITEM_XMACRO(VALIDATE_DRAW_RENDERPASS_EXPECTED, "sg_draw: must be executed in a render pass") \
|
|
|
+ _SG_LOGITEM_XMACRO(VALIDATE_AU_PASS_EXPECTED, "sg_apply_uniforms: must be called in a pass") \
|
|
|
+ _SG_LOGITEM_XMACRO(VALIDATE_AU_NO_PIPELINE, "sg_apply_uniforms: must be called after sg_apply_pipeline()") \
|
|
|
+ _SG_LOGITEM_XMACRO(VALIDATE_AU_NO_UNIFORMBLOCK_AT_SLOT, "sg_apply_uniforms: no uniform block declaration at this shader stage UB slot") \
|
|
|
+ _SG_LOGITEM_XMACRO(VALIDATE_AU_SIZE, "sg_apply_uniforms: data size doesn't match declared uniform block size") \
|
|
|
+ _SG_LOGITEM_XMACRO(VALIDATE_DRAW_RENDERPASS_EXPECTED, "sg_draw: must be called in a render pass") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_DRAW_BASEELEMENT, "sg_draw: base_element cannot be < 0") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_DRAW_NUMELEMENTS, "sg_draw: num_elements cannot be < 0") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_DRAW_NUMINSTANCES, "sg_draw: num_instances cannot be < 0") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_DRAW_REQUIRED_BINDINGS_OR_UNIFORMS_MISSING, "sg_draw: call to sg_apply_bindings() and/or sg_apply_uniforms() missing after sg_apply_pipeline()") \
|
|
|
- _SG_LOGITEM_XMACRO(VALIDATE_DISPATCH_COMPUTEPASS_EXPECTED, "sg_dispatch: must be executed in a compute pass") \
|
|
|
+ _SG_LOGITEM_XMACRO(VALIDATE_DISPATCH_COMPUTEPASS_EXPECTED, "sg_dispatch: must be called in a compute pass") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_DISPATCH_NUMGROUPSX, "sg_dispatch: num_groups_x cannot be < 0") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_DISPATCH_NUMGROUPSY, "sg_dispatch: num_groups_y cannot be < 0") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_DISPATCH_NUMGROUPSZ, "sg_dispatch: num_groups_z cannot be < 0") \
|
|
@@ -18175,6 +18180,42 @@ _SOKOL_PRIVATE bool _sg_validate_begin_pass(const sg_pass* pass) {
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+_SOKOL_PRIVATE bool _sg_validate_apply_viewport(int x, int y, int width, int height, bool origin_top_left) {
|
|
|
+ _SOKOL_UNUSED(x);
|
|
|
+ _SOKOL_UNUSED(y);
|
|
|
+ _SOKOL_UNUSED(width);
|
|
|
+ _SOKOL_UNUSED(height);
|
|
|
+ _SOKOL_UNUSED(origin_top_left);
|
|
|
+ #if !defined(SOKOL_DEBUG)
|
|
|
+ return true;
|
|
|
+ #else
|
|
|
+ if (_sg.desc.disable_validation) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ _sg_validate_begin();
|
|
|
+ _SG_VALIDATE(_sg.cur_pass.in_pass && !_sg.cur_pass.is_compute, VALIDATE_AVP_RENDERPASS_EXPECTED);
|
|
|
+ return _sg_validate_end();
|
|
|
+ #endif
|
|
|
+}
|
|
|
+
|
|
|
+_SOKOL_PRIVATE bool _sg_validate_apply_scissor_rect(int x, int y, int width, int height, bool origin_top_left) {
|
|
|
+ _SOKOL_UNUSED(x);
|
|
|
+ _SOKOL_UNUSED(y);
|
|
|
+ _SOKOL_UNUSED(width);
|
|
|
+ _SOKOL_UNUSED(height);
|
|
|
+ _SOKOL_UNUSED(origin_top_left);
|
|
|
+ #if !defined(SOKOL_DEBUG)
|
|
|
+ return true;
|
|
|
+ #else
|
|
|
+ if (_sg.desc.disable_validation) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ _sg_validate_begin();
|
|
|
+ _SG_VALIDATE(_sg.cur_pass.in_pass && !_sg.cur_pass.is_compute, VALIDATE_ASR_RENDERPASS_EXPECTED);
|
|
|
+ return _sg_validate_end();
|
|
|
+ #endif
|
|
|
+}
|
|
|
+
|
|
|
_SOKOL_PRIVATE bool _sg_validate_apply_pipeline(sg_pipeline pip_id) {
|
|
|
#if !defined(SOKOL_DEBUG)
|
|
|
_SOKOL_UNUSED(pip_id);
|
|
@@ -18194,6 +18235,7 @@ _SOKOL_PRIVATE bool _sg_validate_apply_pipeline(sg_pipeline pip_id) {
|
|
|
_SG_VALIDATE(pip->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_APIP_PIPELINE_VALID);
|
|
|
// the pipeline's shader must be alive and valid
|
|
|
SOKOL_ASSERT(pip->shader);
|
|
|
+ _SG_VALIDATE(_sg.cur_pass.in_pass, VALIDATE_APIP_PASS_EXPECTED);
|
|
|
_SG_VALIDATE(pip->shader->slot.id == pip->cmn.shader_id.id, VALIDATE_APIP_SHADER_EXISTS);
|
|
|
_SG_VALIDATE(pip->shader->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_APIP_SHADER_VALID);
|
|
|
if (pip->cmn.is_compute) {
|
|
@@ -18242,6 +18284,9 @@ _SOKOL_PRIVATE bool _sg_validate_apply_bindings(const sg_bindings* bindings) {
|
|
|
}
|
|
|
_sg_validate_begin();
|
|
|
|
|
|
+ // must be called in a pass
|
|
|
+ _SG_VALIDATE(_sg.cur_pass.in_pass, VALIDATE_ABND_PASS_EXPECTED);
|
|
|
+
|
|
|
// a pipeline object must have been applied
|
|
|
_SG_VALIDATE(_sg.cur_pipeline.id != SG_INVALID_ID, VALIDATE_ABND_PIPELINE);
|
|
|
const _sg_pipeline_t* pip = _sg_lookup_pipeline(&_sg.pools, _sg.cur_pipeline.id);
|
|
@@ -18380,14 +18425,15 @@ _SOKOL_PRIVATE bool _sg_validate_apply_uniforms(int ub_slot, const sg_range* dat
|
|
|
}
|
|
|
SOKOL_ASSERT((ub_slot >= 0) && (ub_slot < SG_MAX_UNIFORMBLOCK_BINDSLOTS));
|
|
|
_sg_validate_begin();
|
|
|
- _SG_VALIDATE(_sg.cur_pipeline.id != SG_INVALID_ID, VALIDATE_AUB_NO_PIPELINE);
|
|
|
+ _SG_VALIDATE(_sg.cur_pass.in_pass, VALIDATE_AU_PASS_EXPECTED);
|
|
|
+ _SG_VALIDATE(_sg.cur_pipeline.id != SG_INVALID_ID, VALIDATE_AU_NO_PIPELINE);
|
|
|
const _sg_pipeline_t* pip = _sg_lookup_pipeline(&_sg.pools, _sg.cur_pipeline.id);
|
|
|
SOKOL_ASSERT(pip && (pip->slot.id == _sg.cur_pipeline.id));
|
|
|
SOKOL_ASSERT(pip->shader && (pip->shader->slot.id == pip->cmn.shader_id.id));
|
|
|
|
|
|
const _sg_shader_t* shd = pip->shader;
|
|
|
- _SG_VALIDATE(shd->cmn.uniform_blocks[ub_slot].stage != SG_SHADERSTAGE_NONE, VALIDATE_AUB_NO_UNIFORMBLOCK_AT_SLOT);
|
|
|
- _SG_VALIDATE(data->size == shd->cmn.uniform_blocks[ub_slot].size, VALIDATE_AUB_SIZE);
|
|
|
+ _SG_VALIDATE(shd->cmn.uniform_blocks[ub_slot].stage != SG_SHADERSTAGE_NONE, VALIDATE_AU_NO_UNIFORMBLOCK_AT_SLOT);
|
|
|
+ _SG_VALIDATE(data->size == shd->cmn.uniform_blocks[ub_slot].size, VALIDATE_AU_SIZE);
|
|
|
|
|
|
return _sg_validate_end();
|
|
|
#endif
|
|
@@ -19840,7 +19886,11 @@ SOKOL_API_IMPL void sg_begin_pass(const sg_pass* pass) {
|
|
|
|
|
|
SOKOL_API_IMPL void sg_apply_viewport(int x, int y, int width, int height, bool origin_top_left) {
|
|
|
SOKOL_ASSERT(_sg.valid);
|
|
|
- SOKOL_ASSERT(_sg.cur_pass.in_pass);
|
|
|
+ #if defined(SOKOL_DEBUG)
|
|
|
+ if (!_sg_validate_apply_viewport(x, y, width, height, origin_top_left)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
_sg_stats_add(num_apply_viewport, 1);
|
|
|
if (!_sg.cur_pass.valid) {
|
|
|
return;
|
|
@@ -19855,7 +19905,11 @@ SOKOL_API_IMPL void sg_apply_viewportf(float x, float y, float width, float heig
|
|
|
|
|
|
SOKOL_API_IMPL void sg_apply_scissor_rect(int x, int y, int width, int height, bool origin_top_left) {
|
|
|
SOKOL_ASSERT(_sg.valid);
|
|
|
- SOKOL_ASSERT(_sg.cur_pass.in_pass);
|
|
|
+ #if defined(SOKOL_DEBUG)
|
|
|
+ if (!_sg_validate_apply_scissor_rect(x, y, width, height, origin_top_left)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
_sg_stats_add(num_apply_scissor_rect, 1);
|
|
|
if (!_sg.cur_pass.valid) {
|
|
|
return;
|
|
@@ -19870,7 +19924,6 @@ SOKOL_API_IMPL void sg_apply_scissor_rectf(float x, float y, float width, float
|
|
|
|
|
|
SOKOL_API_IMPL void sg_apply_pipeline(sg_pipeline pip_id) {
|
|
|
SOKOL_ASSERT(_sg.valid);
|
|
|
- SOKOL_ASSERT(_sg.cur_pass.in_pass);
|
|
|
_sg_stats_add(num_apply_pipeline, 1);
|
|
|
if (!_sg_validate_apply_pipeline(pip_id)) {
|
|
|
_sg.next_draw_valid = false;
|
|
@@ -19900,7 +19953,6 @@ SOKOL_API_IMPL void sg_apply_pipeline(sg_pipeline pip_id) {
|
|
|
|
|
|
SOKOL_API_IMPL void sg_apply_bindings(const sg_bindings* bindings) {
|
|
|
SOKOL_ASSERT(_sg.valid);
|
|
|
- SOKOL_ASSERT(_sg.cur_pass.in_pass);
|
|
|
SOKOL_ASSERT(bindings);
|
|
|
SOKOL_ASSERT((bindings->_start_canary == 0) && (bindings->_end_canary==0));
|
|
|
_sg_stats_add(num_apply_bindings, 1);
|
|
@@ -19998,7 +20050,6 @@ SOKOL_API_IMPL void sg_apply_bindings(const sg_bindings* bindings) {
|
|
|
|
|
|
SOKOL_API_IMPL void sg_apply_uniforms(int ub_slot, const sg_range* data) {
|
|
|
SOKOL_ASSERT(_sg.valid);
|
|
|
- SOKOL_ASSERT(_sg.cur_pass.in_pass);
|
|
|
SOKOL_ASSERT((ub_slot >= 0) && (ub_slot < SG_MAX_UNIFORMBLOCK_BINDSLOTS));
|
|
|
SOKOL_ASSERT(data && data->ptr && (data->size > 0));
|
|
|
_sg_stats_add(num_apply_uniforms, 1);
|