diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index f79a2493c..c9c6b42fd 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -425,8 +425,8 @@ static const char* s_accessNames[] = { BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames count"); -#define SHADER_FUNCTION_NAME ("xlatMtlMain") -#define SHADER_UNIFORM_NAME ("_mtl_u") +#define SHADER_FUNCTION_NAME "xlatMtlMain" +#define SHADER_UNIFORM_NAME "_mtl_u" struct RendererContextMtl; static RendererContextMtl* s_renderMtl; @@ -1931,8 +1931,8 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa void processArguments( PipelineStateMtl* ps - , NSArray* _vertexArgs - , NSArray* _fragmentArgs + , NSArray>* _vertexArgs + , NSArray>* _fragmentArgs ) { ps->m_numPredefined = 0; @@ -1945,47 +1945,54 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa ; const int8_t fragmentBit = (1 == shaderType ? kUniformFragmentBit : 0); - for (MTLArgument* arg in (shaderType == 0 ? _vertexArgs : _fragmentArgs) ) + for (id arg in (shaderType == 0 ? _vertexArgs : _fragmentArgs) ) { BX_TRACE("arg: %s type:%d", utf8String(arg.name), arg.type); - if (arg.active) + if (arg.used) { - if (arg.type == MTLArgumentTypeBuffer - && 0 == bx::strCmp(utf8String(arg.name), SHADER_UNIFORM_NAME) ) + if (arg.type == MTLBindingTypeBuffer) { - BX_ASSERT(arg.index == 0, "Uniform buffer must be in the buffer slot 0."); - BX_ASSERT(MTLDataTypeStruct == arg.bufferDataType, "%s's type must be a struct",SHADER_UNIFORM_NAME ); + const id binding = (id)arg; - if (MTLDataTypeStruct == arg.bufferDataType) + if (0 == bx::strCmp(utf8String(arg.name), SHADER_UNIFORM_NAME) ) { - if (shaderType == 0) - { - ps->m_vshConstantBufferSize = uint32_t(arg.bufferDataSize); - ps->m_vshConstantBufferAlignment = uint32_t(arg.bufferAlignment); - } - else - { - ps->m_fshConstantBufferSize = uint32_t(arg.bufferDataSize); - ps->m_fshConstantBufferAlignment = uint32_t(arg.bufferAlignment); - } + BX_ASSERT(arg.index == 0, "Uniform buffer must be in the buffer slot 0."); - for (MTLStructMember* uniform in arg.bufferStructType.members ) + BX_ASSERT( + MTLDataTypeStruct == binding.bufferDataType + , SHADER_UNIFORM_NAME "'s type must be a struct" + ); + + if (MTLDataTypeStruct == binding.bufferDataType) { - const char* name = utf8String(uniform.name); - BX_TRACE("uniform: %s type:%d", name, uniform.dataType); - - MTLDataType dataType = uniform.dataType; - uint32_t num = 1; - - if (dataType == MTLDataTypeArray) + if (shaderType == 0) { - dataType = uniform.arrayType.elementType; - num = (uint32_t)uniform.arrayType.arrayLength; + ps->m_vshConstantBufferSize = uint32_t(binding.bufferDataSize); + ps->m_vshConstantBufferAlignment = uint32_t(binding.bufferAlignment); + } + else + { + ps->m_fshConstantBufferSize = uint32_t(binding.bufferDataSize); + ps->m_fshConstantBufferAlignment = uint32_t(binding.bufferAlignment); } - switch (dataType) + for (MTLStructMember* uniform in binding.bufferStructType.members ) { + const char* name = utf8String(uniform.name); + BX_TRACE("uniform: %s type:%d", name, uniform.dataType); + + MTLDataType dataType = uniform.dataType; + uint32_t num = 1; + + if (dataType == MTLDataTypeArray) + { + dataType = uniform.arrayType.elementType; + num = (uint32_t)uniform.arrayType.arrayLength; + } + + switch (dataType) + { case MTLDataTypeFloat4: num *= 1; break; case MTLDataTypeFloat4x4: num *= 4; break; case MTLDataTypeFloat3x3: num *= 3; break; @@ -1993,64 +2000,64 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa default: BX_WARN(0, "Unsupported uniform MTLDataType: %d", uniform.dataType); break; - } + } - const PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name); + const PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name); - if (PredefinedUniform::Count != predefined) - { - ps->m_predefined[ps->m_numPredefined].m_loc = uint32_t(uniform.offset); - ps->m_predefined[ps->m_numPredefined].m_count = uint16_t(num); - ps->m_predefined[ps->m_numPredefined].m_type = uint8_t(predefined|fragmentBit); - ++ps->m_numPredefined; - } - else - { - const UniformRegInfo* info = s_renderMtl->m_uniformReg.find(name); - BX_WARN(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name); - - if (NULL != info) + if (PredefinedUniform::Count != predefined) { - if (NULL == constantBuffer) - { - constantBuffer = UniformBuffer::create(1024); - } + ps->m_predefined[ps->m_numPredefined].m_loc = uint32_t(uniform.offset); + ps->m_predefined[ps->m_numPredefined].m_count = uint16_t(num); + ps->m_predefined[ps->m_numPredefined].m_type = uint8_t(predefined|fragmentBit); + ++ps->m_numPredefined; + } + else + { + const UniformRegInfo* info = s_renderMtl->m_uniformReg.find(name); + BX_WARN(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name); - UniformType::Enum type = convertMtlType(dataType); - constantBuffer->writeUniformHandle( (UniformType::Enum)(type|fragmentBit), uint32_t(uniform.offset), info->m_handle, uint16_t(num) ); - BX_TRACE("store %s %d offset:%d", name, info->m_handle, uint32_t(uniform.offset) ); + if (NULL != info) + { + if (NULL == constantBuffer) + { + constantBuffer = UniformBuffer::create(1024); + } + + UniformType::Enum type = convertMtlType(dataType); + constantBuffer->writeUniformHandle( (UniformType::Enum)(type|fragmentBit), uint32_t(uniform.offset), info->m_handle, uint16_t(num) ); + BX_TRACE("store %s %d offset:%d", name, info->m_handle, uint32_t(uniform.offset) ); + } } } } } - } - else if (arg.type == MTLArgumentTypeBuffer - && arg.index > 0 - && NULL != arg.bufferStructType) - { - const char* name = utf8String(arg.name); - BX_UNUSED(name); + else if (arg.index > 0 + && NULL != binding.bufferStructType) + { + const char* name = utf8String(arg.name); + BX_UNUSED(name); - if (arg.index >= BGFX_CONFIG_MAX_TEXTURE_SAMPLERS) - { - BX_TRACE( - "Binding index is too large %d max is %d. " - "User defined uniform '%s' won't be set." - , int32_t(arg.index - 1) - , BGFX_CONFIG_MAX_TEXTURE_SAMPLERS - 1 - , name - ); - } - else - { - ps->m_bindingTypes[arg.index-1] = fragmentBit - ? PipelineStateMtl::BindToFragmentShader - : PipelineStateMtl::BindToVertexShader - ; - BX_TRACE("Buffer %s index: %d", name, int32_t(arg.index-1) ); + if (arg.index >= BGFX_CONFIG_MAX_TEXTURE_SAMPLERS) + { + BX_TRACE( + "Binding index is too large %d max is %d. " + "User defined uniform '%s' won't be set." + , int32_t(arg.index - 1) + , BGFX_CONFIG_MAX_TEXTURE_SAMPLERS - 1 + , name + ); + } + else + { + ps->m_bindingTypes[arg.index-1] = fragmentBit + ? PipelineStateMtl::BindToFragmentShader + : PipelineStateMtl::BindToVertexShader + ; + BX_TRACE("Buffer %s index: %d", name, int32_t(arg.index-1) ); + } } } - else if (arg.type == MTLArgumentTypeTexture) + else if (arg.type == MTLBindingTypeTexture) { const char* name = utf8String(arg.name); @@ -2060,8 +2067,13 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa } else { - ps->m_bindingTypes[arg.index] = fragmentBit ? PipelineStateMtl::BindToFragmentShader : PipelineStateMtl::BindToVertexShader; + ps->m_bindingTypes[arg.index] = fragmentBit + ? PipelineStateMtl::BindToFragmentShader + : PipelineStateMtl::BindToVertexShader + ; + const UniformRegInfo* info = s_renderMtl->m_uniformReg.find(name); + if (info) { BX_TRACE("texture %s %d index:%d", name, info->m_handle, uint32_t(arg.index) ); @@ -2072,7 +2084,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa } } } - else if (arg.type == MTLArgumentTypeSampler) + else if (arg.type == MTLBindingTypeSampler) { BX_TRACE("sampler: %s index:%d", utf8String(arg.name), arg.index); }