Example #1
0
	/** Sets a buffer of values on the current shader instance. */
	void Shader::SetConstantBuffer(u32 index, std::shared_ptr<ConstantBufferBase> buffer)
	{
		ID3D11Buffer* bufferD3D = buffer != nullptr ? buffer->GetBuffer() : nullptr;
		ID3D11DeviceContext* context = GetParent()->GetDeviceContext();
		switch(GetType())
		{
		case ShaderType::Compute:
			context->CSSetConstantBuffers(index, 1, &bufferD3D);
			break;
		case ShaderType::Domain:
			context->DSSetConstantBuffers(index, 1, &bufferD3D);
			break;
		case ShaderType::Geometry:
			context->GSSetConstantBuffers(index, 1, &bufferD3D);
			break;
		case ShaderType::Hull:
			context->HSSetConstantBuffers(index, 1, &bufferD3D);
			break;
		case ShaderType::Pixel:
			context->PSSetConstantBuffers(index, 1, &bufferD3D);
			break;
		case ShaderType::Vertex:
			context->VSSetConstantBuffers(index, 1, &bufferD3D);
			break;
		}
	}
void BindableProgram::Bind 
 (ID3D11DeviceContext&          context,
  ShaderLibrary&                library,
  const SourceConstantBufferPtr src_buffers [DEVICE_CONSTANT_BUFFER_SLOTS_COUNT],
  const InputLayout&            input_layout,
  BindableProgramContext&       program_context)
{
  try
  {
      //поиск входного лэйаута

    if (!program_context.input_layout)
    {
      program_context.input_layout = program.GetInputLayout (library, input_layout);
   
      context.IASetInputLayout (program_context.input_layout.get ());
    }

      //биндинг программы

    if (!program_context.program_binded)
    {      
      program.Bind (context);

      program_context.program_binded = true;
    }

      //поиск и биндинг буферов
//TODO: bindable buffers cache for dirty switch optimization    
//    if (program_context.has_dirty_buffers)
    {
      ID3D11Buffer* buffers [ShaderType_Num][DEVICE_CONSTANT_BUFFER_SLOTS_COUNT];

      memset (buffers, 0, sizeof (buffers));

      for (BufferPrototypeArray::iterator iter=buffer_prototypes.begin (), end=buffer_prototypes.end (); iter!=end; ++iter)
      {
        TargetConstantBufferPrototype& prototype = **iter;

        const unsigned char* index = prototype.GetSourceBuffersIndices ();
        bool                 dirty = false;  

        for (size_t i=0, count=prototype.GetSourceBuffersCount (); i<count; i++, index++)
          if (program_context.dirty_buffers [*index])
          {
            dirty = true;
            break;
          }

//        if (!dirty)
//          continue;

        TargetConstantBuffer& buffer = prototype.GetBuffer (src_buffers, library);

        buffer.Bind (context, buffers);
      }

        //установка контекста

      context.CSSetConstantBuffers (0, DEVICE_CONSTANT_BUFFER_SLOTS_COUNT, buffers [ShaderType_Compute]);
      context.DSSetConstantBuffers (0, DEVICE_CONSTANT_BUFFER_SLOTS_COUNT, buffers [ShaderType_Domain]);
      context.GSSetConstantBuffers (0, DEVICE_CONSTANT_BUFFER_SLOTS_COUNT, buffers [ShaderType_Geometry]);
      context.HSSetConstantBuffers (0, DEVICE_CONSTANT_BUFFER_SLOTS_COUNT, buffers [ShaderType_Hull]);
      context.PSSetConstantBuffers (0, DEVICE_CONSTANT_BUFFER_SLOTS_COUNT, buffers [ShaderType_Pixel]);
      context.VSSetConstantBuffers (0, DEVICE_CONSTANT_BUFFER_SLOTS_COUNT, buffers [ShaderType_Vertex]);

      program_context.has_dirty_buffers = false;

      memset (program_context.dirty_buffers, 0, sizeof (program_context.dirty_buffers));
    }
  }
  catch (xtl::exception& e)
  {
    e.touch ("render::low_level::dx11::BindableProgram::Bind");
    throw;
  }
}
/** Binds a pipeline-state */
void D3D11GraphicsEngineQueued::BindPipelineState(const PipelineState* state)
{
	D3D11PipelineState* s = (D3D11PipelineState*)state;
	D3D11PipelineState* b = (D3D11PipelineState*)BoundPipelineStateByThread[GetCurrentThreadId()];
	ID3D11DeviceContext* context = GetDeferredContextByThread();

	if(!b) b = (D3D11PipelineState*)&DefaultPipelineState;

	// Bind state
	if(b->BlendState != s->BlendState)
		SC_DBG(context->OMSetBlendState(s->BlendState,  (float *)&D3DXVECTOR4(0, 0, 0, 0), 0xFFFFFFFF), GothicRendererInfo::SC_BS);

	if(b->SamplerState != s->SamplerState)
		SC_DBG(context->PSSetSamplers(0, 1, &s->SamplerState), GothicRendererInfo::SC_SMPL);

	if(b->DepthStencilState != s->DepthStencilState)
		SC_DBG(context->OMSetDepthStencilState(s->DepthStencilState, 0), GothicRendererInfo::SC_DSS);

	if(b->RasterizerState != s->RasterizerState)
		SC_DBG(context->RSSetState(s->RasterizerState), GothicRendererInfo::SC_RS);

	// Bind constantbuffers (They are likely to change for every object)
	if(!s->ConstantBuffersVS.empty() && s->ConstantBuffersVS != b->ConstantBuffersVS)SC_DBG(context->VSSetConstantBuffers(0, s->ConstantBuffersVS.size(), &s->ConstantBuffersVS[0]),GothicRendererInfo::SC_CB);
	if(!s->ConstantBuffersPS.empty() && s->ConstantBuffersPS != b->ConstantBuffersPS)SC_DBG(context->PSSetConstantBuffers(0, s->ConstantBuffersPS.size(), &s->ConstantBuffersPS[0]),GothicRendererInfo::SC_CB);
	if(!s->ConstantBuffersHDS.empty() && s->ConstantBuffersHDS != b->ConstantBuffersHDS)SC_DBG(context->HSSetConstantBuffers(0, s->ConstantBuffersHDS.size(), &s->ConstantBuffersHDS[0]),GothicRendererInfo::SC_CB);
	if(!s->ConstantBuffersHDS.empty() && s->ConstantBuffersHDS != b->ConstantBuffersHDS)SC_DBG(context->DSSetConstantBuffers(0, s->ConstantBuffersHDS.size(), &s->ConstantBuffersHDS[0]),GothicRendererInfo::SC_CB);
	if(!s->ConstantBuffersGS.empty() && s->ConstantBuffersGS != b->ConstantBuffersGS)SC_DBG(context->GSSetConstantBuffers(0, s->ConstantBuffersGS.size(), &s->ConstantBuffersGS[0]),GothicRendererInfo::SC_CB);

	// Vertexbuffers
	UINT off[] = {0,0};
	if(memcmp(s->BaseState.VertexBuffers, b->BaseState.VertexBuffers, sizeof(b->BaseState.VertexBuffers)) != 0)
		SC_DBG(context->IASetVertexBuffers(0, s->VertexBuffers.size(), &s->VertexBuffers[0], s->BaseState.VertexStride, off), GothicRendererInfo::SC_VB);

	if(!s->StructuredBuffersVS.empty() && memcmp(s->BaseState.StructuredBuffersVS, b->BaseState.StructuredBuffersVS, sizeof(b->BaseState.StructuredBuffersVS)) != 0)
		SC_DBG(context->VSSetShaderResources(0, 1, &s->StructuredBuffersVS[0]), GothicRendererInfo::SC_VB);

	if(s->IndexBuffer != b->IndexBuffer)
		SC_DBG(context->IASetIndexBuffer(s->IndexBuffer, s->BaseState.IndexStride == 4 ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT, 0), GothicRendererInfo::SC_IB);

	// Shaders
	if(s->VertexShader != b->VertexShader)
		SC_DBG(context->VSSetShader(s->VertexShader, NULL, NULL), GothicRendererInfo::SC_VS);
	
	if(s->InputLayout != b->InputLayout)
		SC_DBG(context->IASetInputLayout(s->InputLayout), GothicRendererInfo::SC_IL);
	
	if(s->PixelShader != b->PixelShader)
		SC_DBG(context->PSSetShader(s->PixelShader, NULL, NULL), GothicRendererInfo::SC_PS);
	
	if(s->HullShader != b->HullShader)
		SC_DBG(context->HSSetShader(s->HullShader, NULL, NULL), GothicRendererInfo::SC_HS);
	
	if(s->DomainShader != b->DomainShader)
		SC_DBG(context->DSSetShader(s->DomainShader, NULL, NULL), GothicRendererInfo::SC_DS);
	
	if(s->GeometryShader != b->GeometryShader)
		SC_DBG(context->GSSetShader(s->GeometryShader, NULL, NULL), GothicRendererInfo::SC_GS);

	// Rendertargets
	if(memcmp(s->RenderTargetViews, b->RenderTargetViews, sizeof(void*) * s->NumRenderTargetViews) != 0 ||
		s->DepthStencilView != b->DepthStencilView)
		SC_DBG(context->OMSetRenderTargets(s->NumRenderTargetViews, s->RenderTargetViews, s->DepthStencilView), GothicRendererInfo::SC_RTVDSV);

	// Textures
	if(memcmp(s->Textures, b->Textures, sizeof(void*) * s->BaseState.NumTextures) != 0)
		SC_DBG(context->PSSetShaderResources(0, s->BaseState.NumTextures, s->Textures), GothicRendererInfo::SC_TX);

	// Primitive topology
	//Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	// Replace old state
	// FIXME: Might not threadsave
	BoundPipelineStateByThread[GetCurrentThreadId()] = s;
}
void BillboardTrees::Render()
{
	if (!m_loadingComplete)
		return;

	auto renderStateMgr = RenderStateMgr::Instance();
	ID3D11DeviceContext* context = m_deviceResources->GetD3DDeviceContext();

	// Set IA stage
	UINT stride = sizeof(PointSize);
	UINT offset = 0;
	if (ShaderChangement::PrimitiveType != D3D11_PRIMITIVE_TOPOLOGY_POINTLIST)
	{
		context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
		ShaderChangement::PrimitiveType = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
	}
	if (ShaderChangement::InputLayout != m_treeInputLayout.Get())
	{
		context->IASetInputLayout(m_treeInputLayout.Get());
		ShaderChangement::InputLayout = m_treeInputLayout.Get();
	}
	context->IASetVertexBuffers(0, 1, m_treeSpriteVB.GetAddressOf(), &stride, &offset);

	ID3D11Buffer* cbuffers[2] = { m_perFrameCB->GetBuffer(), m_treeSettingsCB.GetBuffer() };
	ID3D11SamplerState* samplers[1] = { renderStateMgr->LinearSam() };
	// Bind shaders, constant buffers, srvs and samplers
	context->VSSetShader(m_treeVS.Get(), 0, 0);
	ShaderChangement::VS = m_treeVS.Get();
	context->GSSetShader(m_treeGS.Get(), 0, 0);
	context->GSSetConstantBuffers(0, 1, cbuffers);
	switch (m_renderOptions)
	{
	case BillTreeRenderOption::Light3:		// Light
		context->PSSetShader(m_treeLight3PS.Get(), 0, 0);
		ShaderChangement::PS = m_treeLight3PS.Get();
		break;
	case BillTreeRenderOption::Light3TexClip:		// LightTexClip
		context->PSSetShader(m_treeLight3TexClipPS.Get(), 0, 0);
		ShaderChangement::PS = m_treeLight3TexClipPS.Get();
		break;
	case BillTreeRenderOption::Light3TexClipFog:		// LightTexClipFog
		context->PSSetShader(m_treeLight3TexClipFogPS.Get(), 0, 0);
		ShaderChangement::PS = m_treeLight3TexClipFogPS.Get();
		break;
	default:
		throw ref new Platform::InvalidArgumentException("No such render option");
	}
	context->PSSetConstantBuffers(0, 2, cbuffers);
	context->PSSetSamplers(0, 1, samplers);
	context->PSSetShaderResources(0, 1, m_treeTextureMapArraySRV.GetAddressOf());

	float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
	if (m_alphaToCoverage)
		context->OMSetBlendState(renderStateMgr->AlphaToCoverBS(), blendFactor, 0xffffffff);
	context->Draw(m_treeCount, 0);

	// Recover render state
	if (m_alphaToCoverage)
		context->OMSetBlendState(nullptr, blendFactor, 0xffffffff);
	// Remove gs
	context->GSSetShader(nullptr, 0, 0);
	ShaderChangement::GS = nullptr;
}