// TODO can determine which uniform buffers are used in which stage based on binding index (see 'Create' in GpuProgramsVk.cpp) // if (binding.GetShaderStageFlags() != VK_SHADER_STAGE_FRAGMENT_BIT) // *only* used in fragment shader static uint SerializeUniforms(CompiledShader compiled, BinaryWriter writer) { int totalConstants = 0; foreach (var constantBuffer in compiled.constantBuffers) { totalConstants += constantBuffer.usedConstants; } writer.Write((ushort)totalConstants); int size = 0; foreach (var constantBuffer in compiled.constantBuffers) { for (int i = 0; i < constantBuffer.usedConstants; i++) { var constant = constantBuffer.constants[i]; UnityToBgfx.ConvertBuiltInUniform(constant.name, out string uniformName); writer.Write((byte)uniformName.Length); writer.Write(Encoding.UTF8.GetBytes(uniformName)); if (constant.dataType != UnityHelper.ShaderParamType.kShaderParamFloat) { throw new NotSupportedException("Only float types are supported for uniforms."); } // Data type var type = UnityToBgfx.GetBgfxUniformDataType(constant); writer.Write((byte)type); // TODO bx::write(_writer, uint8_t(un.type | fragmentBit)); // array size writer.Write((byte)constant.arraySize); // Should be 0 if not an array // regIndex - bgfx puts all constants into a single buffer writer.Write((ushort)(size + constant.idx)); // TODO // regCount var regCount = constant.arraySize; if (type == BgfxHelper.UniformType.Mat3) { regCount *= 3; } else if (type == BgfxHelper.UniformType.Mat4) { regCount *= 4; } writer.Write((ushort)regCount); // TODO this is only used in renderer_webgpu.cpp? // texComponent // texDimension // writer.Write((byte)0); // writer.Write((byte)0); } size += constantBuffer.size; } return((uint)size); }
static uint SerializeUniforms(CompiledShaderData compiled, BinaryWriter writer, Stage stage) { if (compiled.constantBuffers.Count == 0 && compiled.samplers.Count == 0) { writer.Write((ushort)0); return(0); } uint fragmentBit = stage == Stage.Fragment ? BgfxHelper.BGFX_UNIFORM_FRAGMENTBIT : 0u; var uniformsCount = compiled.samplers.Count; foreach (var constantBuffer in compiled.constantBuffers) { uniformsCount += constantBuffer.constants.Count; } writer.Write((ushort)uniformsCount); uint constantBufferSize = 0; foreach (var constantBuffer in compiled.constantBuffers) { foreach (var constant in constantBuffer.constants) { UnityToBgfx.ConvertBuiltInUniform(constant.name, out string uniformName); writer.Write((byte)uniformName.Length); writer.Write(Encoding.UTF8.GetBytes(uniformName)); if (constant.dataType != UnityHelper.ShaderParamType.kShaderParamFloat) { throw new NotSupportedException("Only float types are supported for uniforms."); } // data type var type = UnityToBgfx.GetBgfxUniformDataType(constant); writer.Write((byte)((uint)type | fragmentBit)); // array size var arraySize = Math.Max(constant.arraySize, 1); // Unity passes a 0 if not an array writer.Write((byte)arraySize); // regIndex - merge all constants into a single buffer writer.Write((ushort)(constantBufferSize + constant.idx)); // regCount var regCount = (ushort)arraySize; if (type == BgfxHelper.UniformType.Mat3) { regCount *= 3; } else if (type == BgfxHelper.UniformType.Mat4) { regCount *= 4; } writer.Write(regCount); // Unused writer.Write((byte)0); // texComponent writer.Write((byte)0); // texDimension } constantBufferSize += (uint)constantBuffer.size; } foreach (var sampler in compiled.samplers) { writer.Write((byte)sampler.name.Length); writer.Write(Encoding.UTF8.GetBytes(sampler.name)); writer.Write((byte)((ushort)BgfxHelper.UniformType.Sampler | BgfxHelper.BGFX_UNIFORM_SAMPLERBIT | fragmentBit)); // array size writer.Write((byte)0); // regIndex writer.Write((ushort)0); // regCount writer.Write((ushort)0); // texComponent writer.Write((byte)0); // texDimension writer.Write((byte)0); } return(constantBufferSize); }
static void SerializeUniforms(CompiledShaderData compiled, BinaryWriter writer, Stage stage) { if (compiled.constantBuffers.Count == 0 && compiled.samplers.Count == 0) { writer.Write((ushort)0); return; } uint fragmentBit = stage == Stage.Fragment ? BgfxHelper.BGFX_UNIFORM_FRAGMENTBIT : 0u; var uniformsCount = compiled.samplers.Count; foreach (var constantBuffer in compiled.constantBuffers) { uniformsCount += constantBuffer.constants.Count; } writer.Write((ushort)uniformsCount); foreach (var constantBuffer in compiled.constantBuffers) { foreach (var constant in constantBuffer.constants) { writer.Write((byte)constant.name.Length); writer.Write(Encoding.UTF8.GetBytes(constant.name)); if (constant.dataType != UnityHelper.ShaderParamType.kShaderParamFloat) { throw new NotSupportedException("Only float types are supported for uniforms."); } // Data type var type = UnityToBgfx.GetBgfxUniformDataType(constant); writer.Write((byte)((uint)type | fragmentBit)); // array size int arraySize = Math.Max(constant.arraySize, 1); // Unity passes a 0 if not an array writer.Write((byte)arraySize); // regIndex is not used for GL writer.Write((ushort)0); // regCount writer.Write((ushort)arraySize); // Unused writer.Write((byte)0); // texComponent writer.Write((byte)0); // texDimension } } foreach (var sampler in compiled.samplers) { writer.Write((byte)sampler.name.Length); writer.Write(Encoding.UTF8.GetBytes(sampler.name)); writer.Write((byte)((ushort)BgfxHelper.UniformType.Sampler | BgfxHelper.BGFX_UNIFORM_SAMPLERBIT | fragmentBit)); // array size int arraySize = Math.Max(sampler.arraySize, 1); writer.Write((byte)arraySize); // regIndex writer.Write((ushort)0); // regCount writer.Write((ushort)arraySize); // texComponent writer.Write((byte)0); // texDimension writer.Write((byte)0); } }
static uint SerializeUniforms(CompiledShaderData compiled, BinaryWriter writer, Stage stage) { if (compiled.constantBuffers.Count == 0 && compiled.samplers.Count == 0) { writer.Write((ushort)0); return(0); } uint fragmentBit = stage == Stage.Fragment ? BgfxHelper.BGFX_UNIFORM_FRAGMENTBIT : 0u; var uniformsCount = compiled.samplers.Count; foreach (var constantBuffer in compiled.constantBuffers) { uniformsCount += constantBuffer.constants.Count; } writer.Write((ushort)uniformsCount); uint globalConstantBufferSize = 0; foreach (var constantBuffer in compiled.constantBuffers) { uint constantBufferSize = 0; foreach (var constant in constantBuffer.constants) { UnityToBgfx.ConvertBuiltInUniform(constant.name, out string uniformName); writer.Write((byte)uniformName.Length); writer.Write(Encoding.UTF8.GetBytes(uniformName)); if (constant.dataType != UnityHelper.ShaderParamType.kShaderParamFloat) { throw new NotSupportedException("Only float types are supported for uniforms."); } // Data type uint parameterSize; var type = UnityToBgfx.GetBgfxUniformDataType(constant); writer.Write((byte)((uint)type | fragmentBit)); if (type == BgfxHelper.UniformType.Vec4) { parameterSize = 16; } else if (type == BgfxHelper.UniformType.Mat4) { parameterSize = 64; } else { // bgfx.UniformType.Mat3. Size includes padding parameterSize = 44; } // array size writer.Write((byte)constant.arraySize); // Should be 0 if not an array // regIndex - merge all constants into a single buffer writer.Write((ushort)(globalConstantBufferSize + constant.idx)); // regCount parameterSize = constant.arraySize > 0 ? parameterSize * (uint)constant.arraySize : parameterSize; parameterSize = AlignUp(parameterSize, 16); writer.Write((ushort)(parameterSize / 16)); // Unused writer.Write((byte)0); // texComponent writer.Write((byte)0); // texDimension // Actual size of this constant buffer. All unused constants after the last used constant are removed constantBufferSize = (uint)constant.idx + parameterSize; } globalConstantBufferSize += constantBufferSize; } foreach (var sampler in compiled.samplers) { writer.Write((byte)sampler.name.Length); writer.Write(Encoding.UTF8.GetBytes(sampler.name)); writer.Write((byte)((ushort)BgfxHelper.UniformType.Sampler | BgfxHelper.BGFX_UNIFORM_SAMPLERBIT | fragmentBit)); // array size writer.Write((byte)sampler.arraySize); // this will always be zero // regIndex writer.Write((ushort)sampler.register); // regCount writer.Write((ushort)1); // Unused writer.Write((byte)0); // texComponent writer.Write((byte)0); // texDimension } return(globalConstantBufferSize); }