forked from dolphin-emu/dolphin
		
	
		
			
				
	
	
		
			165 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright 2015 Dolphin Emulator Project
 | 
						|
// Licensed under GPLv2+
 | 
						|
// Refer to the license.txt file included.
 | 
						|
 | 
						|
#include <memory>
 | 
						|
 | 
						|
#include "VideoBackends/D3D12/D3DBase.h"
 | 
						|
#include "VideoBackends/D3D12/D3DCommandListManager.h"
 | 
						|
#include "VideoBackends/D3D12/D3DStreamBuffer.h"
 | 
						|
#include "VideoBackends/D3D12/ShaderConstantsManager.h"
 | 
						|
 | 
						|
#include "VideoCommon/GeometryShaderManager.h"
 | 
						|
#include "VideoCommon/PixelShaderManager.h"
 | 
						|
#include "VideoCommon/Statistics.h"
 | 
						|
#include "VideoCommon/VertexShaderManager.h"
 | 
						|
#include "VideoCommon/VideoConfig.h"
 | 
						|
 | 
						|
namespace DX12
 | 
						|
{
 | 
						|
enum SHADER_STAGE
 | 
						|
{
 | 
						|
  SHADER_STAGE_GEOMETRY_SHADER = 0,
 | 
						|
  SHADER_STAGE_PIXEL_SHADER = 1,
 | 
						|
  SHADER_STAGE_VERTEX_SHADER = 2,
 | 
						|
  SHADER_STAGE_COUNT = 3
 | 
						|
};
 | 
						|
 | 
						|
static std::array<std::unique_ptr<D3DStreamBuffer>, SHADER_STAGE_COUNT>
 | 
						|
    s_shader_constant_stream_buffers;
 | 
						|
 | 
						|
static const unsigned int s_shader_constant_buffer_padded_sizes[SHADER_STAGE_COUNT] = {
 | 
						|
    (sizeof(GeometryShaderConstants) + 0xff) & ~0xff, (sizeof(PixelShaderConstants) + 0xff) & ~0xff,
 | 
						|
    (sizeof(VertexShaderConstants) + 0xff) & ~0xff};
 | 
						|
 | 
						|
void ShaderConstantsManager::Init()
 | 
						|
{
 | 
						|
  // Allow a large maximum size, as we want to minimize stalls here
 | 
						|
  std::generate(std::begin(s_shader_constant_stream_buffers),
 | 
						|
                std::end(s_shader_constant_stream_buffers), []() {
 | 
						|
                  return std::make_unique<D3DStreamBuffer>(2 * 1024 * 1024, 64 * 1024 * 1024,
 | 
						|
                                                           nullptr);
 | 
						|
                });
 | 
						|
}
 | 
						|
 | 
						|
void ShaderConstantsManager::Shutdown()
 | 
						|
{
 | 
						|
  for (auto& buffer : s_shader_constant_stream_buffers)
 | 
						|
    buffer.reset();
 | 
						|
}
 | 
						|
 | 
						|
bool ShaderConstantsManager::LoadAndSetGeometryShaderConstants()
 | 
						|
{
 | 
						|
  bool command_list_executed = false;
 | 
						|
 | 
						|
  if (GeometryShaderManager::dirty)
 | 
						|
  {
 | 
						|
    command_list_executed =
 | 
						|
        s_shader_constant_stream_buffers[SHADER_STAGE_GEOMETRY_SHADER]->AllocateSpaceInBuffer(
 | 
						|
            s_shader_constant_buffer_padded_sizes[SHADER_STAGE_GEOMETRY_SHADER],
 | 
						|
            0  // The padded sizes are already aligned to 256 bytes, so don't need to worry about
 | 
						|
               // manually aligning offset.
 | 
						|
            );
 | 
						|
 | 
						|
    memcpy(s_shader_constant_stream_buffers[SHADER_STAGE_GEOMETRY_SHADER]
 | 
						|
               ->GetCPUAddressOfCurrentAllocation(),
 | 
						|
           &GeometryShaderManager::constants, sizeof(GeometryShaderConstants));
 | 
						|
 | 
						|
    GeometryShaderManager::dirty = false;
 | 
						|
 | 
						|
    ADDSTAT(stats.thisFrame.bytesUniformStreamed, sizeof(GeometryShaderConstants));
 | 
						|
 | 
						|
    D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_GS_CBV, true);
 | 
						|
  }
 | 
						|
 | 
						|
  if (D3D::command_list_mgr->GetCommandListDirtyState(COMMAND_LIST_STATE_GS_CBV))
 | 
						|
  {
 | 
						|
    D3D::current_command_list->SetGraphicsRootConstantBufferView(
 | 
						|
        DESCRIPTOR_TABLE_GS_CBV, s_shader_constant_stream_buffers[SHADER_STAGE_GEOMETRY_SHADER]
 | 
						|
                                     ->GetGPUAddressOfCurrentAllocation());
 | 
						|
 | 
						|
    D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_GS_CBV, false);
 | 
						|
  }
 | 
						|
 | 
						|
  return command_list_executed;
 | 
						|
}
 | 
						|
 | 
						|
bool ShaderConstantsManager::LoadAndSetPixelShaderConstants()
 | 
						|
{
 | 
						|
  bool command_list_executed = false;
 | 
						|
 | 
						|
  if (PixelShaderManager::dirty)
 | 
						|
  {
 | 
						|
    command_list_executed =
 | 
						|
        s_shader_constant_stream_buffers[SHADER_STAGE_PIXEL_SHADER]->AllocateSpaceInBuffer(
 | 
						|
            s_shader_constant_buffer_padded_sizes[SHADER_STAGE_PIXEL_SHADER],
 | 
						|
            0  // The padded sizes are already aligned to 256 bytes, so don't need to worry about
 | 
						|
               // manually aligning offset.
 | 
						|
            );
 | 
						|
 | 
						|
    memcpy(s_shader_constant_stream_buffers[SHADER_STAGE_PIXEL_SHADER]
 | 
						|
               ->GetCPUAddressOfCurrentAllocation(),
 | 
						|
           &PixelShaderManager::constants, sizeof(PixelShaderConstants));
 | 
						|
 | 
						|
    PixelShaderManager::dirty = false;
 | 
						|
 | 
						|
    ADDSTAT(stats.thisFrame.bytesUniformStreamed, sizeof(PixelShaderConstants));
 | 
						|
 | 
						|
    D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PS_CBV, true);
 | 
						|
  }
 | 
						|
 | 
						|
  if (D3D::command_list_mgr->GetCommandListDirtyState(COMMAND_LIST_STATE_PS_CBV))
 | 
						|
  {
 | 
						|
    D3D::current_command_list->SetGraphicsRootConstantBufferView(
 | 
						|
        DESCRIPTOR_TABLE_PS_CBVONE, s_shader_constant_stream_buffers[SHADER_STAGE_PIXEL_SHADER]
 | 
						|
                                        ->GetGPUAddressOfCurrentAllocation());
 | 
						|
 | 
						|
    D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PS_CBV, false);
 | 
						|
  }
 | 
						|
 | 
						|
  return command_list_executed;
 | 
						|
}
 | 
						|
 | 
						|
bool ShaderConstantsManager::LoadAndSetVertexShaderConstants()
 | 
						|
{
 | 
						|
  bool command_list_executed = false;
 | 
						|
 | 
						|
  if (VertexShaderManager::dirty)
 | 
						|
  {
 | 
						|
    command_list_executed =
 | 
						|
        s_shader_constant_stream_buffers[SHADER_STAGE_VERTEX_SHADER]->AllocateSpaceInBuffer(
 | 
						|
            s_shader_constant_buffer_padded_sizes[SHADER_STAGE_VERTEX_SHADER],
 | 
						|
            0  // The padded sizes are already aligned to 256 bytes, so don't need to worry about
 | 
						|
               // manually aligning offset.
 | 
						|
            );
 | 
						|
 | 
						|
    memcpy(s_shader_constant_stream_buffers[SHADER_STAGE_VERTEX_SHADER]
 | 
						|
               ->GetCPUAddressOfCurrentAllocation(),
 | 
						|
           &VertexShaderManager::constants, sizeof(VertexShaderConstants));
 | 
						|
 | 
						|
    VertexShaderManager::dirty = false;
 | 
						|
 | 
						|
    ADDSTAT(stats.thisFrame.bytesUniformStreamed, sizeof(VertexShaderConstants));
 | 
						|
 | 
						|
    D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_VS_CBV, true);
 | 
						|
  }
 | 
						|
 | 
						|
  if (D3D::command_list_mgr->GetCommandListDirtyState(COMMAND_LIST_STATE_VS_CBV))
 | 
						|
  {
 | 
						|
    const D3D12_GPU_VIRTUAL_ADDRESS calculated_gpu_va =
 | 
						|
        s_shader_constant_stream_buffers[SHADER_STAGE_VERTEX_SHADER]
 | 
						|
            ->GetGPUAddressOfCurrentAllocation();
 | 
						|
 | 
						|
    D3D::current_command_list->SetGraphicsRootConstantBufferView(DESCRIPTOR_TABLE_VS_CBV,
 | 
						|
                                                                 calculated_gpu_va);
 | 
						|
 | 
						|
    if (g_ActiveConfig.bEnablePixelLighting)
 | 
						|
      D3D::current_command_list->SetGraphicsRootConstantBufferView(DESCRIPTOR_TABLE_PS_CBVTWO,
 | 
						|
                                                                   calculated_gpu_va);
 | 
						|
 | 
						|
    D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_VS_CBV, false);
 | 
						|
  }
 | 
						|
 | 
						|
  return command_list_executed;
 | 
						|
}
 | 
						|
} |