fast fix for pixel shader compilation in dx11

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5687 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Rodolfo Osvaldo Bogado
2010-06-14 03:09:44 +00:00
parent c759f7b3be
commit 41266b5ed0
7 changed files with 32 additions and 27 deletions

View File

@ -129,6 +129,13 @@
#endif // WIN32 #endif // WIN32
typedef enum
{
API_OPENGL,
API_D3D9,
API_D3D11
} API_TYPE;
// A macro to disallow the copy constructor and operator= functions // A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class // This should be used in the private: declarations for a class
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ #define DISALLOW_COPY_AND_ASSIGN(TypeName) \

View File

@ -146,10 +146,10 @@ void GetPixelShaderId(PIXELSHADERUID *uid, u32 texturemask, u32 dstAlphaEnable)
// output is given by .outreg // output is given by .outreg
// tevtemp is set according to swapmodetables and // tevtemp is set according to swapmodetables and
static void WriteStage(char *&p, int n, u32 texture_mask, u32 HLSL); static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType);
static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, u32 texture_mask, u32 HLSL); static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, u32 texture_mask, API_TYPE ApiType);
// static void WriteAlphaCompare(char *&p, int num, int comp); // static void WriteAlphaCompare(char *&p, int num, int comp);
static bool WriteAlphaTest(char *&p, u32 HLSL); static bool WriteAlphaTest(char *&p, API_TYPE ApiType);
static void WriteFog(char *&p); static void WriteFog(char *&p);
const float epsilon8bit = 1.0f / 255.0f; const float epsilon8bit = 1.0f / 255.0f;
@ -357,7 +357,7 @@ static void BuildSwapModeTable()
} }
} }
const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, u32 HLSL) const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, API_TYPE ApiType)
{ {
setlocale(LC_NUMERIC, "C"); // Reset locale for compilation setlocale(LC_NUMERIC, "C"); // Reset locale for compilation
text[sizeof(text) - 1] = 0x7C; // canary text[sizeof(text) - 1] = 0x7C; // canary
@ -385,7 +385,7 @@ const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, u32 H
// Declare samplers // Declare samplers
if (texture_mask) if (texture_mask)
{ {
if (HLSL) if (ApiType != API_OPENGL)
WRITE(p, "uniform sampler "); WRITE(p, "uniform sampler ");
else else
WRITE(p, "uniform samplerRECT "); WRITE(p, "uniform samplerRECT ");
@ -488,13 +488,13 @@ const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, u32 H
char buffer[32]; char buffer[32];
sprintf(buffer, "float3 indtex%d", i); sprintf(buffer, "float3 indtex%d", i);
SampleTexture(p, buffer, "tempcoord", "abg", bpmem.tevindref.getTexMap(i), texture_mask,HLSL); SampleTexture(p, buffer, "tempcoord", "abg", bpmem.tevindref.getTexMap(i), texture_mask,ApiType);
} }
} }
for (int i = 0; i < numStages; i++) for (int i = 0; i < numStages; i++)
WriteStage(p, i, texture_mask,HLSL); //build the equation for this stage WriteStage(p, i, texture_mask,ApiType); //build the equation for this stage
if(numStages) if(numStages)
{ {
// The results of the last texenv stage are put onto the screen, // The results of the last texenv stage are put onto the screen,
@ -506,13 +506,15 @@ const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, u32 H
// emulation of unisgned 8 overflow when casting // emulation of unisgned 8 overflow when casting
WRITE(p, "prev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); WRITE(p, "prev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
if (!WriteAlphaTest(p, HLSL)) if (!WriteAlphaTest(p, ApiType))
{ {
// alpha test will always fail, so restart the shader and just make it an empty function // alpha test will always fail, so restart the shader and just make it an empty function
p = pmainstart; p = pmainstart;
WRITE(p, "ocol0 = 0;\n"); WRITE(p, "ocol0 = 0;\n");
WRITE(p, "depth = 1.f;\n"); WRITE(p, "depth = 1.f;\n");
WRITE(p, "discard;return;\n"); WRITE(p, "discard;\n");
if(ApiType != API_D3D11)
WRITE(p, "return;\n");
} }
else else
{ {
@ -602,7 +604,7 @@ static const char *TEVCMPAlphaOPTable[16] =
}; };
static void WriteStage(char *&p, int n, u32 texture_mask, u32 HLSL) static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType)
{ {
char *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap]; char *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap];
char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap]; char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap];
@ -698,7 +700,7 @@ static void WriteStage(char *&p, int n, u32 texture_mask, u32 HLSL)
WRITE(p, "tevcoord.xy = float2(0.0f,0.0f);\n"); WRITE(p, "tevcoord.xy = float2(0.0f,0.0f);\n");
} }
SampleTexture(p, "textemp", "tevcoord", texswap, texmap, texture_mask, HLSL); SampleTexture(p, "textemp", "tevcoord", texswap, texmap, texture_mask, ApiType);
} }
else else
WRITE(p, "textemp=float4(1.0f,1.0f,1.0f,1.0f);\n"); WRITE(p, "textemp=float4(1.0f,1.0f,1.0f,1.0f);\n");
@ -851,7 +853,7 @@ static void WriteStage(char *&p, int n, u32 texture_mask, u32 HLSL)
WRITE(p, ";\n\n"); WRITE(p, ";\n\n");
} }
void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, u32 texture_mask, u32 HLSL) void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, u32 texture_mask, API_TYPE ApiType)
{ {
if (texture_mask & (1<<texmap)) { if (texture_mask & (1<<texmap)) {
// non pow 2 // non pow 2
@ -873,13 +875,13 @@ void SampleTexture(char *&p, const char *destination, const char *texcoords, con
WRITE(p, "tempcoord.y = %s.y;\n", texcoords); WRITE(p, "tempcoord.y = %s.y;\n", texcoords);
} }
if (HLSL) if (ApiType != API_OPENGL)
WRITE(p, "%s=tex2D(samp%d,tempcoord.xy).%s;\n", destination, texmap, texswap); WRITE(p, "%s=tex2D(samp%d,tempcoord.xy).%s;\n", destination, texmap, texswap);
else else
WRITE(p, "%s=texRECT(samp%d,tempcoord.xy).%s;\n", destination, texmap, texswap); WRITE(p, "%s=texRECT(samp%d,tempcoord.xy).%s;\n", destination, texmap, texswap);
} }
else { else {
if (HLSL) if (ApiType != API_OPENGL)
WRITE(p, "%s=tex2D(samp%d,%s.xy).%s;\n", destination, texmap, texcoords, texswap); WRITE(p, "%s=tex2D(samp%d,%s.xy).%s;\n", destination, texmap, texcoords, texswap);
else else
WRITE(p, "%s=texRECT(samp%d,%s.xy).%s;\n", destination, texmap, texcoords, texswap); WRITE(p, "%s=texRECT(samp%d,%s.xy).%s;\n", destination, texmap, texcoords, texswap);
@ -910,7 +912,7 @@ static const char *tevAlphaFunclogicTable[] =
" == " // xnor " == " // xnor
}; };
static bool WriteAlphaTest(char *&p, u32 HLSL) static bool WriteAlphaTest(char *&p, API_TYPE ApiType)
{ {
u32 op = bpmem.alphaFunc.logic; u32 op = bpmem.alphaFunc.logic;
u32 comp[2] = {bpmem.alphaFunc.comp0,bpmem.alphaFunc.comp1}; u32 comp[2] = {bpmem.alphaFunc.comp0,bpmem.alphaFunc.comp1};
@ -942,7 +944,7 @@ static bool WriteAlphaTest(char *&p, u32 HLSL)
} }
// using discard then return works the same in cg and hlsl // using discard then return works the same in cg and dx9 but not in dx11
WRITE(p, "if(!( "); WRITE(p, "if(!( ");
int compindex = bpmem.alphaFunc.comp0 % 8; int compindex = bpmem.alphaFunc.comp0 % 8;
@ -953,7 +955,7 @@ static bool WriteAlphaTest(char *&p, u32 HLSL)
compindex = bpmem.alphaFunc.comp1 % 8; compindex = bpmem.alphaFunc.comp1 % 8;
WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table
WRITE(p, ")){ocol0 = 0;depth = 1.f;discard;return;}\n"); WRITE(p, ")){ocol0 = 0;depth = 1.f;discard;%s}\n",(ApiType != API_D3D11)? "return;" : "");
return true; return true;
} }

View File

@ -101,7 +101,7 @@ public:
} }
}; };
const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, u32 HLSL = 0); const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, API_TYPE ApiType);
void GetPixelShaderId(PIXELSHADERUID *uid, u32 texturemask, u32 dstAlphaEnable); void GetPixelShaderId(PIXELSHADERUID *uid, u32 texturemask, u32 dstAlphaEnable);
extern PIXELSHADERUID last_pixel_shader_uid; extern PIXELSHADERUID last_pixel_shader_uid;

View File

@ -19,6 +19,7 @@
#define GCOGL_VERTEXSHADER_H #define GCOGL_VERTEXSHADER_H
#include "XFMemory.h" #include "XFMemory.h"
#include "Common.h"
#define SHADER_POSMTX_ATTRIB 1 #define SHADER_POSMTX_ATTRIB 1
#define SHADER_NORM1_ATTRIB 6 #define SHADER_NORM1_ATTRIB 6
@ -99,12 +100,7 @@ public:
} }
}; };
typedef enum
{
API_OPENGL,
API_D3D9,
API_D3D11
} API_TYPE;
// components is included in the uid. // components is included in the uid.
const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type); const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type);

View File

@ -232,7 +232,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha)
} }
// need to compile a new shader // need to compile a new shader
const char* code = GeneratePixelShaderCode(PixelShaderManager::GetTextureMask(), dstAlpha, 2); const char* code = GeneratePixelShaderCode(PixelShaderManager::GetTextureMask(), dstAlpha, API_D3D11);
ID3D10Blob* pbytecode; ID3D10Blob* pbytecode;
if (!D3D::CompilePixelShader(code, strlen(code), &pbytecode)) if (!D3D::CompilePixelShader(code, strlen(code), &pbytecode))

View File

@ -334,7 +334,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha)
} }
// OK, need to generate and compile it. // OK, need to generate and compile it.
const char *code = GeneratePixelShaderCode(PixelShaderManager::GetTextureMask(), dstAlpha, 2); const char *code = GeneratePixelShaderCode(PixelShaderManager::GetTextureMask(), dstAlpha, API_D3D9);
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) { if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
static int counter = 0; static int counter = 0;

View File

@ -207,7 +207,7 @@ FRAGMENTSHADER* PixelShaderCache::GetShader(bool dstAlphaEnable)
newentry.frameCount = frameCount; newentry.frameCount = frameCount;
pShaderLast = &newentry.shader; pShaderLast = &newentry.shader;
const char *code = GeneratePixelShaderCode(PixelShaderManager::GetTextureMask(), const char *code = GeneratePixelShaderCode(PixelShaderManager::GetTextureMask(),
dstAlphaEnable); dstAlphaEnable,API_OPENGL);
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) { if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {