D3D: Support compiling compute shaders

This commit is contained in:
Stenzek 2018-02-09 22:59:51 +10:00
parent aaea515d71
commit e8ff2b2006
4 changed files with 99 additions and 3 deletions

View File

@ -511,6 +511,16 @@ const char* PixelShaderVersionString()
return "ps_4_0"; return "ps_4_0";
} }
const char* ComputeShaderVersionString()
{
if (s_featlevel == D3D_FEATURE_LEVEL_11_0)
return "cs_5_0";
else if (s_featlevel == D3D_FEATURE_LEVEL_10_1)
return "cs_4_1";
else /*if(featlevel == D3D_FEATURE_LEVEL_10_0)*/
return "cs_4_0";
}
D3DTexture2D* GetBackBuffer() D3DTexture2D* GetBackBuffer()
{ {
return s_backbuf; return s_backbuf;

View File

@ -69,6 +69,7 @@ D3DTexture2D* GetBackBuffer();
const char* PixelShaderVersionString(); const char* PixelShaderVersionString();
const char* GeometryShaderVersionString(); const char* GeometryShaderVersionString();
const char* VertexShaderVersionString(); const char* VertexShaderVersionString();
const char* ComputeShaderVersionString();
bool BGRATexturesSupported(); bool BGRATexturesSupported();
bool AllowTearingSupported(); bool AllowTearingSupported();

View File

@ -188,6 +188,66 @@ bool CompilePixelShader(const std::string& code, D3DBlob** blob, const D3D_SHADE
return SUCCEEDED(hr); return SUCCEEDED(hr);
} }
// bytecode->shader
ID3D11ComputeShader* CreateComputeShaderFromByteCode(const void* bytecode, size_t len)
{
ID3D11ComputeShader* shader;
HRESULT hr = D3D::device->CreateComputeShader(bytecode, len, nullptr, &shader);
if (FAILED(hr))
{
PanicAlert("CreateComputeShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__);
return nullptr;
}
return shader;
}
// code->bytecode
bool CompileComputeShader(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::ComputeShaderVersionString(), flags, 0, &shaderBuffer, &errorBuffer);
if (errorBuffer)
{
INFO_LOG(VIDEO, "Compute shader compiler messages:\n%s",
(const char*)errorBuffer->GetBufferPointer());
}
if (FAILED(hr))
{
static int num_failures = 0;
std::string filename = StringFromFormat("%sbad_cs_%04i.txt",
File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++);
std::ofstream file;
File::OpenFStream(file, filename, std::ios_base::out);
file << code;
file.close();
PanicAlert("Failed to compile compute shader: %s\nDebug info (%s):\n%s", filename.c_str(),
D3D::ComputeShaderVersionString(),
reinterpret_cast<const char*>(errorBuffer->GetBufferPointer()));
*blob = nullptr;
errorBuffer->Release();
}
else
{
*blob = new D3DBlob(shaderBuffer);
shaderBuffer->Release();
}
return SUCCEEDED(hr);
}
ID3D11VertexShader* CompileAndCreateVertexShader(const std::string& code) ID3D11VertexShader* CompileAndCreateVertexShader(const std::string& code)
{ {
D3DBlob* blob = nullptr; D3DBlob* blob = nullptr;
@ -226,6 +286,19 @@ ID3D11PixelShader* CompileAndCreatePixelShader(const std::string& code)
return nullptr; return nullptr;
} }
ID3D11ComputeShader* CompileAndCreateComputeShader(const std::string& code)
{
D3DBlob* blob = nullptr;
CompileComputeShader(code, &blob);
if (blob)
{
ID3D11ComputeShader* shader = CreateComputeShaderFromByteCode(blob);
blob->Release();
return shader;
}
return nullptr;
}
} // namespace } // namespace
} // namespace DX11 } // namespace DX11

View File

@ -19,6 +19,7 @@ namespace D3D
ID3D11VertexShader* CreateVertexShaderFromByteCode(const void* bytecode, size_t len); ID3D11VertexShader* CreateVertexShaderFromByteCode(const void* bytecode, size_t len);
ID3D11GeometryShader* CreateGeometryShaderFromByteCode(const void* bytecode, size_t len); ID3D11GeometryShader* CreateGeometryShaderFromByteCode(const void* bytecode, size_t len);
ID3D11PixelShader* CreatePixelShaderFromByteCode(const void* bytecode, size_t len); ID3D11PixelShader* CreatePixelShaderFromByteCode(const void* bytecode, size_t len);
ID3D11ComputeShader* CreateComputeShaderFromByteCode(const void* bytecode, size_t len);
// The returned bytecode buffers should be Release()d. // The returned bytecode buffers should be Release()d.
bool CompileVertexShader(const std::string& code, D3DBlob** blob); bool CompileVertexShader(const std::string& code, D3DBlob** blob);
@ -26,12 +27,15 @@ bool CompileGeometryShader(const std::string& code, D3DBlob** blob,
const D3D_SHADER_MACRO* pDefines = nullptr); const D3D_SHADER_MACRO* pDefines = nullptr);
bool CompilePixelShader(const std::string& code, D3DBlob** blob, bool CompilePixelShader(const std::string& code, D3DBlob** blob,
const D3D_SHADER_MACRO* pDefines = nullptr); const D3D_SHADER_MACRO* pDefines = nullptr);
bool CompileComputeShader(const std::string& code, D3DBlob** blob,
const D3D_SHADER_MACRO* pDefines = nullptr);
// Utility functions // Utility functions
ID3D11VertexShader* CompileAndCreateVertexShader(const std::string& code); ID3D11VertexShader* CompileAndCreateVertexShader(const std::string& code);
ID3D11GeometryShader* CompileAndCreateGeometryShader(const std::string& code, ID3D11GeometryShader* CompileAndCreateGeometryShader(const std::string& code,
const D3D_SHADER_MACRO* pDefines = nullptr); const D3D_SHADER_MACRO* pDefines = nullptr);
ID3D11PixelShader* CompileAndCreatePixelShader(const std::string& code); ID3D11PixelShader* CompileAndCreatePixelShader(const std::string& code);
ID3D11ComputeShader* CompileAndCreateComputeShader(const std::string& code);
inline ID3D11VertexShader* CreateVertexShaderFromByteCode(D3DBlob* bytecode) inline ID3D11VertexShader* CreateVertexShaderFromByteCode(D3DBlob* bytecode)
{ {
@ -45,21 +49,29 @@ inline ID3D11PixelShader* CreatePixelShaderFromByteCode(D3DBlob* bytecode)
{ {
return CreatePixelShaderFromByteCode(bytecode->Data(), bytecode->Size()); return CreatePixelShaderFromByteCode(bytecode->Data(), bytecode->Size());
} }
inline ID3D11ComputeShader* CreateComputeShaderFromByteCode(D3DBlob* bytecode)
{
return CreateComputeShaderFromByteCode(bytecode->Data(), bytecode->Size());
}
inline ID3D11VertexShader* CompileAndCreateVertexShader(D3DBlob* code) inline ID3D11VertexShader* CompileAndCreateVertexShader(D3DBlob* code)
{ {
return CompileAndCreateVertexShader((const char*)code->Data()); return CompileAndCreateVertexShader(reinterpret_cast<const char*>(code->Data()));
} }
inline ID3D11GeometryShader* inline ID3D11GeometryShader*
CompileAndCreateGeometryShader(D3DBlob* code, const D3D_SHADER_MACRO* pDefines = nullptr) CompileAndCreateGeometryShader(D3DBlob* code, const D3D_SHADER_MACRO* pDefines = nullptr)
{ {
return CompileAndCreateGeometryShader((const char*)code->Data(), pDefines); return CompileAndCreateGeometryShader(reinterpret_cast<const char*>(code->Data()), pDefines);
} }
inline ID3D11PixelShader* CompileAndCreatePixelShader(D3DBlob* code) inline ID3D11PixelShader* CompileAndCreatePixelShader(D3DBlob* code)
{ {
return CompileAndCreatePixelShader((const char*)code->Data()); return CompileAndCreatePixelShader(reinterpret_cast<const char*>(code->Data()));
}
inline ID3D11ComputeShader* CompileAndCreateComputeShader(D3DBlob* code)
{
return CompileAndCreateComputeShader(reinterpret_cast<const char*>(code->Data()));
} }
} }