forked from dolphin-emu/dolphin
		
	
		
			
				
	
	
		
			232 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			232 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright 2010 Dolphin Emulator Project
 | 
						|
// Licensed under GPLv2+
 | 
						|
// Refer to the license.txt file included.
 | 
						|
 | 
						|
#include <fstream>
 | 
						|
#include <string>
 | 
						|
 | 
						|
#include "Common/FileUtil.h"
 | 
						|
#include "Common/Logging/Log.h"
 | 
						|
#include "Common/MsgHandler.h"
 | 
						|
#include "Common/StringUtil.h"
 | 
						|
#include "VideoBackends/D3D/D3DBase.h"
 | 
						|
#include "VideoBackends/D3D/D3DShader.h"
 | 
						|
#include "VideoCommon/VideoConfig.h"
 | 
						|
 | 
						|
namespace DX11
 | 
						|
{
 | 
						|
namespace D3D
 | 
						|
{
 | 
						|
// bytecode->shader
 | 
						|
ID3D11VertexShader* CreateVertexShaderFromByteCode(const void* bytecode, unsigned int len)
 | 
						|
{
 | 
						|
  ID3D11VertexShader* v_shader;
 | 
						|
  HRESULT hr = D3D::device->CreateVertexShader(bytecode, len, nullptr, &v_shader);
 | 
						|
  if (FAILED(hr))
 | 
						|
    return nullptr;
 | 
						|
 | 
						|
  return v_shader;
 | 
						|
}
 | 
						|
 | 
						|
// code->bytecode
 | 
						|
bool CompileVertexShader(const std::string& code, D3DBlob** blob)
 | 
						|
{
 | 
						|
  ID3D10Blob* shaderBuffer = nullptr;
 | 
						|
  ID3D10Blob* errorBuffer = nullptr;
 | 
						|
 | 
						|
#if defined(_DEBUG) || defined(DEBUGFAST)
 | 
						|
  UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY | D3D10_SHADER_DEBUG;
 | 
						|
#else
 | 
						|
  UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY | D3D10_SHADER_OPTIMIZATION_LEVEL3 |
 | 
						|
               D3D10_SHADER_SKIP_VALIDATION;
 | 
						|
#endif
 | 
						|
  HRESULT hr = PD3DCompile(code.c_str(), code.length(), nullptr, nullptr, nullptr, "main",
 | 
						|
                           D3D::VertexShaderVersionString(), flags, 0, &shaderBuffer, &errorBuffer);
 | 
						|
  if (errorBuffer)
 | 
						|
  {
 | 
						|
    INFO_LOG(VIDEO, "Vertex shader compiler messages:\n%s\n",
 | 
						|
             (const char*)errorBuffer->GetBufferPointer());
 | 
						|
  }
 | 
						|
 | 
						|
  if (FAILED(hr))
 | 
						|
  {
 | 
						|
    static int num_failures = 0;
 | 
						|
    std::string filename = StringFromFormat("%sbad_vs_%04i.txt",
 | 
						|
                                            File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++);
 | 
						|
    std::ofstream file;
 | 
						|
    OpenFStream(file, filename, std::ios_base::out);
 | 
						|
    file << code;
 | 
						|
    file.close();
 | 
						|
 | 
						|
    PanicAlert("Failed to compile vertex shader: %s\nDebug info (%s):\n%s", filename.c_str(),
 | 
						|
               D3D::VertexShaderVersionString(), (const char*)errorBuffer->GetBufferPointer());
 | 
						|
 | 
						|
    *blob = nullptr;
 | 
						|
    errorBuffer->Release();
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    *blob = new D3DBlob(shaderBuffer);
 | 
						|
    shaderBuffer->Release();
 | 
						|
  }
 | 
						|
  return SUCCEEDED(hr);
 | 
						|
}
 | 
						|
 | 
						|
// bytecode->shader
 | 
						|
ID3D11GeometryShader* CreateGeometryShaderFromByteCode(const void* bytecode, unsigned int len)
 | 
						|
{
 | 
						|
  ID3D11GeometryShader* g_shader;
 | 
						|
  HRESULT hr = D3D::device->CreateGeometryShader(bytecode, len, nullptr, &g_shader);
 | 
						|
  if (FAILED(hr))
 | 
						|
    return nullptr;
 | 
						|
 | 
						|
  return g_shader;
 | 
						|
}
 | 
						|
 | 
						|
// code->bytecode
 | 
						|
bool CompileGeometryShader(const std::string& code, D3DBlob** blob,
 | 
						|
                           const D3D_SHADER_MACRO* pDefines)
 | 
						|
{
 | 
						|
  ID3D10Blob* shaderBuffer = nullptr;
 | 
						|
  ID3D10Blob* errorBuffer = nullptr;
 | 
						|
 | 
						|
#if defined(_DEBUG) || defined(DEBUGFAST)
 | 
						|
  UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY | D3D10_SHADER_DEBUG;
 | 
						|
#else
 | 
						|
  UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY | D3D10_SHADER_OPTIMIZATION_LEVEL3 |
 | 
						|
               D3D10_SHADER_SKIP_VALIDATION;
 | 
						|
#endif
 | 
						|
  HRESULT hr =
 | 
						|
      PD3DCompile(code.c_str(), code.length(), nullptr, pDefines, nullptr, "main",
 | 
						|
                  D3D::GeometryShaderVersionString(), flags, 0, &shaderBuffer, &errorBuffer);
 | 
						|
 | 
						|
  if (errorBuffer)
 | 
						|
  {
 | 
						|
    INFO_LOG(VIDEO, "Geometry shader compiler messages:\n%s\n",
 | 
						|
             (const char*)errorBuffer->GetBufferPointer());
 | 
						|
  }
 | 
						|
 | 
						|
  if (FAILED(hr))
 | 
						|
  {
 | 
						|
    static int num_failures = 0;
 | 
						|
    std::string filename = StringFromFormat("%sbad_gs_%04i.txt",
 | 
						|
                                            File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++);
 | 
						|
    std::ofstream file;
 | 
						|
    OpenFStream(file, filename, std::ios_base::out);
 | 
						|
    file << code;
 | 
						|
    file.close();
 | 
						|
 | 
						|
    PanicAlert("Failed to compile geometry shader: %s\nDebug info (%s):\n%s", filename.c_str(),
 | 
						|
               D3D::GeometryShaderVersionString(), (const char*)errorBuffer->GetBufferPointer());
 | 
						|
 | 
						|
    *blob = nullptr;
 | 
						|
    errorBuffer->Release();
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    *blob = new D3DBlob(shaderBuffer);
 | 
						|
    shaderBuffer->Release();
 | 
						|
  }
 | 
						|
  return SUCCEEDED(hr);
 | 
						|
}
 | 
						|
 | 
						|
// bytecode->shader
 | 
						|
ID3D11PixelShader* CreatePixelShaderFromByteCode(const void* bytecode, unsigned int len)
 | 
						|
{
 | 
						|
  ID3D11PixelShader* p_shader;
 | 
						|
  HRESULT hr = D3D::device->CreatePixelShader(bytecode, len, nullptr, &p_shader);
 | 
						|
  if (FAILED(hr))
 | 
						|
  {
 | 
						|
    PanicAlert("CreatePixelShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__);
 | 
						|
    p_shader = nullptr;
 | 
						|
  }
 | 
						|
  return p_shader;
 | 
						|
}
 | 
						|
 | 
						|
// code->bytecode
 | 
						|
bool CompilePixelShader(const std::string& code, D3DBlob** blob, const D3D_SHADER_MACRO* pDefines)
 | 
						|
{
 | 
						|
  ID3D10Blob* shaderBuffer = nullptr;
 | 
						|
  ID3D10Blob* errorBuffer = nullptr;
 | 
						|
 | 
						|
#if defined(_DEBUG) || defined(DEBUGFAST)
 | 
						|
  UINT flags = D3D10_SHADER_DEBUG;
 | 
						|
#else
 | 
						|
  UINT flags = D3D10_SHADER_OPTIMIZATION_LEVEL3;
 | 
						|
#endif
 | 
						|
  HRESULT hr = PD3DCompile(code.c_str(), code.length(), nullptr, pDefines, nullptr, "main",
 | 
						|
                           D3D::PixelShaderVersionString(), flags, 0, &shaderBuffer, &errorBuffer);
 | 
						|
 | 
						|
  if (errorBuffer)
 | 
						|
  {
 | 
						|
    INFO_LOG(VIDEO, "Pixel shader compiler messages:\n%s",
 | 
						|
             (const char*)errorBuffer->GetBufferPointer());
 | 
						|
  }
 | 
						|
 | 
						|
  if (FAILED(hr))
 | 
						|
  {
 | 
						|
    static int num_failures = 0;
 | 
						|
    std::string filename = StringFromFormat("%sbad_ps_%04i.txt",
 | 
						|
                                            File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++);
 | 
						|
    std::ofstream file;
 | 
						|
    OpenFStream(file, filename, std::ios_base::out);
 | 
						|
    file << code;
 | 
						|
    file.close();
 | 
						|
 | 
						|
    PanicAlert("Failed to compile pixel shader: %s\nDebug info (%s):\n%s", filename.c_str(),
 | 
						|
               D3D::PixelShaderVersionString(), (const char*)errorBuffer->GetBufferPointer());
 | 
						|
 | 
						|
    *blob = nullptr;
 | 
						|
    errorBuffer->Release();
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    *blob = new D3DBlob(shaderBuffer);
 | 
						|
    shaderBuffer->Release();
 | 
						|
  }
 | 
						|
 | 
						|
  return SUCCEEDED(hr);
 | 
						|
}
 | 
						|
 | 
						|
ID3D11VertexShader* CompileAndCreateVertexShader(const std::string& code)
 | 
						|
{
 | 
						|
  D3DBlob* blob = nullptr;
 | 
						|
  if (CompileVertexShader(code, &blob))
 | 
						|
  {
 | 
						|
    ID3D11VertexShader* v_shader = CreateVertexShaderFromByteCode(blob);
 | 
						|
    blob->Release();
 | 
						|
    return v_shader;
 | 
						|
  }
 | 
						|
  return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
ID3D11GeometryShader* CompileAndCreateGeometryShader(const std::string& code,
 | 
						|
                                                     const D3D_SHADER_MACRO* pDefines)
 | 
						|
{
 | 
						|
  D3DBlob* blob = nullptr;
 | 
						|
  if (CompileGeometryShader(code, &blob, pDefines))
 | 
						|
  {
 | 
						|
    ID3D11GeometryShader* g_shader = CreateGeometryShaderFromByteCode(blob);
 | 
						|
    blob->Release();
 | 
						|
    return g_shader;
 | 
						|
  }
 | 
						|
  return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
ID3D11PixelShader* CompileAndCreatePixelShader(const std::string& code)
 | 
						|
{
 | 
						|
  D3DBlob* blob = nullptr;
 | 
						|
  CompilePixelShader(code, &blob);
 | 
						|
  if (blob)
 | 
						|
  {
 | 
						|
    ID3D11PixelShader* p_shader = CreatePixelShaderFromByteCode(blob);
 | 
						|
    blob->Release();
 | 
						|
    return p_shader;
 | 
						|
  }
 | 
						|
  return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
}  // namespace
 | 
						|
 | 
						|
}  // namespace DX11
 |