Browse Source

Metal: Invalidate PSO when program is destroyed. Issue #1585.

Branimir Karadžić 7 years ago
parent
commit
11729403f4
2 changed files with 32 additions and 8 deletions
  1. 7 7
      src/renderer_mtl.h
  2. 25 1
      src/renderer_mtl.mm

+ 7 - 7
src/renderer_mtl.h

@@ -778,6 +778,13 @@ namespace bgfx { namespace mtl
 		uint32_t m_hash;
 	};
 
+	struct SamplerInfo
+	{
+		uint32_t      m_index;
+		UniformHandle m_uniform;
+		bool          m_fragment;
+	};
+
 	struct ProgramMtl
 	{
 		ProgramMtl()
@@ -812,13 +819,6 @@ namespace bgfx { namespace mtl
 		uint32_t m_fshConstantBufferSize;
 		uint32_t m_fshConstantBufferAlignmentMask;
 
-		struct SamplerInfo
-		{
-			uint32_t			m_index;
-			bgfx::UniformHandle m_uniform;
-			bool				m_fragment;
-		};
-
 		SamplerInfo m_samplers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
 		uint32_t	m_samplerCount;
 

+ 25 - 1
src/renderer_mtl.mm

@@ -634,6 +634,7 @@ namespace bgfx { namespace mtl
 			m_gpuTimer.shutdown();
 
 			m_pipelineStateCache.invalidate();
+			m_pipelineProgram.clear();
 
 			for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii)
 			{
@@ -763,6 +764,19 @@ namespace bgfx { namespace mtl
 
 		void destroyProgram(ProgramHandle _handle) override
 		{
+			for (PipelineProgramArray::iterator it = m_pipelineProgram.begin(); it != m_pipelineProgram.end();)
+			{
+				if (it->program.idx == _handle.idx)
+				{
+					m_pipelineStateCache.invalidate(it->key);
+					it = m_pipelineProgram.erase(it);
+				}
+				else
+				{
+					++it;
+				}
+			}
+
 			m_program[_handle.idx].destroy();
 		}
 
@@ -2041,6 +2055,7 @@ namespace bgfx { namespace mtl
 				}
 
 				m_pipelineStateCache.add(hash, pso);
+				m_pipelineProgram.push_back({hash, _program});
 			}
 
 			return pso;
@@ -2161,6 +2176,15 @@ namespace bgfx { namespace mtl
 		UniformRegistry m_uniformReg;
 		void*           m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
 
+		struct PipelineProgram
+		{
+			uint64_t      key;
+			ProgramHandle program;
+		};
+
+		typedef stl::vector<PipelineProgram> PipelineProgramArray;
+
+		PipelineProgramArray             m_pipelineProgram;
 		StateCacheT<RenderPipelineState> m_pipelineStateCache;
 		StateCacheT<DepthStencilState>   m_depthStencilStateCache;
 		StateCacheT<SamplerState>        m_samplerStateCache;
@@ -3991,7 +4015,7 @@ namespace bgfx { namespace mtl
 
 					for (uint32_t sampler = 0; sampler < program.m_samplerCount; ++sampler)
 					{
-						ProgramMtl::SamplerInfo& samplerInfo = program.m_samplers[sampler];
+						SamplerInfo& samplerInfo = program.m_samplers[sampler];
 
 						UniformHandle handle = samplerInfo.m_uniform;
 						int stage = *((int*)m_uniforms[handle.idx]);