Initial work on post-shader translation for D3D11

This commit is contained in:
Henrik Rydgard 2017-02-16 16:37:34 +01:00
parent acde17e3ce
commit e7612c13da
5 changed files with 111 additions and 11 deletions

View File

@ -51,8 +51,15 @@ static EShLanguage GetLanguage(const Draw::ShaderStage stage) {
}
}
void ShaderTranslationInit() {
glslang::InitializeProcess();
}
void ShaderTranslationShutdown() {
glslang::FinalizeProcess();
}
bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShaderMetadata *destMetadata, std::string src, ShaderLanguage srcLang, Draw::ShaderStage stage, std::string *errorMessage) {
if (srcLang != GLSL_300)
if (srcLang != GLSL_300 && srcLang != GLSL_140)
return false;
glslang::TProgram program;
@ -62,15 +69,14 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShade
init_resources(Resources);
// Enable SPIR-V and Vulkan rules when parsing GLSL
EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);
EShMessages messages = EShMessages::EShMsgDefault; // (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);
EShLanguage shaderStage = GetLanguage(stage);
glslang::TShader shader(shaderStage);
shaderStrings[0] = src.c_str();
shader.setStrings(shaderStrings, 1);
if (!shader.parse(&Resources, 100, false, messages)) {
if (!shader.parse(&Resources, 100, EProfile::ECompatibilityProfile, false, false, messages)) {
ELOG("%s", shader.getInfoLog());
ELOG("%s", shader.getInfoDebugLog());
if (errorMessage) {
@ -116,6 +122,14 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShade
case HLSL_D3D11:
{
spirv_cross::CompilerHLSL hlsl(spirv);
spirv_cross::ShaderResources resources = hlsl.get_shader_resources();
int i = 0;
for (auto &resource : resources.sampled_images) {
// int location = hlsl.get_decoration(resource.id, spv::DecorationLocation);
hlsl.set_decoration(resource.id, spv::DecorationLocation, i);
i++;
}
spirv_cross::CompilerHLSL::Options options{};
options.fixup_clipspace = true;
options.shader_model = 50;

View File

@ -27,6 +27,9 @@ struct TranslatedShaderMetadata {
};
void ShaderTranslationInit();
void ShaderTranslationShutdown();
bool TranslateShader(std::string *dst, ShaderLanguage destLang, TranslatedShaderMetadata *destMetadata, std::string src, ShaderLanguage srcLang, Draw::ShaderStage stage, std::string *errorMessage);
#endif

View File

@ -18,8 +18,11 @@
#include "math/lin/matrix4x4.h"
#include "ext/native/thin3d/thin3d.h"
#include "base/basictypes.h"
#include "file/vfs.h"
#include "file/zip_read.h"
#include "Common/ColorConv.h"
#include "Common/MathUtil.h"
#include "Core/Host.h"
#include "Core/MemMap.h"
#include "Core/Config.h"
@ -30,7 +33,9 @@
#include "GPU/Debugger/Stepping.h"
#include "GPU/Common/FramebufferCommon.h"
#include "GPU/Common/ShaderTranslation.h"
#include "GPU/Common/TextureDecoder.h"
#include "GPU/Common/PostShader.h"
#include "GPU/D3D11/FramebufferManagerD3D11.h"
#include "GPU/D3D11/ShaderManagerD3D11.h"
#include "GPU/D3D11/TextureCacheD3D11.h"
@ -105,6 +110,13 @@ FramebufferManagerD3D11::FramebufferManagerD3D11(Draw::DrawContext *draw)
vb.Usage = D3D11_USAGE_DYNAMIC;
vb.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
device_->CreateBuffer(&vb, nullptr, &quadBuffer_);
vb.ByteWidth = ROUND_UP(sizeof(PostShaderUniforms), 16);
vb.Usage = D3D11_USAGE_DYNAMIC;
device_->CreateBuffer(&vb, nullptr, &postConstants_);
ShaderTranslationInit();
CompilePostShader();
D3D11_TEXTURE2D_DESC packDesc{};
packDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
@ -121,6 +133,8 @@ FramebufferManagerD3D11::FramebufferManagerD3D11(Draw::DrawContext *draw)
FramebufferManagerD3D11::~FramebufferManagerD3D11() {
packTexture_->Release();
ShaderTranslationShutdown();
// Drawing cleanup
if (quadVertexShader_)
quadVertexShader_->Release();
@ -176,6 +190,59 @@ void FramebufferManagerD3D11::DisableState() {
context_->OMSetDepthStencilState(stockD3D11.depthStencilDisabled, 0xFF);
}
void FramebufferManagerD3D11::CompilePostShader() {
usePostShader_ = false;
SetNumExtraFBOs(0);
std::string vsSource;
std::string psSource;
const ShaderInfo *shaderInfo = 0;
if (g_Config.sPostShaderName == "Off") {
return;
}
shaderInfo = GetPostShaderInfo(g_Config.sPostShaderName);
if (shaderInfo) {
postShaderAtOutputResolution_ = shaderInfo->outputResolution;
size_t sz;
char *vs = (char *)VFSReadFile(shaderInfo->vertexShaderFile.c_str(), &sz);
if (!vs)
return;
char *ps = (char *)VFSReadFile(shaderInfo->fragmentShaderFile.c_str(), &sz);
if (!ps) {
free(vs);
return;
}
std::string vsSourceGLSL = vs;
std::string psSourceGLSL = ps;
free(vs);
free(ps);
TranslatedShaderMetadata metaVS, metaFS;
std::string errorVS, errorFS;
if (!TranslateShader(&vsSource, HLSL_D3D11, &metaVS, vsSourceGLSL, GLSL_140, Draw::ShaderStage::VERTEX, &errorVS))
return;
if (!TranslateShader(&psSource, HLSL_D3D11, &metaFS, psSourceGLSL, GLSL_140, Draw::ShaderStage::FRAGMENT, &errorFS))
return;
} else {
return;
}
std::vector<uint8_t> byteCode;
postVertexShader_ = CreateVertexShaderD3D11(device_, vsSource.data(), vsSource.size(), &byteCode);
if (!postVertexShader_) {
return;
}
postPixelShader_ = CreatePixelShaderD3D11(device_, psSource.data(), psSource.size());
if (!postPixelShader_) {
postVertexShader_->Release();
return;
}
device_->CreateInputLayout(g_QuadVertexElements, 2, byteCode.data(), byteCode.size(), &postInputLayout_);
usePostShader_ = true;
}
void FramebufferManagerD3D11::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) {
u8 *convBuf = NULL;
@ -334,10 +401,20 @@ void FramebufferManagerD3D11::Bind2DShader() {
}
void FramebufferManagerD3D11::BindPostShader(const PostShaderUniforms &uniforms) {
// TODO: Actually bind a post processing shader
context_->IASetInputLayout(quadInputLayout_);
context_->PSSetShader(quadPixelShader_, 0, 0);
context_->VSSetShader(quadVertexShader_, 0, 0);
if (!postPixelShader_) {
if (usePostShader_) {
CompilePostShader();
}
if (!usePostShader_) {
context_->IASetInputLayout(quadInputLayout_);
context_->PSSetShader(quadPixelShader_, 0, 0);
context_->VSSetShader(quadVertexShader_, 0, 0);
return;
}
}
context_->IASetInputLayout(postInputLayout_);
context_->PSSetShader(postPixelShader_, 0, 0);
context_->VSSetShader(postVertexShader_, 0, 0);
}
void FramebufferManagerD3D11::RebindFramebuffer() {

View File

@ -94,6 +94,7 @@ protected:
void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
private:
void CompilePostShader();
void BindPostShader(const PostShaderUniforms &uniforms) override;
void Bind2DShader() override;
void MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) override;
@ -136,10 +137,17 @@ private:
ShaderManagerD3D11 *shaderManagerD3D11_;
DrawEngineD3D11 *drawEngine_;
// 1:1 Readback texture, 512x512 fixed
// Permanent 1:1 readback texture, 512x512 fixed
// For larger debug readbacks, we create/destroy textures on the fly.
ID3D11Texture2D *packTexture_;
// Used by post-processing shader
// Postprocessing
ID3D11VertexShader *postVertexShader_ = nullptr;
ID3D11PixelShader *postPixelShader_ = nullptr;
ID3D11InputLayout *postInputLayout_ = nullptr;
ID3D11Buffer *postConstants_ = nullptr;
// Used by post-processing shader
std::vector<Draw::Framebuffer *> extraFBOs_;

View File

@ -36,7 +36,6 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
@ -49,7 +48,6 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />