| 749 | } |
| 750 | |
| 751 | void* Material::GetOrCreateConstantBuffer(uint8_t shaderIndex) |
| 752 | { |
| 753 | se_assert(shaderIndex < std::size(ShaderDescriptions)); |
| 754 | |
| 755 | // Fast-path for already allocated CB |
| 756 | if (MaterialCBs[shaderIndex].MaterialCB != nullptr) { |
| 757 | return MaterialCBs[shaderIndex].MaterialCB; |
| 758 | } |
| 759 | |
| 760 | AcquireSRWLockShared(&MaterialCBLock); |
| 761 | // Re-check when we have a reader lock |
| 762 | if (MaterialCBs[shaderIndex].MaterialCB != nullptr) { |
| 763 | // Concurrent thread allocated the CB |
| 764 | ReleaseSRWLockShared(&MaterialCBLock); |
| 765 | return MaterialCBs[shaderIndex].MaterialCB; |
| 766 | } |
| 767 | |
| 768 | // No CB, we need to build it ourself |
| 769 | ReleaseSRWLockShared(&MaterialCBLock); |
| 770 | AcquireSRWLockExclusive(&MaterialCBLock); |
| 771 | |
| 772 | auto size = ShaderDescriptions[shaderIndex].MaterialCBSize; |
| 773 | auto cb = (uint8_t *)GameAllocRaw(size); |
| 774 | memset(cb, 0, size); |
| 775 | |
| 776 | for (auto const& param : Parameters.ScalarParameters) { |
| 777 | if (param.Binding.PerShaderCBOffsets[shaderIndex] != -1) { |
| 778 | *(float*)(cb + param.Binding.PerShaderCBOffsets[shaderIndex]) = param.Value; |
| 779 | } |
| 780 | } |
| 781 | |
| 782 | for (auto const& param : Parameters.Vector2Parameters) { |
| 783 | if (param.Binding.PerShaderCBOffsets[shaderIndex] != -1) { |
| 784 | *(glm::vec2*)(cb + param.Binding.PerShaderCBOffsets[shaderIndex]) = param.Value; |
| 785 | } |
| 786 | } |
| 787 | |
| 788 | for (auto const& param : Parameters.Vector3Parameters) { |
| 789 | if (param.Binding.PerShaderCBOffsets[shaderIndex] != -1) { |
| 790 | *(glm::vec3*)(cb + param.Binding.PerShaderCBOffsets[shaderIndex]) = param.Value; |
| 791 | } |
| 792 | } |
| 793 | |
| 794 | for (auto const& param : Parameters.VectorParameters) { |
| 795 | if (param.Binding.PerShaderCBOffsets[shaderIndex] != -1) { |
| 796 | *(glm::vec4*)(cb + param.Binding.PerShaderCBOffsets[shaderIndex]) = param.Value; |
| 797 | } |
| 798 | } |
| 799 | |
| 800 | MaterialCBs[shaderIndex].MaterialCB = cb; |
| 801 | MaterialCBs[shaderIndex].MaterialCBSize = size; |
| 802 | |
| 803 | ReleaseSRWLockExclusive(&MaterialCBLock); |
| 804 | return cb; |
| 805 | } |
| 806 | |
| 807 | bool MaterialRenderingData::CheckConstantBuffer(Material& instance) |
| 808 | { |