2
0
Эх сурвалжийг харах

Simplify SPIRV bindings shifts (shaderc bin version 11) (#2487)

Hugo Amnov 4 жил өмнө
parent
commit
ec36cf9872

+ 16 - 4
src/renderer_vk.cpp

@@ -7,6 +7,7 @@
 
 #if BGFX_CONFIG_RENDERER_VULKAN
 #	include "renderer_vk.h"
+#	include "shader_spirv.h"
 
 #if BX_PLATFORM_OSX
 #	import <Cocoa/Cocoa.h>
@@ -4373,6 +4374,8 @@ VK_DESTROY
 		m_numUniforms = count;
 		m_numTextures = 0;
 
+		m_oldBindingModel = isShaderVerLess(magic, 11);
+
 		BX_TRACE("%s Shader consts %d"
 			, getShaderTypeName(magic)
 			, count
@@ -4466,7 +4469,12 @@ VK_DESTROY
 						{
 							continue;
 						}
-						const uint16_t stage = regIndex - (isBuffer ? 16 : 32) - (fragment ? 48 : 0);  // regIndex is used for buffer binding index
+
+						const uint8_t reverseShift = m_oldBindingModel
+							? (fragment ? kSpirvOldFragmentShift : 0) + (isBuffer ? kSpirvOldBufferShift : kSpirvOldImageShift)
+							: kSpirvBindShift;
+
+						const uint16_t stage = regIndex - reverseShift; // regIndex is used for buffer binding index
 
 						m_bindInfo[stage].type = isBuffer ? BindType::Buffer : BindType::Image;
 						m_bindInfo[stage].uniformHandle  = { 0 };
@@ -4491,7 +4499,11 @@ VK_DESTROY
 					}
 					else if (UniformType::Sampler == (~kUniformMask & type) )
 					{
-						const uint16_t stage = regIndex - 16 - (fragment ? 48 : 0); // regIndex is used for image/sampler binding index
+						const uint8_t reverseShift = m_oldBindingModel
+							? (fragment ? kSpirvOldFragmentShift : 0) + kSpirvOldTextureShift
+							: kSpirvBindShift;
+
+						const uint16_t stage = regIndex - reverseShift; // regIndex is used for image/sampler binding index
 
 						const UniformRegInfo* info = s_renderVK->m_uniformReg.find(name);
 						BX_ASSERT(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name);
@@ -4499,7 +4511,7 @@ VK_DESTROY
 						m_bindInfo[stage].uniformHandle    = info->m_handle;
 						m_bindInfo[stage].type             = BindType::Sampler;
 						m_bindInfo[stage].binding          = regIndex;
-						m_bindInfo[stage].samplerBinding   = regIndex + 16;
+						m_bindInfo[stage].samplerBinding   = regIndex + kSpirvSamplerShift;
 
 						const VkImageViewType viewType = hasTexData
 							? textureDimensionToViewType(idToTextureDimension(texDimension) )
@@ -4611,7 +4623,7 @@ VK_DESTROY
 		uint16_t bidx = 0;
 		if (m_size > 0)
 		{
-			m_uniformBinding = fragment ? 48 : 0;
+			m_uniformBinding = fragment ? (m_oldBindingModel ? kSpirvOldFragmentBinding : kSpirvFragmentBinding) : 0;
 
 			VkDescriptorSetLayoutBinding& binding = m_bindings[bidx];
 			binding.stageFlags = VK_SHADER_STAGE_ALL;

+ 3 - 0
src/renderer_vk.h

@@ -466,6 +466,7 @@ VK_DESTROY_FUNC(SurfaceKHR);
 			, m_numPredefined(0)
 			, m_uniformBinding(0)
 			, m_numBindings(0)
+			, m_oldBindingModel(false)
 		{
 		}
 
@@ -494,6 +495,8 @@ VK_DESTROY_FUNC(SurfaceKHR);
 		uint32_t m_uniformBinding;
 		uint16_t m_numBindings;
 		VkDescriptorSetLayoutBinding m_bindings[32];
+
+		bool m_oldBindingModel;
 	};
 
 	struct ProgramVK

+ 19 - 8
src/renderer_webgpu.cpp

@@ -13,6 +13,7 @@
 #	include "renderer.h"
 #	include "debug_renderdoc.h"
 #	include "emscripten.h"
+#	include "shader_spirv.h"
 
 #	if BX_PLATFORM_ANDROID
 #		define VK_USE_PLATFORM_ANDROID_KHR
@@ -1317,7 +1318,7 @@ namespace bgfx { namespace webgpu
 			// first two bindings are always uniform buffer (vertex/fragment)
 			if (0 < program.m_vsh->m_gpuSize)
 			{
-				bindings.m_entries[0].binding = 0;
+				bindings.m_entries[0].binding = kSpirvVertexBinding;
 				bindings.m_entries[0].offset = 0;
 				bindings.m_entries[0].size = program.m_vsh->m_gpuSize;
 				bindings.m_entries[0].buffer = scratchBuffer.m_buffer;
@@ -1327,7 +1328,7 @@ namespace bgfx { namespace webgpu
 			if (NULL != program.m_fsh
 			&& 0 < program.m_fsh->m_gpuSize)
 			{
-				bindings.m_entries[1].binding = 48;
+				bindings.m_entries[1].binding = program.m_fsh->m_oldBindingModel ? kSpirvOldFragmentBinding : kSpirvFragmentBinding;
 				bindings.m_entries[1].offset = 0;
 				bindings.m_entries[1].size = program.m_fsh->m_gpuSize;
 				bindings.m_entries[1].buffer = scratchBuffer.m_buffer;
@@ -1406,7 +1407,7 @@ namespace bgfx { namespace webgpu
 							textureEntry.textureView = texture.m_ptr.CreateView(&viewDesc);
 
 							wgpu::BindGroupEntry& samplerEntry = b.m_entries[b.numEntries++];
-							samplerEntry.binding = bindInfo.m_binding + 16;
+							samplerEntry.binding = bindInfo.m_binding + kSpirvSamplerShift;
 							samplerEntry.sampler = 0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & flags)
 								? getSamplerState(flags)
 								: texture.m_sampler;
@@ -2514,6 +2515,8 @@ namespace bgfx { namespace webgpu
 		m_numPredefined = 0;
 		m_numUniforms = count;
 
+		m_oldBindingModel = isShaderVerLess(magic, 11);
+
 		BX_TRACE("%s Shader consts %d"
 			, getShaderTypeName(magic)
 			, count
@@ -2573,7 +2576,11 @@ namespace bgfx { namespace webgpu
 					const bool buffer = idToDescriptorType(regCount) == DescriptorType::StorageBuffer;
 					const bool readonly = (type & kUniformReadOnlyBit) != 0;
 
-					const uint8_t stage = regIndex - (buffer ? 16 : 32) - (fragment ? 48 : 0);
+					const uint8_t reverseShift = m_oldBindingModel
+						? (fragment ? kSpirvOldFragmentShift : 0) + (buffer ? kSpirvOldBufferShift : kSpirvOldImageShift)
+						: kSpirvBindShift;
+
+					const uint8_t stage = regIndex - reverseShift;
 
 					m_bindInfo[stage].m_index = m_numBuffers;
 					m_bindInfo[stage].m_binding = regIndex;
@@ -2607,7 +2614,11 @@ namespace bgfx { namespace webgpu
 					const UniformRegInfo* info = s_renderWgpu->m_uniformReg.find(name);
 					BX_ASSERT(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name);
 
-					const uint8_t stage = regIndex - 16 - (fragment ? 48 : 0);
+					const uint8_t reverseShift = m_oldBindingModel
+						? (fragment ? kSpirvOldFragmentShift : 0) + kSpirvOldTextureShift
+						: kSpirvBindShift;
+
+					const uint8_t stage = regIndex - reverseShift;
 
 					m_bindInfo[stage].m_index = m_numSamplers;
 					m_bindInfo[stage].m_binding = regIndex;
@@ -2647,7 +2658,7 @@ namespace bgfx { namespace webgpu
 					const bool comparisonSampler = (type & kUniformCompareBit) != 0;
 
 					m_samplers[m_numSamplers] = wgpu::BindGroupLayoutEntry();
-					m_samplers[m_numSamplers].binding = regIndex + 16;
+					m_samplers[m_numSamplers].binding = regIndex + kSpirvSamplerShift;
 					m_samplers[m_numSamplers].visibility = shaderStage;
 					m_samplers[m_numSamplers].sampler.type = comparisonSampler
 						? wgpu::SamplerBindingType::Comparison
@@ -2817,7 +2828,7 @@ namespace bgfx { namespace webgpu
 
 		if (_vsh->m_size > 0)
 		{
-			bindings[numBindings].binding = 0;
+			bindings[numBindings].binding = kSpirvVertexBinding;
 			bindings[numBindings].visibility = _vsh->m_stage;
 			bindings[numBindings].buffer.type = wgpu::BufferBindingType::Uniform;
 			bindings[numBindings].buffer.hasDynamicOffset = true;
@@ -2826,7 +2837,7 @@ namespace bgfx { namespace webgpu
 
 		if (NULL != _fsh && _fsh->m_size > 0)
 		{
-			bindings[numBindings].binding = 48;
+			bindings[numBindings].binding = _fsh->m_oldBindingModel ? kSpirvOldFragmentBinding : kSpirvFragmentBinding;
 			bindings[numBindings].visibility = wgpu::ShaderStage::Fragment;
 			bindings[numBindings].buffer.type = wgpu::BufferBindingType::Uniform;
 			bindings[numBindings].buffer.hasDynamicOffset = true;

+ 2 - 0
src/renderer_webgpu.h

@@ -177,6 +177,8 @@ namespace bgfx { namespace webgpu
 		uint8_t                    m_numSamplers = 0;
 		wgpu::BindGroupLayoutEntry m_buffers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
 		uint32_t                   m_numBuffers = 0;
+
+		bool m_oldBindingModel = false;
 	};
 
 	struct PipelineStateWgpu;

+ 12 - 0
src/shader_spirv.h

@@ -15,6 +15,18 @@ BX_ERROR_RESULT(BGFX_SHADER_SPIRV_INVALID_INSTRUCTION, BX_MAKEFOURCC('S', 'H', 0
 
 namespace bgfx
 {
+	constexpr uint8_t kSpirvVertexBinding   = 0;
+	constexpr uint8_t kSpirvFragmentBinding = 1;
+	constexpr uint8_t kSpirvBindShift       = 2;
+	constexpr uint8_t kSpirvSamplerShift    = 16;
+
+	constexpr uint8_t kSpirvOldVertexBinding    = 0;
+	constexpr uint8_t kSpirvOldFragmentBinding  = 48;
+	constexpr uint8_t kSpirvOldFragmentShift    = 48;
+	constexpr uint8_t kSpirvOldBufferShift      = 16;
+	constexpr uint8_t kSpirvOldImageShift       = 32;
+	constexpr uint8_t kSpirvOldTextureShift     = 16;
+
 	// Reference(s):
 	// - https://web.archive.org/web/20181126035927/https://www.khronos.org/registry/spir-v/specs/1.0/SPIRV.html
 	//

+ 1 - 1
tools/shaderc/shaderc.cpp

@@ -13,7 +13,7 @@ extern "C"
 #include <fpp.h>
 } // extern "C"
 
-#define BGFX_SHADER_BIN_VERSION 10
+#define BGFX_SHADER_BIN_VERSION 11
 #define BGFX_CHUNK_MAGIC_CSH BX_MAKEFOURCC('C', 'S', 'H', BGFX_SHADER_BIN_VERSION)
 #define BGFX_CHUNK_MAGIC_FSH BX_MAKEFOURCC('F', 'S', 'H', BGFX_SHADER_BIN_VERSION)
 #define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', BGFX_SHADER_BIN_VERSION)

+ 7 - 6
tools/shaderc/shaderc_spirv.cpp

@@ -448,12 +448,13 @@ namespace bgfx { namespace spirv
 		shader->setEnvInput(glslang::EShSourceHlsl, stage, glslang::EShClientVulkan, s_GLSL_VULKAN_CLIENT_VERSION);
 		shader->setEnvClient(glslang::EShClientVulkan, getGlslangTargetVulkanVersion(_version));
 		shader->setEnvTarget(glslang::EShTargetSpv, getGlslangTargetSpirvVersion(_version));
-		uint32_t bindingOffset = (stage == EShLanguage::EShLangFragment ? 48 : 0);
-		shader->setShiftBinding(glslang::EResUbo, bindingOffset);
-		shader->setShiftBinding(glslang::EResTexture, bindingOffset + 16);
-		shader->setShiftBinding(glslang::EResSampler, bindingOffset + 32);
-		shader->setShiftBinding(glslang::EResSsbo, bindingOffset + 16);
-		shader->setShiftBinding(glslang::EResImage, bindingOffset + 32);
+
+		// Reserve two spots for the stage UBOs
+		shader->setShiftBinding(glslang::EResUbo, (stage == EShLanguage::EShLangFragment ? kSpirvFragmentBinding : kSpirvVertexBinding));
+		shader->setShiftBinding(glslang::EResTexture, kSpirvBindShift);
+		shader->setShiftBinding(glslang::EResSampler, kSpirvBindShift + kSpirvSamplerShift);
+		shader->setShiftBinding(glslang::EResSsbo, kSpirvBindShift);
+		shader->setShiftBinding(glslang::EResImage, kSpirvBindShift);
 
 		const char* shaderStrings[] = { _code.c_str() };
 		shader->setStrings(