|
@@ -4123,6 +4123,7 @@ typedef struct sg_frame_stats {
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_PIPELINEDESC_COMPUTE_SHADER_EXPECTED, "sg_pipeline_desc.shader must be a compute shader") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_PIPELINEDESC_NO_COMPUTE_SHADER_EXPECTED, "sg_pipeline_desc.compute is false, but shader is a compute shader") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_PIPELINEDESC_NO_CONT_ATTRS, "sg_pipeline_desc.layout.attrs is not continuous") \
|
|
|
+ _SG_LOGITEM_XMACRO(VALIDATE_PIPELINEDESC_ATTR_BASETYPE_MISMATCH, "sg_pipeline_desc.layout.attrs[].format is incompatble with sg_shader_desc.attrs[].base_type") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_PIPELINEDESC_LAYOUT_STRIDE4, "sg_pipeline_desc.layout.buffers[].stride must be multiple of 4") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_PIPELINEDESC_ATTR_SEMANTICS, "D3D11 missing vertex attribute semantics in shader") \
|
|
|
_SG_LOGITEM_XMACRO(VALIDATE_PIPELINEDESC_SHADER_READONLY_STORAGEBUFFERS, "sg_pipeline_desc.shader: only readonly storage buffer bindings allowed in render pipelines") \
|
|
@@ -5529,6 +5530,10 @@ _SOKOL_PRIVATE void _sg_sampler_common_init(_sg_sampler_common_t* cmn, const sg_
|
|
|
cmn->max_anisotropy = desc->max_anisotropy;
|
|
|
}
|
|
|
|
|
|
+typedef struct {
|
|
|
+ sg_shader_attr_base_type base_type;
|
|
|
+} _sg_shader_attr_t;
|
|
|
+
|
|
|
typedef struct {
|
|
|
sg_shader_stage stage;
|
|
|
uint32_t size;
|
|
@@ -5561,6 +5566,7 @@ typedef struct {
|
|
|
typedef struct {
|
|
|
uint32_t required_bindings_and_uniforms;
|
|
|
bool is_compute;
|
|
|
+ _sg_shader_attr_t attrs[SG_MAX_VERTEX_ATTRIBUTES];
|
|
|
_sg_shader_uniform_block_t uniform_blocks[SG_MAX_UNIFORMBLOCK_BINDSLOTS];
|
|
|
_sg_shader_storage_buffer_t storage_buffers[SG_MAX_STORAGEBUFFER_BINDSLOTS];
|
|
|
_sg_shader_image_t images[SG_MAX_IMAGE_BINDSLOTS];
|
|
@@ -5570,6 +5576,9 @@ typedef struct {
|
|
|
|
|
|
_SOKOL_PRIVATE void _sg_shader_common_init(_sg_shader_common_t* cmn, const sg_shader_desc* desc) {
|
|
|
cmn->is_compute = desc->compute_func.source || desc->compute_func.bytecode.ptr;
|
|
|
+ for (size_t i = 0; i < SG_MAX_VERTEX_ATTRIBUTES; i++) {
|
|
|
+ cmn->attrs[i].base_type = desc->attrs[i].base_type;
|
|
|
+ }
|
|
|
for (size_t i = 0; i < SG_MAX_UNIFORMBLOCK_BINDSLOTS; i++) {
|
|
|
const sg_shader_uniform_block* src = &desc->uniform_blocks[i];
|
|
|
_sg_shader_uniform_block_t* dst = &cmn->uniform_blocks[i];
|
|
@@ -18177,7 +18186,7 @@ _SOKOL_PRIVATE bool _sg_validate_pipeline_desc(const sg_pipeline_desc* desc) {
|
|
|
} else {
|
|
|
_SG_VALIDATE(!shd->cmn.is_compute, VALIDATE_PIPELINEDESC_NO_COMPUTE_SHADER_EXPECTED);
|
|
|
bool attrs_cont = true;
|
|
|
- for (int attr_index = 0; attr_index < SG_MAX_VERTEX_ATTRIBUTES; attr_index++) {
|
|
|
+ for (size_t attr_index = 0; attr_index < SG_MAX_VERTEX_ATTRIBUTES; attr_index++) {
|
|
|
const sg_vertex_attr_state* a_state = &desc->layout.attrs[attr_index];
|
|
|
if (a_state->format == SG_VERTEXFORMAT_INVALID) {
|
|
|
attrs_cont = false;
|
|
@@ -18185,6 +18194,8 @@ _SOKOL_PRIVATE bool _sg_validate_pipeline_desc(const sg_pipeline_desc* desc) {
|
|
|
}
|
|
|
_SG_VALIDATE(attrs_cont, VALIDATE_PIPELINEDESC_NO_CONT_ATTRS);
|
|
|
SOKOL_ASSERT(a_state->buffer_index < SG_MAX_VERTEXBUFFER_BINDSLOTS);
|
|
|
+ // vertex format must match expected shader attribute base type
|
|
|
+ _SG_VALIDATE(_sg_vertexformat_basetype(a_state->format) == shd->cmn.attrs[attr_index].base_type, VALIDATE_PIPELINEDESC_ATTR_BASETYPE_MISMATCH);
|
|
|
#if defined(SOKOL_D3D11)
|
|
|
// on D3D11, semantic names (and semantic indices) must be provided
|
|
|
_SG_VALIDATE(!_sg_strempty(&shd->d3d11.attrs[attr_index].sem_name), VALIDATE_PIPELINEDESC_ATTR_SEMANTICS);
|