Ver código fonte

D3D12: Cleanup.

Branimir Karadžić 10 anos atrás
pai
commit
d960217e9b
3 arquivos alterados com 164 adições e 156 exclusões
  1. 1 1
      src/bgfx_p.h
  2. 162 145
      src/renderer_d3d12.cpp
  3. 1 10
      src/renderer_d3d12.h

+ 1 - 1
src/bgfx_p.h

@@ -1404,7 +1404,7 @@ namespace bgfx
 		{
 			Binding& bind = m_draw.m_bind[_stage];
 			bind.m_idx    = _handle.idx;
-			bind.m_type   = Binding::Texture;
+			bind.m_type   = uint8_t(Binding::Texture);
 			bind.m_un.m_draw.m_flags = (_flags&BGFX_SAMPLER_DEFAULT_FLAGS)
 				? BGFX_SAMPLER_DEFAULT_FLAGS
 				: _flags

+ 162 - 145
src/renderer_d3d12.cpp

@@ -1019,10 +1019,10 @@ namespace bgfx { namespace d3d12
 
 		void shutdown()
 		{
-			preReset();
-
 			m_batch.destroy();
 
+			preReset();
+
 			m_samplerAllocator.destroy();
 
 			for (uint32_t ii = 0; ii < BX_COUNTOF(m_scratchBuffer); ++ii)
@@ -1417,7 +1417,6 @@ namespace bgfx { namespace d3d12
 				| BGFX_STATE_DEPTH_TEST_ALWAYS
 				;
 
-			m_currentProgram = &m_program[0];
 			ID3D12PipelineState* pso = getPipelineState(state
 				, packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT)
 				, _blitter.m_vb->decl.idx
@@ -1435,7 +1434,7 @@ namespace bgfx { namespace d3d12
 			setShaderUniform(flags, predefined.m_loc, proj, 4);
 
 			D3D12_GPU_VIRTUAL_ADDRESS gpuAddress;
-			commitShaderConstants(gpuAddress);
+			commitShaderConstants(_blitter.m_program.idx, gpuAddress);
 
 			ScratchBufferD3D12& scratchBuffer = m_scratchBuffer[m_backBufferColorIdx];
 			ID3D12DescriptorHeap* heaps[] =
@@ -1683,26 +1682,27 @@ data.NumQualityLevels = 0;
 			setShaderUniform(_flags, _regIndex, _val, _numRegs);
 		}
 
-		void commitShaderConstants(D3D12_GPU_VIRTUAL_ADDRESS& _gpuAddress)
+		void commitShaderConstants(uint16_t _programIdx, D3D12_GPU_VIRTUAL_ADDRESS& _gpuAddress)
 		{
+			ProgramD3D12& program = m_program[_programIdx];
 			uint32_t total = bx::strideAlign(0
-				+ m_currentProgram->m_vsh->m_size
-				+ (NULL != m_currentProgram->m_fsh ? m_currentProgram->m_fsh->m_size : 0)
+				+ program.m_vsh->m_size
+				+ (NULL != program.m_fsh ? program.m_fsh->m_size : 0)
 				, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT
 				);
 			uint8_t* data = (uint8_t*)m_scratchBuffer[m_backBufferColorIdx].allocCbv(_gpuAddress, total);
 
 			{
-				uint32_t size = m_currentProgram->m_vsh->m_size;
+				uint32_t size = program.m_vsh->m_size;
 				memcpy(data, m_vsScratch, size);
 				data += size;
 
 				m_vsChanges = 0;
 			}
 
-			if (NULL != m_currentProgram->m_fsh)
+			if (NULL != program.m_fsh)
 			{
-				memcpy(data, m_fsScratch, m_currentProgram->m_fsh->m_size);
+				memcpy(data, m_fsScratch, program.m_fsh->m_size);
 
 				m_fsChanges = 0;
 			}
@@ -1995,7 +1995,7 @@ data.NumQualityLevels = 0;
 
 			ID3D12PipelineState* pso = m_pipelineStateCache.find(hash);
 
-			if(NULL != pso)
+			if (BX_LIKELY(NULL != pso) )
 			{
 				return pso;
 			}
@@ -2196,12 +2196,9 @@ data.NumQualityLevels = 0;
 				cachedData = BX_ALLOC(g_allocator, length);
 				if (g_callback->cacheRead(hash, cachedData, length) )
 				{
-					BX_TRACE("Loading chached PSO (size %d).", length);
+					BX_TRACE("Loading cached PSO (size %d).", length);
 					bx::MemoryReader reader(cachedData, length);
 
-// 					uint32_t format;
-// 					bx::read(&reader, format);
-
 					desc.CachedPSO.pCachedBlob           = reader.getDataPtr();
 					desc.CachedPSO.CachedBlobSizeInBytes = (size_t)reader.remaining();
 
@@ -2404,10 +2401,8 @@ data.NumQualityLevels = 0;
 			}
 		}
 
-		void clearQuad(ClearQuad& _clearQuad, const Rect& _rect, const Clear& _clear, const float _palette[][4])
+		void clearQuad(const Rect& _rect, const Clear& _clear, const float _palette[][4])
 		{
-			BX_UNUSED(_clearQuad);
-
 			uint32_t width  = m_scd.BufferDesc.Width;
 			uint32_t height = m_scd.BufferDesc.Height;
 
@@ -2512,7 +2507,6 @@ data.NumQualityLevels = 0;
 
 		TextVideoMem m_textVideoMem;
 
-		ProgramD3D12* m_currentProgram;
 		uint8_t m_fsScratch[64<<10];
 		uint8_t m_vsScratch[64<<10];
 		uint32_t m_fsChanges;
@@ -2605,7 +2599,7 @@ data.NumQualityLevels = 0;
 		return data;
 	}
 
-	void ScratchBufferD3D12::allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& gpuHandle, TextureD3D12& _texture, uint8_t _mip)
+	void ScratchBufferD3D12::allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, TextureD3D12& _texture, uint8_t _mip)
 	{
 		ID3D12Device* device = s_renderD3D12->m_device;
 
@@ -2646,11 +2640,11 @@ data.NumQualityLevels = 0;
 			);
 		m_cpuHandle.ptr += m_incrementSize;
 
-		gpuHandle = m_gpuHandle;
+		_gpuHandle = m_gpuHandle;
 		m_gpuHandle.ptr += m_incrementSize;
 	}
 
-	void ScratchBufferD3D12::allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& gpuHandle, TextureD3D12& _texture, uint8_t _mip)
+	void ScratchBufferD3D12::allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, TextureD3D12& _texture, uint8_t _mip)
 	{
 		ID3D12Device* device = s_renderD3D12->m_device;
 
@@ -2682,11 +2676,11 @@ data.NumQualityLevels = 0;
 			);
 		m_cpuHandle.ptr += m_incrementSize;
 
-		gpuHandle = m_gpuHandle;
+		_gpuHandle = m_gpuHandle;
 		m_gpuHandle.ptr += m_incrementSize;
 	}
 
-	void ScratchBufferD3D12::allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& gpuHandle, BufferD3D12& _buffer)
+	void ScratchBufferD3D12::allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, BufferD3D12& _buffer)
 	{
 		ID3D12Device* device = s_renderD3D12->m_device;
 		device->CreateShaderResourceView(_buffer.m_ptr
@@ -2695,11 +2689,11 @@ data.NumQualityLevels = 0;
 			);
 		m_cpuHandle.ptr += m_incrementSize;
 
-		gpuHandle = m_gpuHandle;
+		_gpuHandle = m_gpuHandle;
 		m_gpuHandle.ptr += m_incrementSize;
 	}
 
-	void ScratchBufferD3D12::allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& gpuHandle, BufferD3D12& _buffer)
+	void ScratchBufferD3D12::allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, BufferD3D12& _buffer)
 	{
 		ID3D12Device* device = s_renderD3D12->m_device;
 		device->CreateUnorderedAccessView(_buffer.m_ptr
@@ -2709,7 +2703,7 @@ data.NumQualityLevels = 0;
 			);
 		m_cpuHandle.ptr += m_incrementSize;
 
-		gpuHandle = m_gpuHandle;
+		_gpuHandle = m_gpuHandle;
 		m_gpuHandle.ptr += m_incrementSize;
 	}
 
@@ -3055,7 +3049,9 @@ data.NumQualityLevels = 0;
 	{
 		Enum type = Enum(!!isValid(_draw.m_indexBuffer) );
 
-		const VertexBufferD3D12& vb = s_renderD3D12->m_vertexBuffers[_draw.m_vertexBuffer.idx];
+		VertexBufferD3D12& vb = s_renderD3D12->m_vertexBuffers[_draw.m_vertexBuffer.idx];
+		vb.setState(_commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
+
 		uint16_t declIdx = !isValid(vb.m_decl) ? _draw.m_vertexDecl.idx : vb.m_decl.idx;
 		const VertexDecl& vertexDecl = s_renderD3D12->m_vertexDecls[declIdx];
 		uint32_t numIndices = 0;
@@ -3081,7 +3077,7 @@ data.NumQualityLevels = 0;
 			}
 			else
 			{
-				cmd.vbv[1].BufferLocation = 0;
+				memset(&cmd.vbv[1], 0, sizeof(cmd.vbv[1]) );
 			}
 			cmd.draw.InstanceCount = _draw.m_numInstances;
 			cmd.draw.VertexCountPerInstance = numVertices;
@@ -3090,7 +3086,9 @@ data.NumQualityLevels = 0;
 		}
 		else
 		{
-			const BufferD3D12& ib = s_renderD3D12->m_indexBuffers[_draw.m_indexBuffer.idx];
+			BufferD3D12& ib = s_renderD3D12->m_indexBuffers[_draw.m_indexBuffer.idx];
+			ib.setState(_commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
+
 			const bool hasIndex16 = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32);
 			const uint32_t indexSize = hasIndex16 ? 2 : 4;
 
@@ -3119,7 +3117,7 @@ data.NumQualityLevels = 0;
 			}
 			else
 			{
-				cmd.vbv[1].BufferLocation = 0;
+				memset(&cmd.vbv[1], 0, sizeof(cmd.vbv[1]) );
 			}
 			cmd.drawIndexed.IndexCountPerInstance = numIndices;
 			cmd.drawIndexed.InstanceCount = _draw.m_numInstances;
@@ -3187,10 +3185,14 @@ data.NumQualityLevels = 0;
 						if (0 != memcmp(m_current.vbv, cmd.vbv, sizeof(cmd.vbv) ) )
 						{
 							memcpy(m_current.vbv, cmd.vbv, sizeof(cmd.vbv) );
-							_commandList->IASetVertexBuffers(0, 2, cmd.vbv);
+							_commandList->IASetVertexBuffers(0
+								, 0 == cmd.vbv[1].BufferLocation ? 1 : 2
+								, cmd.vbv
+								);
 						}
 
-						_commandList->DrawInstanced(cmd.draw.VertexCountPerInstance
+						_commandList->DrawInstanced(
+							  cmd.draw.VertexCountPerInstance
 							, cmd.draw.InstanceCount
 							, cmd.draw.StartVertexLocation
 							, cmd.draw.StartInstanceLocation
@@ -3225,7 +3227,8 @@ data.NumQualityLevels = 0;
 							_commandList->IASetIndexBuffer(&cmd.ibv);
 						}
 
-						_commandList->DrawIndexedInstanced(cmd.drawIndexed.IndexCountPerInstance
+						_commandList->DrawIndexedInstanced(
+							  cmd.drawIndexed.IndexCountPerInstance
 							, cmd.drawIndexed.InstanceCount
 							, cmd.drawIndexed.StartIndexLocation
 							, cmd.drawIndexed.BaseVertexLocation
@@ -3285,7 +3288,6 @@ data.NumQualityLevels = 0;
 		m_flags   = _flags;
 
 		const bool needUav = 0 != (_flags & (BGFX_BUFFER_COMPUTE_WRITE|BGFX_BUFFER_DRAW_INDIRECT) );
-//		const bool needSrv = 0 != (_flags & BGFX_BUFFER_COMPUTE_READ);
 		const bool drawIndirect = 0 != (_flags & BGFX_BUFFER_DRAW_INDIRECT);
 		m_dynamic = NULL == _data || needUav;
 
@@ -3297,7 +3299,7 @@ data.NumQualityLevels = 0;
 			: D3D12_RESOURCE_FLAG_NONE
 			;
 
-		if(drawIndirect)
+		if (drawIndirect)
 		{
 			format = DXGI_FORMAT_R32G32B32A32_UINT;
 			stride = 16;
@@ -3383,6 +3385,15 @@ data.NumQualityLevels = 0;
 		s_renderD3D12->m_cmd.release(staging);
 	}
 
+	void BufferD3D12::destroy()
+	{
+		if (NULL != m_ptr)
+		{
+			s_renderD3D12->m_cmd.release(m_ptr);
+			m_dynamic = false;
+		}
+	}
+
 	D3D12_RESOURCE_STATES BufferD3D12::setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state)
 	{
 		if (m_state != _state)
@@ -3894,7 +3905,7 @@ data.NumQualityLevels = 0;
 	{
 		if (NULL != m_ptr)
 		{
-			DX_RELEASE(m_ptr, 0);
+			s_renderD3D12->m_cmd.release(m_ptr);
 			m_ptr = NULL;
 		}
 	}
@@ -3955,11 +3966,6 @@ data.NumQualityLevels = 0;
 		s_renderD3D12->m_cmd.release(staging);
 	}
 
-	void TextureD3D12::commit(uint8_t _stage, uint32_t _flags)
-	{
-		BX_UNUSED(_stage, _flags);
-	}
-
 	void TextureD3D12::resolve()
 	{
 	}
@@ -4141,7 +4147,7 @@ data.NumQualityLevels = 0;
 		}
 	}
 
-	void RendererContextD3D12::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
+	void RendererContextD3D12::submit(Frame* _render, ClearQuad& /*_clearQuad*/, TextVideoMemBlitter& _textVideoMemBlitter)
 	{
 //		PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), L"rendererSubmit");
 
@@ -4179,12 +4185,12 @@ data.NumQualityLevels = 0;
 // 		setDebugWireframe(wireframe);
 
 		uint16_t currentSamplerStateIdx = invalidHandle;
+		uint16_t currentProgramIdx      = invalidHandle;
 		uint32_t currentBindHash = 0;
 		ID3D12PipelineState* currentPso = NULL;
 		SortKey key;
 		uint16_t view = UINT16_MAX;
 		FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
-		float alphaRef = 0.0f;
 		uint32_t blendFactor = 0;
 
 		const uint64_t primType = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;
@@ -4193,11 +4199,10 @@ data.NumQualityLevels = 0;
 
 		bool wasCompute = false;
 		bool viewHasScissor = false;
+		bool restoreScissor = false;
 		Rect viewScissorRect;
 		viewScissorRect.clear();
 
-		BX_UNUSED(alphaRef);
-
 		uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {};
 		uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {};
 		uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {};
@@ -4251,6 +4256,8 @@ data.NumQualityLevels = 0;
 
 					view = key.m_view;
 					currentPso = NULL;
+					currentSamplerStateIdx = invalidHandle;
+					currentProgramIdx      = invalidHandle;
 
 					fbh = _render->m_fb[view];
 					setFrameBuffer(fbh);
@@ -4276,13 +4283,14 @@ data.NumQualityLevels = 0;
 					rc.right  = viewScissorRect.m_x + viewScissorRect.m_width;
 					rc.bottom = viewScissorRect.m_y + viewScissorRect.m_height;
 					m_commandList->RSSetScissorRects(1, &rc);
+					restoreScissor = false;
 
 					Clear& clr = _render->m_clear[view];
 					if (BGFX_CLEAR_NONE != clr.m_flags)
 					{
 						Rect clearRect = rect;
 						clearRect.intersect(rect, viewScissorRect);
-						clearQuad(_clearQuad, clearRect, clr, _render->m_clearColor);
+						clearQuad(clearRect, clr, _render->m_clearColor);
 					}
 
 					prim = s_primInfo[BX_COUNTOF(s_primName)]; // Force primitive type update.
@@ -4302,34 +4310,9 @@ data.NumQualityLevels = 0;
 						m_commandList->SetDescriptorHeaps(BX_COUNTOF(heaps), heaps);
 					}
 
+#if 0
 					const RenderCompute& compute = renderItem.compute;
 
-					bool constantsChanged = compute.m_constBegin < compute.m_constEnd;
-					rendererUpdateUniforms(this, _render->m_constantBuffer, compute.m_constBegin, compute.m_constEnd);
-
-					{
-						ProgramD3D12& program = m_program[key.m_program];
-						m_currentProgram = &program;
-
-						if (constantsChanged)
-						{
-							ConstantBuffer* vcb = program.m_vsh->m_constantBuffer;
-							if (NULL != vcb)
-							{
-								commit(*vcb);
-							}
-						}
-
-						viewState.setPredefined<4>(this, view, 0, program, _render, compute);
-
-						constantsChanged |= program.m_numPredefined > 0;
-
-						if (constantsChanged)
-						{
-							commitShaderConstants(gpuAddress);
-						}
-					}
-
 					ID3D12PipelineState* pso = getPipelineState(key.m_program);
 					if (pso != currentPso)
 					{
@@ -4338,59 +4321,101 @@ data.NumQualityLevels = 0;
 						currentBindHash = 0;
 					}
 
-					D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_MAX_COMPUTE_BINDINGS] = {};
-					uint32_t samplerFlags[BGFX_MAX_COMPUTE_BINDINGS] = {};
-
-					for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii)
+					uint32_t bindHash = bx::hashMurmur2A(compute.m_bind, sizeof(compute.m_bind) );
+					if (currentBindHash != bindHash)
 					{
-						const Binding& bind = compute.m_bind[ii];
-						if (invalidHandle != bind.m_idx)
+						currentBindHash  = bindHash;
+
+						D3D12_GPU_DESCRIPTOR_HANDLE* srv = bindLru.find(bindHash);
+						if (NULL == srv)
 						{
-							switch (bind.m_type)
+							D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_MAX_COMPUTE_BINDINGS] = {};
+							uint32_t samplerFlags[BGFX_MAX_COMPUTE_BINDINGS] = {};
+
+							for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii)
 							{
-							case Binding::Image:
+								const Binding& bind = compute.m_bind[ii];
+								if (invalidHandle != bind.m_idx)
 								{
-									TextureD3D12& texture = m_textures[bind.m_idx];
-
-									if (Access::Read != bind.m_un.m_compute.m_access)
+									switch (bind.m_type)
 									{
-										scratchBuffer.allocUav(srvHandle[ii], texture, bind.m_un.m_compute.m_mip);
-									}
-									else
-									{
-										scratchBuffer.allocSrv(srvHandle[ii], texture, bind.m_un.m_compute.m_mip);
-										samplerFlags[ii] = texture.m_flags;
+									case Binding::Image:
+										{
+											TextureD3D12& texture = m_textures[bind.m_idx];
+
+											if (Access::Read != bind.m_un.m_compute.m_access)
+											{
+												texture.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
+												scratchBuffer.allocUav(srvHandle[ii], texture, bind.m_un.m_compute.m_mip);
+											}
+											else
+											{
+												texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
+												scratchBuffer.allocSrv(srvHandle[ii], texture, bind.m_un.m_compute.m_mip);
+												samplerFlags[ii] = texture.m_flags;
+											}
+										}
+										break;
+
+									case Binding::IndexBuffer:
+									case Binding::VertexBuffer:
+										{
+											BufferD3D12& buffer = Binding::IndexBuffer == bind.m_type
+												? m_indexBuffers[bind.m_idx]
+												: m_vertexBuffers[bind.m_idx]
+												;
+
+											if (Access::Read != bind.m_un.m_compute.m_access)
+											{
+												buffer.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
+												scratchBuffer.allocUav(srvHandle[ii], buffer);
+											}
+											else
+											{
+												buffer.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
+												scratchBuffer.allocSrv(srvHandle[ii], buffer);
+											}
+										}
+										break;
 									}
 								}
-								break;
-
-							case Binding::IndexBuffer:
-							case Binding::VertexBuffer:
-								{
-									BufferD3D12& buffer = Binding::IndexBuffer == bind.m_type
-										? m_indexBuffers[bind.m_idx]
-										: m_vertexBuffers[bind.m_idx]
-										;
+							}
 
-									if (Access::Read != bind.m_un.m_compute.m_access)
-									{
-										scratchBuffer.allocUav(srvHandle[ii], buffer);
-									}
-									else
-									{
-										scratchBuffer.allocSrv(srvHandle[ii], buffer);
-									}
-								}
-								break;
+							uint16_t samplerStateIdx = getSamplerState(samplerFlags, BGFX_MAX_COMPUTE_BINDINGS);
+							if (samplerStateIdx != currentSamplerStateIdx)
+							{
+								currentSamplerStateIdx = samplerStateIdx;
+								m_commandList->SetComputeRootDescriptorTable(Rdt::Sampler, m_samplerAllocator.get(samplerStateIdx) );
 							}
+
+							m_commandList->SetComputeRootDescriptorTable(Rdt::SRV, srvHandle[0]);
+							m_commandList->SetComputeRootDescriptorTable(Rdt::UAV, srvHandle[0]);
+						}
+						else
+						{
+							m_commandList->SetComputeRootDescriptorTable(Rdt::SRV, *srv);
+							m_commandList->SetComputeRootDescriptorTable(Rdt::UAV, *srv);
 						}
 					}
 
-					uint16_t samplerStateIdx = getSamplerState(samplerFlags, BGFX_MAX_COMPUTE_BINDINGS);
-					m_commandList->SetComputeRootDescriptorTable(Rdt::Sampler, m_samplerAllocator.get(samplerStateIdx) );
-					m_commandList->SetComputeRootDescriptorTable(Rdt::SRV, srvHandle[0]);
-					m_commandList->SetComputeRootDescriptorTable(Rdt::UAV, srvHandle[0]);
-					m_commandList->SetComputeRootConstantBufferView(Rdt::CBV, gpuAddress);
+					if (compute.m_constBegin < compute.m_constEnd
+					||  currentProgramIdx != key.m_program)
+					{
+						rendererUpdateUniforms(this, _render->m_constantBuffer, compute.m_constBegin, compute.m_constEnd);
+
+						currentProgramIdx = key.m_program;
+						ProgramD3D12& program = m_program[key.m_program];
+
+						ConstantBuffer* vcb = program.m_vsh->m_constantBuffer;
+						if (NULL != vcb)
+						{
+							commit(*vcb);
+						}
+
+						viewState.setPredefined<4>(this, view, 0, program, _render, compute);
+						commitShaderConstants(key.m_program, gpuAddress);
+						m_commandList->SetComputeRootConstantBufferView(Rdt::CBV, gpuAddress);
+					}
 
 					if (isValid(compute.m_indirectBuffer) )
 					{
@@ -4404,7 +4429,7 @@ data.NumQualityLevels = 0;
 						uint32_t args = compute.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
 						for (uint32_t ii = 0; ii < numDrawIndirect; ++ii)
 						{
-//							deviceCtx->DispatchIndirect(ptr, args);
+//							m_commandList->ExecuteIndirect(ptr, args);
 							args += BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
 						}
 					}
@@ -4412,7 +4437,7 @@ data.NumQualityLevels = 0;
 					{
 						m_commandList->Dispatch(compute.m_numX, compute.m_numY, compute.m_numZ);
 					}
-
+#endif // 0
 					continue;
 				}
 
@@ -4444,8 +4469,8 @@ data.NumQualityLevels = 0;
 // 						PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), viewNameW);
 					}
 
-					m_currentProgram = NULL;
 					currentSamplerStateIdx = invalidHandle;
+					currentProgramIdx      = invalidHandle;
 
 					m_commandList->SetGraphicsRootSignature(m_rootSignature);
 					ID3D12DescriptorHeap* heaps[] = {
@@ -4465,9 +4490,6 @@ data.NumQualityLevels = 0;
 					primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
 				}
 
-				bool constantsChanged = draw.m_constBegin < draw.m_constEnd;
-				rendererUpdateUniforms(this, _render->m_constantBuffer, draw.m_constBegin, draw.m_constEnd);
-
 				if (isValid(draw.m_vertexBuffer) )
 				{
 					const uint64_t state = draw.m_flags;
@@ -4586,10 +4608,12 @@ data.NumQualityLevels = 0;
 					{
 						currentState.m_scissor = scissor;
 
-						if(UINT16_MAX == scissor)
+						if (UINT16_MAX == scissor)
 						{
-							if(viewHasScissor)
+							if (restoreScissor
+							||  viewHasScissor)
 							{
+								restoreScissor = false;
 								D3D12_RECT rc;
 								rc.left   = viewScissorRect.m_x;
 								rc.top    = viewScissorRect.m_y;
@@ -4600,6 +4624,7 @@ data.NumQualityLevels = 0;
 						}
 						else
 						{
+							restoreScissor = true;
 							Rect scissorRect;
 							scissorRect.intersect(viewScissorRect,_render->m_rectCache.m_cache[scissor]);
 							D3D12_RECT rc;
@@ -4617,39 +4642,31 @@ data.NumQualityLevels = 0;
 						m_commandList->SetPipelineState(pso);
 					}
 
+					if (draw.m_constBegin < draw.m_constEnd
+					||  currentProgramIdx != key.m_program
+					||  BGFX_STATE_ALPHA_REF_MASK & changedFlags)
 					{
+						rendererUpdateUniforms(this, _render->m_constantBuffer, draw.m_constBegin, draw.m_constEnd);
+
+						currentProgramIdx = key.m_program;
 						ProgramD3D12& program = m_program[key.m_program];
-						m_currentProgram = &program;
 
-						if (constantsChanged)
+						ConstantBuffer* vcb = program.m_vsh->m_constantBuffer;
+						if (NULL != vcb)
 						{
-							ConstantBuffer* vcb = program.m_vsh->m_constantBuffer;
-							if (NULL != vcb)
-							{
-								commit(*vcb);
-							}
-
-							ConstantBuffer* fcb = program.m_fsh->m_constantBuffer;
-							if (NULL != fcb)
-							{
-								commit(*fcb);
-							}
+							commit(*vcb);
 						}
 
-						if (BGFX_STATE_ALPHA_REF_MASK & changedFlags)
+						ConstantBuffer* fcb = program.m_fsh->m_constantBuffer;
+						if (NULL != fcb)
 						{
-							uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT;
-							viewState.m_alphaRef = ref/255.0f;
+							commit(*fcb);
 						}
 
+						uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT;
+						viewState.m_alphaRef = ref/255.0f;
 						viewState.setPredefined<4>(this, view, 0, program, _render, draw);
-
-						constantsChanged |= program.m_numPredefined > 0;
-
-						if (constantsChanged)
-						{
-							commitShaderConstants(gpuAddress);
-						}
+						commitShaderConstants(key.m_program, gpuAddress);
 					}
 
 					uint32_t numIndices        = m_batch.draw(m_commandList, gpuAddress, draw);

+ 1 - 10
src/renderer_d3d12.h

@@ -140,15 +140,7 @@ namespace bgfx { namespace d3d12
 
 		void create(uint32_t _size, void* _data, uint16_t _flags, bool _vertex, uint32_t _stride = 0);
 		void update(ID3D12GraphicsCommandList* _commandList, uint32_t _offset, uint32_t _size, void* _data, bool _discard = false);
-
-		void destroy()
-		{
-			if (NULL != m_ptr)
-			{
-				DX_RELEASE(m_ptr, 0);
-				m_dynamic = false;
-			}
-		}
+		void destroy();
 
 		D3D12_RESOURCE_STATES setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);
 
@@ -272,7 +264,6 @@ namespace bgfx { namespace d3d12
 		void create(const Memory* _mem, uint32_t _flags, uint8_t _skip);
 		void destroy();
 		void update(ID3D12GraphicsCommandList* _commandList, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
-		void commit(uint8_t _stage, uint32_t _flags = BGFX_SAMPLER_DEFAULT_FLAGS);
 		void resolve();
 		D3D12_RESOURCE_STATES setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);