diff --git a/Source/Core/DolphinWX/Dolphin.vcxproj b/Source/Core/DolphinWX/Dolphin.vcxproj index 829a7d9f4e16..f42b84ed1d6c 100644 --- a/Source/Core/DolphinWX/Dolphin.vcxproj +++ b/Source/Core/DolphinWX/Dolphin.vcxproj @@ -374,9 +374,6 @@ xcopy "$(SolutionDir)..\Externals\msvcrt\$(PlatformName)\*.dll" "$(TargetDir)" / {9a4c733c-bade-4ac6-b58a-6e274395e90e} - - {dc7d7af4-ce47-49e8-8b63-265cb6233a49} - {1909cd2d-1707-456f-86ca-0df42a727c99} @@ -408,4 +405,4 @@ xcopy "$(SolutionDir)..\Externals\msvcrt\$(PlatformName)\*.dll" "$(TargetDir)" / - \ No newline at end of file + diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 409f94cd0b24..7f6f1e00808b 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -67,9 +67,9 @@ void VideoConfigDiag::Event_Close(wxCloseEvent& ev) } #if defined(_WIN32) -wxString backend_desc = wxTRANSLATE("Selects what graphics API to use internally.\nDirect3D 9 usually is the fastest one. OpenGL is more accurate though. Direct3D 11 is somewhere between the two.\nNote that the Direct3D backends are only available on Windows.\n\nIf unsure, use Direct3D 11."); +wxString backend_desc = wxTRANSLATE("Selects what graphics API to use internally.\nThe software renderer is only used for debugging, so you'll want to use either Direct3D or OpenGL. Different games will behave differently on each backend, so for best emulation experience it's recommended to try both and chose the one that fits your requirements best.\nNote that the Direct3D backend is not available on old Windows versions.\n\nIf unsure, use Direct3D."); #else -wxString backend_desc = wxTRANSLATE("Selects what graphics API to use internally.\nDirect3D 9 usually is the fastest one. OpenGL is more accurate though. Direct3D 11 is somewhere between the two.\nNote that the Direct3D backends are only available on Windows.\n\nIf unsure, use OpenGL."); +wxString backend_desc = wxTRANSLATE("Selects what graphics API to use internally.\nThe software renderer is only used for debugging, so unless you have a reason to use it you'll want to select OpenGL here.\n\nIf unsure, use OpenGL."); #endif wxString adapter_desc = wxTRANSLATE("Select a hardware adapter to use.\n\nIf unsure, use the first one."); wxString display_res_desc = wxTRANSLATE("Selects the display resolution used in fullscreen mode.\nThis should always be bigger than or equal to the internal resolution. Performance impact is negligible.\n\nIf unsure, use your desktop resolution.\nIf still unsure, use the highest resolution which works for you."); diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 84410bc64387..afbd5861e917 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -271,20 +271,15 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T for (int i = 0; i < 8; ++i) out.Write("uniform sampler2D samp%d;\n", i); } - else + else // D3D { // Declare samplers for (int i = 0; i < 8; ++i) - out.Write("%s samp%d : register(s%d);\n", (ApiType == API_D3D11) ? "sampler" : "uniform sampler2D", i, i); + out.Write("sampler samp%d : register(s%d);\n", i, i); - if (ApiType == API_D3D11) - { - out.Write("\n"); - for (int i = 0; i < 8; ++i) - { - out.Write("Texture2D Tex%d : register(t%d);\n", i, i); - } - } + out.Write("\n"); + for (int i = 0; i < 8; ++i) + out.Write("Texture2D Tex%d : register(t%d);\n", i, i); } out.Write("\n"); @@ -361,13 +356,13 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T { static bool warn_once = true; if (warn_once) - WARN_LOG(VIDEO, "Early z test enabled but not possible to emulate with current configuration. Make sure to use the D3D11 or OpenGL backend and enable fast depth calculations. If this message still shows up your hardware isn't able to emulate the feature properly (a GPU which supports D3D 11.0 / OGL 4.2 is required)."); + WARN_LOG(VIDEO, "Early z test enabled but not possible to emulate with current configuration. Make sure to enable fast depth calculations. If this message still shows up your hardware isn't able to emulate the feature properly (a GPU with D3D 11.0 / OGL 4.2 support is required)."); warn_once = false; } out.Write("void main()\n{\n"); } - else + else // D3D { if (forced_early_z) { @@ -377,27 +372,17 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T { static bool warn_once = true; if (warn_once) - WARN_LOG(VIDEO, "Early z test enabled but not possible to emulate with current configuration. Make sure to use the D3D11 or OpenGL backend and enable fast depth calculations. If this message still shows up your hardware isn't able to emulate the feature properly (a GPU which supports D3D 11.0 / OGL 4.2 is required)."); + WARN_LOG(VIDEO, "Early z test enabled but not possible to emulate with current configuration. Make sure to enable fast depth calculations. If this message still shows up your hardware isn't able to emulate the feature properly (a GPU with D3D 11.0 / OGL 4.2 support is required)."); warn_once = false; } out.Write("void main(\n"); - if(ApiType != API_D3D11) - { - out.Write(" out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n", - dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "", - per_pixel_depth ? "\n out float depth : DEPTH," : "", - ApiType & API_D3D9_SM20 ? "POSITION" : "VPOS"); - } - else - { - out.Write(" out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n", - dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "", - per_pixel_depth ? "\n out float depth : SV_Depth," : ""); - } + out.Write(" out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n", + dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "", + per_pixel_depth ? "\n out float depth : SV_Depth," : ""); - // "centroid" attribute is only supported by D3D11 - const char* optCentroid = (ApiType == API_D3D11 ? "centroid" : ""); + // Use centroid sampling to make MSAA work properly + const char* optCentroid = "centroid"; out.Write(" in %s float4 colors_0 : COLOR0,\n", optCentroid); out.Write(" in %s float4 colors_1 : COLOR1", optCentroid); @@ -623,10 +608,11 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T WriteAlphaTest(out, uid_data, ApiType, dstAlphaMode, per_pixel_depth); + // TODO: Make more sense out of this comment // D3D9 doesn't support readback of depth in pixel shader, so we always have to calculate it again. // This shouldn't be a performance issue as the written depth is usually still from perspective division // but this isn't true for z-textures, so there will be depth issues between enabled and disabled z-textures fragments - if ((ApiType == API_OPENGL || ApiType == API_D3D11) && g_ActiveConfig.bFastDepthCalc) + if (g_ActiveConfig.bFastDepthCalc) out.Write("float zCoord = rawpos.z;\n"); else { @@ -682,18 +668,10 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) { out.SetConstantsUsed(C_ALPHA, C_ALPHA); - if(ApiType & API_D3D9) - { - // alpha component must be 0 or the shader will not compile (Direct3D 9Ex restriction) - // Colors will be blended against the color from ocol1 in D3D 9... - out.Write("\tocol1 = float4(prev.a, prev.a, prev.a, 0.0);\n"); - } - else - { - // Colors will be blended against the alpha from ocol1... - out.Write("\tocol1 = prev;\n"); - } - // ...and the alpha from ocol0 will be written to the framebuffer. + + // Colors will be blended against the alpha from ocol1 and + // the alpha from ocol0 will be written to the framebuffer. + out.Write("\tocol1 = prev;\n"); out.Write("\tocol0.a = " I_ALPHA"[0].a;\n"); } @@ -1127,10 +1105,10 @@ void SampleTexture(T& out, const char *texcoords, const char *texswap, int texma { out.SetConstantsUsed(C_TEXDIMS+texmap,C_TEXDIMS+texmap); - if (ApiType == API_D3D11) + if (ApiType == API_D3D) out.Write("Tex%d.Sample(samp%d,%s.xy * " I_TEXDIMS"[%d].xy).%s;\n", texmap,texmap, texcoords, texmap, texswap); - else - out.Write("%s(samp%d,%s.xy * " I_TEXDIMS"[%d].xy).%s;\n", ApiType == API_OPENGL ? "texture" : "tex2D", texmap, texcoords, texmap, texswap); + else // OGL + out.Write("texture(samp%d,%s.xy * " I_TEXDIMS"[%d].xy).%s;\n", texmap, texcoords, texmap, texswap); } static const char *tevAlphaFuncsTable[] = @@ -1164,7 +1142,6 @@ static inline void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_T out.SetConstantsUsed(C_ALPHA, C_ALPHA); - // using discard then return works the same in cg and dx9 but not in dx11 out.Write("\tif(!( "); uid_data.alpha_test_comp0 = bpmem.alpha_test.comp0; @@ -1198,14 +1175,14 @@ static inline void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_T // It seems to be less buggy than not to update the depth buffer if alpha test fails, // but both ways wouldn't be accurate. - // OpenGL 4.2 has a flag which allows the driver to still update the depth buffer + // OpenGL 4.2 has a flag which allows the driver to still update the depth buffer // if alpha test fails. The driver doesn't have to, but I assume they all do because // it's the much faster code path for the GPU. uid_data.alpha_test_use_zcomploc_hack = bpmem.UseEarlyDepthTest() && bpmem.zmode.updateenable && !g_ActiveConfig.backend_info.bSupportsEarlyZ; if (!uid_data.alpha_test_use_zcomploc_hack) { out.Write("\t\tdiscard;\n"); - if (ApiType != API_D3D11) + if (ApiType != API_D3D) out.Write("\t\treturn;\n"); } diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 7d5b9354ad1d..111f70cac1fa 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -481,8 +481,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage, // Sometimes, we can get around recreating a texture if only the number of mip levels changes // e.g. if our texture cache entry got too many mipmap levels we can limit the number of used levels by setting the appropriate render states // Thus, we don't update this member for every Load, but just whenever the texture gets recreated - // TODO: D3D9 doesn't support min_lod. We should add a workaround for that here! - + // TODO: This is the wrong value. We should be storing the number of levels our actual texture has. // But that will currently make the above "existing entry" tests fail as "texLevels" is not calculated until after. // Currently, we might try to reuse a texture which appears to have more levels than actual, maybe.. diff --git a/Source/Core/VideoCommon/Src/TextureConversionShader.cpp b/Source/Core/VideoCommon/Src/TextureConversionShader.cpp index fec8b8afdec5..7916e47c1236 100644 --- a/Source/Core/VideoCommon/Src/TextureConversionShader.cpp +++ b/Source/Core/VideoCommon/Src/TextureConversionShader.cpp @@ -83,38 +83,22 @@ void WriteSwizzler(char*& p, u32 format, API_TYPE ApiType) { WRITE(p, "#define samp0 samp9\n"); WRITE(p, "uniform sampler2DRect samp0;\n"); - } - else if (ApiType & API_D3D9) - { - WRITE(p,"uniform sampler samp0 : register(s0);\n"); - } - else - { - WRITE(p,"sampler samp0 : register(s0);\n"); - WRITE(p, "Texture2D Tex0 : register(t0);\n"); - } - if (ApiType == API_OPENGL) - { WRITE(p, " out vec4 ocol0;\n"); WRITE(p, " VARYIN float2 uv0;\n"); WRITE(p, "void main()\n"); } - else + else // D3D { + WRITE(p,"sampler samp0 : register(s0);\n"); + WRITE(p, "Texture2D Tex0 : register(t0);\n"); + WRITE(p,"void main(\n"); - if (ApiType != API_D3D11) - { - WRITE(p," out float4 ocol0 : COLOR0,\n"); - } - else - { - WRITE(p," out float4 ocol0 : SV_Target,\n"); - } + WRITE(p," out float4 ocol0 : SV_Target,\n"); WRITE(p," in float2 uv0 : TEXCOORD0)\n"); } - WRITE(p, "{\n" + WRITE(p, "{\n" " float2 sampleUv;\n" " float2 uv1 = floor(uv0);\n"); @@ -142,15 +126,15 @@ void WriteSwizzler(char*& p, u32 format, API_TYPE ApiType) if (ApiType != API_OPENGL) { - WRITE(p, " sampleUv = sampleUv + float2(0.0,1.0);\n");// still to determine the reason for this + WRITE(p, " sampleUv = sampleUv + float2(0.0,1.0);\n"); // still need to determine the reason for this WRITE(p, " sampleUv = sampleUv / " I_COLORS"[0].zw;\n"); } } -// block dimensions : widthStride, heightStride +// block dimensions : widthStride, heightStride // texture dims : width, height, x offset, y offset void Write32BitSwizzler(char*& p, u32 format, API_TYPE ApiType) -{ +{ // [0] left, top, right, bottom of source rectangle within source texture // [1] width and height of destination texture in pixels // Two were merged for GLSL @@ -164,39 +148,23 @@ void Write32BitSwizzler(char*& p, u32 format, API_TYPE ApiType) { WRITE(p, "#define samp0 samp9\n"); WRITE(p, "uniform sampler2DRect samp0;\n"); - } - else if (ApiType & API_D3D9) - { - WRITE(p,"uniform sampler samp0 : register(s0);\n"); - } - else - { - WRITE(p,"sampler samp0 : register(s0);\n"); - WRITE(p, "Texture2D Tex0 : register(t0);\n"); - } - if (ApiType == API_OPENGL) - { WRITE(p, " out float4 ocol0;\n"); WRITE(p, " VARYIN float2 uv0;\n"); WRITE(p, "void main()\n"); } else { + WRITE(p,"sampler samp0 : register(s0);\n"); + WRITE(p, "Texture2D Tex0 : register(t0);\n"); + WRITE(p,"void main(\n"); - if(ApiType != API_D3D11) - { - WRITE(p," out float4 ocol0 : COLOR0,\n"); - } - else - { - WRITE(p," out float4 ocol0 : SV_Target,\n"); - } + WRITE(p," out float4 ocol0 : SV_Target,\n"); WRITE(p," in float2 uv0 : TEXCOORD0)\n"); } - WRITE(p, "{\n" + WRITE(p, "{\n" " float2 sampleUv;\n" " float2 uv1 = floor(uv0);\n"); @@ -232,18 +200,16 @@ void Write32BitSwizzler(char*& p, u32 format, API_TYPE ApiType) void WriteSampleColor(char*& p, const char* colorComp, const char* dest, API_TYPE ApiType) { const char* texSampleOpName; - if (ApiType & API_D3D9) - texSampleOpName = "tex2D"; - else if (ApiType == API_D3D11) + if (ApiType == API_D3D) texSampleOpName = "tex0.Sample"; - else + else // OGL texSampleOpName = "texture2DRect"; // the increment of sampleUv.x is delayed, so we perform it here. see WriteIncrementSampleX. const char* texSampleIncrementUnit; - if (ApiType != API_OPENGL) + if (ApiType == API_D3D) texSampleIncrementUnit = I_COLORS"[0].x / " I_COLORS"[0].z"; - else + else // OGL texSampleIncrementUnit = I_COLORS"[0].x"; WRITE(p, " %s = %s(samp0, sampleUv + float2(%d.0 * (%s), 0.0)).%s;\n", @@ -296,7 +262,7 @@ void WriteEncoderEnd(char* p, API_TYPE ApiType) void WriteI8Encoder(char* p, API_TYPE ApiType) { WriteSwizzler(p, GX_TF_I8, ApiType); - WRITE(p, " float3 texSample;\n"); + WRITE(p, " float3 texSample;\n"); WriteSampleColor(p, "rgb", "texSample", ApiType); WriteColorToIntensity(p, "texSample", "ocol0.b"); @@ -430,7 +396,7 @@ void WriteRGB565Encoder(char* p,API_TYPE ApiType) WRITE(p, " float2 texRs = float2(texSample0.r, texSample1.r);\n"); WRITE(p, " float2 texGs = float2(texSample0.g, texSample1.g);\n"); WRITE(p, " float2 texBs = float2(texSample0.b, texSample1.b);\n"); - + WriteToBitDepth(p, 6, "texGs", "float2 gInt"); WRITE(p, " float2 gUpper = floor(gInt / 8.0);\n"); WRITE(p, " float2 gLower = gInt - gUpper * 8.0;\n"); @@ -888,12 +854,12 @@ const char *GenerateEncodingShader(u32 format,API_TYPE ApiType) break; default: PanicAlert("Unknown texture copy format: 0x%x\n", format); - break; + break; } if (text[sizeof(text) - 1] != 0x7C) PanicAlert("TextureConversionShader generator - buffer too small, canary has been eaten!"); - + #ifndef ANDROID uselocale(old_locale); // restore locale freelocale(locale); diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 39b478feb517..336979a09bfe 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -28,7 +28,7 @@ static void DefineVSOutputStructMember(T& object, API_TYPE api_type, const char* if (api_type == API_OPENGL) object.Write(";\n"); - else + else // D3D { if (semantic_index != -1) object.Write(" : %s%d;\n", semantic, semantic_index); @@ -167,7 +167,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ out.Write("void main()\n{\n"); } - else + else // D3D { out.Write("VS_OUTPUT main(\n"); @@ -197,19 +197,10 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ // transforms if (components & VB_HAS_POSMTXIDX) { - if (api_type & API_D3D9) - { - out.Write("int4 indices = D3DCOLORtoUBYTE4(blend_indices);\n"); - out.Write("int posmtx = indices.x;\n"); - } - else if (api_type == API_D3D11) - { - out.Write("int posmtx = blend_indices.x * 255.0;\n"); - } + if (api_type == API_D3D) + out.Write("int posmtx = blend_indices.x * 255.0;\n"); // TODO: Ugly, should use an integer instead else - { out.Write("int posmtx = int(fposmtx);\n"); - } if (is_writing_shadercode && (DriverDetails::HasBug(DriverDetails::BUG_NODYNUBOACCESS) && !DriverDetails::HasBug(DriverDetails::BUG_ANNIHILATEDUBOS)) ) { @@ -454,11 +445,11 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ //write the true depth value, if the game uses depth textures pixel shaders will override with the correct values //if not early z culling will improve speed - if (api_type & API_D3D9 || api_type == API_D3D11) + if (api_type == API_D3D) { out.Write("o.pos.z = " I_DEPTHPARAMS".x * o.pos.w + o.pos.z * " I_DEPTHPARAMS".y;\n"); } - else + else // OGL { // this results in a scale from -1..0 to -1..1 after perspective // divide @@ -482,13 +473,6 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ //seems to get rather complicated } - if (api_type & API_D3D9) - { - // D3D9 is addressing pixel centers instead of pixel boundaries in clip space. - // Thus we need to offset the final position by half a pixel - out.Write("o.pos = o.pos + float4(" I_DEPTHPARAMS".z, " I_DEPTHPARAMS".w, 0.f, 0.f);\n"); - } - if(api_type == API_OPENGL) { // Bit ugly here @@ -528,7 +512,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ out.Write("gl_Position = o.pos;\n"); out.Write("}\n"); } - else + else // D3D { out.Write("return o;\n}\n"); } diff --git a/Source/Core/VideoCommon/Src/VideoBackendBase.cpp b/Source/Core/VideoCommon/Src/VideoBackendBase.cpp index 4769ede3a003..13d85c2e37c0 100644 --- a/Source/Core/VideoCommon/Src/VideoBackendBase.cpp +++ b/Source/Core/VideoCommon/Src/VideoBackendBase.cpp @@ -6,7 +6,6 @@ // TODO: ugly #ifdef _WIN32 -#include "../../../Plugins/Plugin_VideoDX9/Src/VideoBackend.h" #include "../../../Plugins/Plugin_VideoDX11/Src/VideoBackend.h" #endif #if !defined(USE_GLES) || USE_GLES3 @@ -41,9 +40,8 @@ void VideoBackend::PopulateList() { VideoBackend* backends[4] = { NULL }; - // D3D11 > OGL > D3D9 > SW + // D3D11 > OGL > SW #ifdef _WIN32 - g_available_video_backends.push_back(backends[2] = new DX9::VideoBackend); if (IsGteVista()) g_available_video_backends.push_back(backends[0] = new DX11::VideoBackend); #endif diff --git a/Source/Core/VideoCommon/Src/VideoBackendBase.h b/Source/Core/VideoCommon/Src/VideoBackendBase.h index cc4ff15416f8..1d691c8ba408 100644 --- a/Source/Core/VideoCommon/Src/VideoBackendBase.h +++ b/Source/Core/VideoCommon/Src/VideoBackendBase.h @@ -128,14 +128,14 @@ class VideoBackend // the implementation needs not do synchronization logic, because calls to it are surrounded by PauseAndLock now virtual void DoState(PointerWrap &p) = 0; - + virtual void CheckInvalidState() = 0; }; extern std::vector g_available_video_backends; extern VideoBackend* g_video_backend; -// inherited by dx9/dx11/ogl backends +// inherited by D3D/OGL backends class VideoBackendHardware : public VideoBackend { void RunLoop(bool enable); @@ -150,7 +150,7 @@ class VideoBackendHardware : public VideoBackend u32 Video_AccessEFB(EFBAccessType, u32, u32, u32); u32 Video_GetQueryResult(PerfQueryType type); - + void Video_AddMessage(const char* pstr, unsigned int milliseconds); void Video_ClearMessages(); bool Video_Screenshot(const char* filename); @@ -171,9 +171,9 @@ class VideoBackendHardware : public VideoBackend void PauseAndLock(bool doLock, bool unpauseOnUnlock=true); void DoState(PointerWrap &p); - + bool m_invalid; - + public: void CheckInvalidState(); diff --git a/Source/Core/VideoCommon/Src/VideoCommon.h b/Source/Core/VideoCommon/Src/VideoCommon.h index c85a6e382ad7..175bd8a5b043 100644 --- a/Source/Core/VideoCommon/Src/VideoCommon.h +++ b/Source/Core/VideoCommon/Src/VideoCommon.h @@ -85,11 +85,8 @@ struct TargetRectangle : public MathUtil::Rectangle typedef enum { API_OPENGL = 1, - API_D3D9_SM30 = 2, - API_D3D9_SM20 = 4, - API_D3D9 = 6, - API_D3D11 = 8, - API_NONE = 16 + API_D3D = 2, + API_NONE = 3 } API_TYPE; inline u32 RGBA8ToRGBA6ToRGBA8(u32 src) diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 22c75131eb9c..93840d75868f 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -98,7 +98,6 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Hacks", "EFBScaledCopy", &bCopyEFBScaled, true); iniFile.Get("Hacks", "EFBCopyCacheEnable", &bEFBCopyCacheEnable, false); iniFile.Get("Hacks", "EFBEmulateFormatChanges", &bEFBEmulateFormatChanges, false); - iniFile.Get("Hacks", "ForceDualSourceBlend", &bForceDualSourceBlend, false); iniFile.Get("Hardware", "Adapter", &iAdapter, 0); @@ -283,7 +282,6 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Hacks", "EFBScaledCopy", bCopyEFBScaled); iniFile.Set("Hacks", "EFBCopyCacheEnable", bEFBCopyCacheEnable); iniFile.Set("Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges); - iniFile.Set("Hacks", "ForceDualSourceBlend", bForceDualSourceBlend); iniFile.Set("Hardware", "Adapter", iAdapter); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 489b75de0d7d..890b9b9edae3 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -123,8 +123,6 @@ struct VideoConfig bool bEnablePixelLighting; bool bHackedBufferUpload; bool bFastDepthCalc; - //for dx9-backend - bool bForceDualSourceBlend; int iLog; // CONF_ bits int iSaveTargetId; // TODO: Should be dropped @@ -143,14 +141,14 @@ struct VideoConfig { API_TYPE APIType; - std::vector Adapters; // for D3D9 and D3D11 + std::vector Adapters; // for D3D std::vector AAModes; std::vector PPShaders; // post-processing shaders - bool bUseRGBATextures; // used for D3D11 in TextureCache + bool bUseRGBATextures; // used for D3D in TextureCache bool bUseMinimalMipCount; bool bSupports3DVision; - bool bSupportsDualSourceBlend; // only supported by D3D11 and OpenGL + bool bSupportsDualSourceBlend; bool bSupportsFormatReinterpretation; bool bSupportsPixelLighting; bool bSupportsPrimitiveRestart; diff --git a/Source/Dolphin_2010.sln b/Source/Dolphin_2010.sln index 207795dd26a2..ffa7dee93016 100644 --- a/Source/Dolphin_2010.sln +++ b/Source/Dolphin_2010.sln @@ -64,12 +64,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DiscIO", "Core\DiscIO\DiscI {3E1339F5-9311-4122-9442-369702E8FCAD} = {3E1339F5-9311-4122-9442-369702E8FCAD} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoDX9", "Plugins\Plugin_VideoDX9\Plugin_VideoDX9.vcxproj", "{DC7D7AF4-CE47-49E8-8B63-265CB6233A49}" - ProjectSection(ProjectDependencies) = postProject - {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} = {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} - {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoDX11", "Plugins\Plugin_VideoDX11\Plugin_VideoDX11.vcxproj", "{9A4C733C-BADE-4AC6-B58A-6E274395E90E}" ProjectSection(ProjectDependencies) = postProject {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} = {3E5C4E02-1BA9-4776-BDBE-E3F91FFA34CF} @@ -278,18 +272,6 @@ Global {B6398059-EBB6-4C34-B547-95F365B71FF4}.Release|Win32.Build.0 = Release|Win32 {B6398059-EBB6-4C34-B547-95F365B71FF4}.Release|x64.ActiveCfg = Release|x64 {B6398059-EBB6-4C34-B547-95F365B71FF4}.Release|x64.Build.0 = Release|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|Win32.ActiveCfg = Debug|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|Win32.Build.0 = Debug|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|x64.ActiveCfg = Debug|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Debug|x64.Build.0 = Debug|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|Win32.Build.0 = DebugFast|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|x64.ActiveCfg = DebugFast|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.DebugFast|x64.Build.0 = DebugFast|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|Win32.ActiveCfg = Release|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|Win32.Build.0 = Release|Win32 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|x64.ActiveCfg = Release|x64 - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49}.Release|x64.Build.0 = Release|x64 {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Debug|Win32.ActiveCfg = Debug|Win32 {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Debug|Win32.Build.0 = Debug|Win32 {9A4C733C-BADE-4AC6-B58A-6E274395E90E}.Debug|x64.ActiveCfg = Debug|x64 diff --git a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp index 9009d390299f..4b96953a3a60 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp @@ -172,7 +172,7 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth, static char buffer[16384]; ShaderCode code; code.SetBuffer(buffer); - GenerateVSOutputStructForGS(code, components, API_D3D11); + GenerateVSOutputStructForGS(code, components, API_D3D); code.Write("\n%s", LINE_GS_COMMON); std::stringstream numTexCoordsStream; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp index 1dd98edd2e0c..56b61e05cd49 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp @@ -453,11 +453,11 @@ void PixelShaderCache::Shutdown() bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) { PixelShaderUid uid; - GetPixelShaderUid(uid, dstAlphaMode, API_D3D11, components); + GetPixelShaderUid(uid, dstAlphaMode, API_D3D, components); if (g_ActiveConfig.bEnableShaderDebugging) { PixelShaderCode code; - GeneratePixelShaderCode(code, dstAlphaMode, API_D3D11, components); + GeneratePixelShaderCode(code, dstAlphaMode, API_D3D, components); pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p"); } @@ -487,7 +487,7 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) // Need to compile a new shader PixelShaderCode code; - GeneratePixelShaderCode(code, dstAlphaMode, API_D3D11, components); + GeneratePixelShaderCode(code, dstAlphaMode, API_D3D, components); D3DBlob* pbytecode; if (!D3D::CompilePixelShader(code.GetBuffer(), (unsigned int)strlen(code.GetBuffer()), &pbytecode)) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp index 9d6e02104e97..f33d7444a20b 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp @@ -166,7 +166,7 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize, static char buffer[16384]; ShaderCode code; code.SetBuffer(buffer); - GenerateVSOutputStructForGS(code, components, API_D3D11); + GenerateVSOutputStructForGS(code, components, API_D3D); code.Write("\n%s", POINT_GS_COMMON); std::stringstream numTexCoordsStream; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp index 6121824b8e50..d9ea7e2a8c2c 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp @@ -200,11 +200,11 @@ void VertexShaderCache::Shutdown() bool VertexShaderCache::SetShader(u32 components) { VertexShaderUid uid; - GetVertexShaderUid(uid, components, API_D3D11); + GetVertexShaderUid(uid, components, API_D3D); if (g_ActiveConfig.bEnableShaderDebugging) { VertexShaderCode code; - GenerateVertexShaderCode(code, components, API_D3D11); + GenerateVertexShaderCode(code, components, API_D3D); vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v"); } @@ -230,7 +230,7 @@ bool VertexShaderCache::SetShader(u32 components) } VertexShaderCode code; - GenerateVertexShaderCode(code, components, API_D3D11); + GenerateVertexShaderCode(code, components, API_D3D); D3DBlob* pbytecode = NULL; D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &pbytecode); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index 59f0899d819d..989fb2ef9121 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -58,18 +58,18 @@ unsigned int VideoBackend::PeekMessages() void VideoBackend::UpdateFPSDisplay(const char *text) { TCHAR temp[512]; - swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX11 | %hs"), scm_rev_str, text); + swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | D3D | %hs"), scm_rev_str, text); EmuWindow::SetWindowText(temp); } std::string VideoBackend::GetName() { - return "DX11"; + return "D3D"; } std::string VideoBackend::GetDisplayName() { - return "Direct3D11"; + return "Direct3D"; } void InitBackendInfo() @@ -82,7 +82,7 @@ void InitBackendInfo() return; } - g_Config.backend_info.APIType = API_D3D11; + g_Config.backend_info.APIType = API_D3D; g_Config.backend_info.bUseRGBATextures = true; // the GX formats barely match any D3D11 formats g_Config.backend_info.bUseMinimalMipCount = true; g_Config.backend_info.bSupports3DVision = false; @@ -142,7 +142,7 @@ void VideoBackend::ShowConfig(void *_hParent) { #if defined(HAVE_WX) && HAVE_WX InitBackendInfo(); - VideoConfigDiag diag((wxWindow*)_hParent, _trans("Direct3D11"), "gfx_dx11"); + VideoConfigDiag diag((wxWindow*)_hParent, _trans("Direct3D"), "gfx_dx11"); diag.ShowModal(); #endif } diff --git a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcxproj b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcxproj deleted file mode 100644 index 02d39e314fe5..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcxproj +++ /dev/null @@ -1,239 +0,0 @@ - - - - - DebugFast - Win32 - - - DebugFast - x64 - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {DC7D7AF4-CE47-49E8-8B63-265CB6233A49} - Plugin_VideoDX9 - VideoDX9 - - - - StaticLibrary - true - Unicode - - - StaticLibrary - true - Unicode - - - StaticLibrary - false - Unicode - false - - - StaticLibrary - false - Unicode - - - StaticLibrary - false - Unicode - - - StaticLibrary - false - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(PlatformName)\$(Configuration)\ - - - - $(ProjectName)D - - - - - - - - - - - - - Disabled - ..\..\Core\Common\Src;..\..\Core\Core\Src;..\..\Core\VideoCommon\Src;..\..\Core\DolphinWX\Src;..\..\..\Externals\wxWidgets3;..\..\..\Externals\wxWidgets3\include;%(AdditionalIncludeDirectories) - _SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebug - stdafx.h - Use - - - true - ..\..\..\Binary\$(PlatformName)\Plugins\$(TargetName)$(TargetExt) - - - - - ..\..\Core\Common\Src;..\..\Core\Core\Src;..\..\Core\VideoCommon\Src;..\..\Core\DolphinWX\Src;..\..\..\Externals\wxWidgets3;..\..\..\Externals\wxWidgets3\include;%(AdditionalIncludeDirectories) - - - true - ..\..\..\Binary\$(PlatformName)\Plugins\$(TargetName)$(TargetExt) - - - - - ..\..\Core\Common\Src;..\..\Core\Core\Src;..\..\Core\VideoCommon\Src;..\..\Core\DolphinWX\Src;..\..\..\Externals\wxWidgets3;..\..\..\Externals\wxWidgets3\include;%(AdditionalIncludeDirectories) - - - true - true - true - ..\..\..\Binary\$(PlatformName)\Plugins\$(TargetName)$(TargetExt) - - - - - ..\..\Core\Common\Src;..\..\Core\Core\Src;..\..\Core\VideoCommon\Src;..\..\Core\DolphinWX\Src;..\..\..\Externals\wxWidgets3;..\..\..\Externals\wxWidgets3\include;%(AdditionalIncludeDirectories) - - - true - true - true - ..\..\..\Binary\$(PlatformName)\Plugins\$(TargetName)$(TargetExt) - - - - - ..\..\Core\Common\Src;..\..\Core\Core\Src;..\..\Core\VideoCommon\Src;..\..\Core\DolphinWX\Src;..\..\..\Externals\wxWidgets3;..\..\..\Externals\wxWidgets3\include;%(AdditionalIncludeDirectories) - - - true - true - true - ..\..\..\Binary\$(PlatformName)\Plugins\$(TargetName)$(TargetExt) - - - - - ..\..\Core\Common\Src;..\..\Core\Core\Src;..\..\Core\VideoCommon\Src;..\..\Core\DolphinWX\Src;..\..\..\Externals\wxWidgets3;..\..\..\Externals\wxWidgets3\include;%(AdditionalIncludeDirectories) - - - true - true - true - ..\..\..\Binary\$(PlatformName)\Plugins\$(TargetName)$(TargetExt) - - - - - {3e5c4e02-1ba9-4776-bdbe-e3f91ffa34cf} - - - - - - - - - - - - - - - Create - Create - Create - Create - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcxproj.filters b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcxproj.filters deleted file mode 100644 index c1d091c2399d..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcxproj.filters +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - Render - - - Render - - - Render - - - Render - - - Render - - - Render - - - Render - - - D3D - - - D3D - - - D3D - - - D3D - - - D3D - - - Render - - - - - - - - - Render - - - Render - - - Render - - - Render - - - Render - - - Render - - - D3D - - - D3D - - - D3D - - - D3D - - - D3D - - - Render - - - - - {7acd5e48-186b-4788-ab0a-3551205635f8} - - - {46f1aa47-0eaf-4c32-bdbb-f61c587cd233} - - - \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp deleted file mode 100644 index 44e5abd3175b..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp +++ /dev/null @@ -1,955 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include "D3DBase.h" -#include "VideoConfig.h" -#include "Render.h" -#include "XFStructs.h" -#include "StringUtil.h" -#include "VideoCommon.h" - -D3DXSAVESURFACETOFILEATYPE PD3DXSaveSurfaceToFileA = NULL; -D3DXSAVETEXTURETOFILEATYPE PD3DXSaveTextureToFileA = NULL; -D3DXCOMPILESHADERTYPE PD3DXCompileShader = NULL; - -namespace DX9 -{ -static char vsVersions[5][7] = {"ERROR", "vs_1_4", "vs_2_a", "vs_3_0", "vs_4_0"}; -static char psVersions[5][7] = {"ERROR", "ps_1_4", "ps_2_a", "ps_3_0", "ps_4_0"}; -// D3DX -HINSTANCE hD3DXDll = NULL; -int d3dx_dll_ref = 0; - -typedef IDirect3D9* (WINAPI* DIRECT3DCREATE9)(UINT); -DIRECT3DCREATE9 PDirect3DCreate9 = NULL; -HINSTANCE hD3DDll = NULL; -int d3d_dll_ref = 0; - -namespace D3D -{ - -LPDIRECT3D9 D3D = NULL; // Used to create the D3DDevice -LPDIRECT3DDEVICE9 dev = NULL; // Our rendering device -LPDIRECT3DSURFACE9 back_buffer; -LPDIRECT3DSURFACE9 back_buffer_z; -D3DCAPS9 caps; -HWND hWnd; - -static int multisample; -static int resolution; -static int xres, yres; -static bool auto_depth_stencil = false; - -#define VENDOR_NVIDIA 4318 -#define VENDOR_ATI 4098 -#define VENDOR_INTEL 32902 - -bool bFrameInProgress = false; - -#define MAX_ADAPTERS 4 -static Adapter adapters[MAX_ADAPTERS]; -static int numAdapters; -static int cur_adapter; - -// Value caches for state filtering -const int MaxStreamSources = 16; -const int MaxTextureStages = 9; -const int MaxRenderStates = 210 + 46; -const int MaxTextureTypes = 33; -const int MaxSamplerSize = 13; -const int MaxSamplerTypes = 15; -static bool m_RenderStatesSet[MaxRenderStates]; -static DWORD m_RenderStates[MaxRenderStates]; -static bool m_RenderStatesChanged[MaxRenderStates]; - -static DWORD m_TextureStageStates[MaxTextureStages][MaxTextureTypes]; -static bool m_TextureStageStatesSet[MaxTextureStages][MaxTextureTypes]; -static bool m_TextureStageStatesChanged[MaxTextureStages][MaxTextureTypes]; - -static DWORD m_SamplerStates[MaxSamplerSize][MaxSamplerTypes]; -static bool m_SamplerStatesSet[MaxSamplerSize][MaxSamplerTypes]; -static bool m_SamplerStatesChanged[MaxSamplerSize][MaxSamplerTypes]; - -static LPDIRECT3DBASETEXTURE9 m_Textures[16]; -static LPDIRECT3DVERTEXDECLARATION9 m_VtxDecl; -static bool m_VtxDeclChanged; -static LPDIRECT3DPIXELSHADER9 m_PixelShader; -static bool m_PixelShaderChanged; -static LPDIRECT3DVERTEXSHADER9 m_VertexShader; -static bool m_VertexShaderChanged; -struct StreamSourceDescriptor -{ - LPDIRECT3DVERTEXBUFFER9 pStreamData; - UINT OffsetInBytes; - UINT Stride; -}; -static StreamSourceDescriptor m_stream_sources[MaxStreamSources]; -static bool m_stream_sources_Changed[MaxStreamSources]; -static LPDIRECT3DINDEXBUFFER9 m_index_buffer; -static bool m_index_buffer_Changed; - -// Z buffer formats to be used for EFB depth surface -D3DFORMAT DepthFormats[] = { - FOURCC_INTZ, - FOURCC_DF24, - FOURCC_RAWZ, - FOURCC_DF16, - D3DFMT_D24X8, - D3DFMT_D24X4S4, - D3DFMT_D24S8, - D3DFMT_D24FS8, - D3DFMT_D32, // too much precision, but who cares - D3DFMT_D16, // much lower precision, but better than nothing - D3DFMT_D15S1, -}; - - -void Enumerate(); - -int GetNumAdapters() { return numAdapters; } -const Adapter &GetAdapter(int i) { return adapters[i]; } -const Adapter &GetCurAdapter() { return adapters[cur_adapter]; } - -bool IsATIDevice() -{ - return GetCurAdapter().ident.VendorId == VENDOR_ATI; -} -bool IsIntelDevice() -{ - return GetCurAdapter().ident.VendorId == VENDOR_INTEL; -} - - -HRESULT Init() -{ - if (d3d_dll_ref++ > 0) return S_OK; - - hD3DDll = LoadLibraryA("d3d9.dll"); - if (!hD3DDll) - { - MessageBoxA(NULL, "Failed to load d3d9.dll", "Critical error", MB_OK | MB_ICONERROR); - return E_FAIL; - } - PDirect3DCreate9 = (DIRECT3DCREATE9)GetProcAddress(hD3DDll, "Direct3DCreate9"); - if (PDirect3DCreate9 == NULL) MessageBoxA(NULL, "GetProcAddress failed for Direct3DCreate9!", "Critical error", MB_OK | MB_ICONERROR); - - // Create the D3D object, which is needed to create the D3DDevice. - D3D = PDirect3DCreate9(D3D_SDK_VERSION); - if (!D3D) - { - --d3d_dll_ref; - return E_FAIL; - } - - // Init the caps structure using data from the currently selected device - int adapter = g_Config.iAdapter; - D3D->GetDeviceCaps((adapter >= 0 && adapter < std::min(MAX_ADAPTERS, numAdapters)) ? adapter : D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps); - Enumerate(); - if(IsIntelDevice()){ - // Murder the a because Intel doesn't support 2.0a because the 'a' part was a ATI and Nvidia war going on - psVersions[2][5] = '0'; - vsVersions[2][5] = '0'; - } - - return S_OK; -} - -void Shutdown() -{ - if (!d3d_dll_ref) return; - if (--d3d_dll_ref != 0) return; - - if (D3D) D3D->Release(); - D3D = NULL; - - if (hD3DDll) FreeLibrary(hD3DDll); - PDirect3DCreate9 = NULL; -} - -void EnableAlphaToCoverage() -{ - // Each vendor has their own specific little hack. - if (GetCurAdapter().ident.VendorId == VENDOR_ATI) - SetRenderState(D3DRS_POINTSIZE, (D3DFORMAT)MAKEFOURCC('A', '2', 'M', '1')); - else - SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')); -} - -void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp) -{ - ZeroMemory(pp, sizeof(D3DPRESENT_PARAMETERS)); - pp->hDeviceWindow = hWnd; - if (auto_depth_stencil) - { - pp->EnableAutoDepthStencil = TRUE; - pp->AutoDepthStencilFormat = D3DFMT_D24S8; - } else { - pp->EnableAutoDepthStencil = FALSE; - pp->AutoDepthStencilFormat = D3DFMT_UNKNOWN; - } - pp->BackBufferFormat = D3DFMT_X8R8G8B8; - if (aa_mode >= (int)adapters[adapter].aa_levels.size()) - aa_mode = 0; - - pp->MultiSampleType = adapters[adapter].aa_levels[aa_mode].ms_setting; - pp->MultiSampleQuality = adapters[adapter].aa_levels[aa_mode].qual_setting; - - pp->Flags = auto_depth_stencil ? D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL : 0; - - if(g_Config.b3DVision) - { - xres = pp->BackBufferWidth = adapters[adapter].resolutions[f].xres; - yres = pp->BackBufferHeight = adapters[adapter].resolutions[f].yres; - } - else - { - RECT client; - GetClientRect(hWnd, &client); - xres = pp->BackBufferWidth = client.right - client.left; - yres = pp->BackBufferHeight = client.bottom - client.top; - } - pp->SwapEffect = D3DSWAPEFFECT_DISCARD; - pp->PresentationInterval = g_Config.IsVSync() ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE; - pp->Windowed = !g_Config.b3DVision; -} - -void Enumerate() -{ - numAdapters = D3D->GetAdapterCount(); - - for (int i = 0; i < std::min(MAX_ADAPTERS, numAdapters); i++) - { - Adapter &a = adapters[i]; - a.aa_levels.clear(); - a.resolutions.clear(); - D3D->GetAdapterIdentifier(i, 0, &a.ident); - bool isNvidia = a.ident.VendorId == VENDOR_NVIDIA; - - // Add SuperSamples modes - a.aa_levels.push_back(AALevel("None", D3DMULTISAMPLE_NONE, 0)); - a.aa_levels.push_back(AALevel("4x SSAA", D3DMULTISAMPLE_NONE, 0)); - a.aa_levels.push_back(AALevel("9x SSAA", D3DMULTISAMPLE_NONE, 0)); - //Add multisample modes - //disable them will they are not implemnted - /* - DWORD qlevels = 0; - if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType( - i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels)) - if (qlevels > 0) - a.aa_levels.push_back(AALevel("2x MSAA", D3DMULTISAMPLE_2_SAMPLES, 0)); - - if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType( - i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels)) - if (qlevels > 0) - a.aa_levels.push_back(AALevel("4x MSAA", D3DMULTISAMPLE_4_SAMPLES, 0)); - - if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType( - i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels)) - if (qlevels > 0) - a.aa_levels.push_back(AALevel("8x MSAA", D3DMULTISAMPLE_8_SAMPLES, 0)); - - if (isNvidia) - { - // CSAA support - if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType( - i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_4_SAMPLES, &qlevels)) - { - if (qlevels > 2) - { - // 8x, 8xQ are available - // See http://developer.nvidia.com/object/coverage-sampled-aa.html - a.aa_levels.push_back(AALevel("8x CSAA", D3DMULTISAMPLE_4_SAMPLES, 2)); - a.aa_levels.push_back(AALevel("8xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 0)); - } - } - if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType( - i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels)) - { - if (qlevels > 2) - { - // 16x, 16xQ are available - // See http://developer.nvidia.com/object/coverage-sampled-aa.html - a.aa_levels.push_back(AALevel("16x CSAA", D3DMULTISAMPLE_4_SAMPLES, 4)); - a.aa_levels.push_back(AALevel("16xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 2)); - } - } - } - */ - // Determine if INTZ is supported. Code from ATI's doc. - // http://developer.amd.com/gpu_assets/Advanced%20DX9%20Capabilities%20for%20ATI%20Radeon%20Cards.pdf - a.supports_intz = D3D_OK == D3D->CheckDeviceFormat( - i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, - D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_INTZ); - // Also check for RAWZ (nvidia only, but the only option to get Z24 textures on sub GF8800 - a.supports_rawz = D3D_OK == D3D->CheckDeviceFormat( - i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, - D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_RAWZ); - // Might as well check for RESZ and NULL too. - a.supports_resz = D3D_OK == D3D->CheckDeviceFormat( - i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, - D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_RESZ); - a.supports_null = D3D_OK == D3D->CheckDeviceFormat( - i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, - D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_NULL); - - if (a.aa_levels.size() == 1) - { - strcpy(a.aa_levels[0].name, "(Not supported on this device)"); - } - int numModes = D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8); - for (int m = 0; m < numModes; m++) - { - D3DDISPLAYMODE mode; - D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode); - - int found = -1; - for (int x = 0; x < (int)a.resolutions.size(); x++) - { - if (a.resolutions[x].xres == mode.Width && a.resolutions[x].yres == mode.Height) - { - found = x; - break; - } - } - - Resolution temp; - Resolution &r = found==-1 ? temp : a.resolutions[found]; - - sprintf(r.name, "%ix%i", mode.Width, mode.Height); - r.bitdepths.insert(mode.Format); - r.refreshes.insert(mode.RefreshRate); - if (found == -1 && mode.Width >= 640 && mode.Height >= 480) - { - r.xres = mode.Width; - r.yres = mode.Height; - a.resolutions.push_back(r); - } - } - } -} - -// dynamically picks one of the available d3dx9 dlls and loads it. -// we're first trying to load the dll Dolphin was compiled with, otherwise the most up-to-date one -HRESULT LoadD3DX9() -{ - if (d3dx_dll_ref++ > 0) return S_OK; - - HRESULT hr = E_FAIL; - hD3DXDll = LoadLibraryA(StringFromFormat("d3dx9_%d.dll", D3DX_SDK_VERSION).c_str()); - if (hD3DXDll != NULL) - { - hr = S_OK; - } - else - { - // if that fails, try loading older dlls (no need to look for newer ones) - for (unsigned int num = D3DX_SDK_VERSION-1; num >= 24; --num) - { - hD3DXDll = LoadLibraryA(StringFromFormat("d3dx9_%d.dll", num).c_str()); - if (hD3DXDll != NULL) - { - NOTICE_LOG(VIDEO, "Successfully loaded %s. If you're having trouble, try updating your DX runtime first.", StringFromFormat("d3dx9_%d.dll", num).c_str()); - hr = S_OK; - break; - } - } - if (FAILED(hr)) - { - MessageBoxA(NULL, "Failed to load any D3DX9 dll, update your DX9 runtime, please", "Critical error", MB_OK | MB_ICONERROR); - return hr; - } - } - PD3DXCompileShader = (D3DXCOMPILESHADERTYPE)GetProcAddress(hD3DXDll, "D3DXCompileShader"); - if (PD3DXCompileShader == NULL) - { - MessageBoxA(NULL, "GetProcAddress failed for D3DXCompileShader!", "Critical error", MB_OK | MB_ICONERROR); - goto fail; - } - - PD3DXSaveSurfaceToFileA = (D3DXSAVESURFACETOFILEATYPE)GetProcAddress(hD3DXDll, "D3DXSaveSurfaceToFileA"); - if (PD3DXSaveSurfaceToFileA == NULL) - { - MessageBoxA(NULL, "GetProcAddress failed for D3DXSaveSurfaceToFileA!", "Critical error", MB_OK | MB_ICONERROR); - goto fail; - } - - PD3DXSaveTextureToFileA = (D3DXSAVETEXTURETOFILEATYPE)GetProcAddress(hD3DXDll, "D3DXSaveTextureToFileA"); - if (PD3DXSaveTextureToFileA == NULL) - { - MessageBoxA(NULL, "GetProcAddress failed for D3DXSaveTextureToFileA!", "Critical error", MB_OK | MB_ICONERROR); - goto fail; - } - return S_OK; - -fail: - --d3dx_dll_ref; - FreeLibrary(hD3DXDll); - PD3DXCompileShader = NULL; - PD3DXSaveSurfaceToFileA = NULL; - PD3DXSaveTextureToFileA = NULL; - return E_FAIL; -} - -void UnloadD3DX9() -{ - if (!d3dx_dll_ref) return; - if (--d3dx_dll_ref != 0) return; - - FreeLibrary(hD3DXDll); - PD3DXCompileShader = NULL; - PD3DXSaveSurfaceToFileA = NULL; - PD3DXSaveTextureToFileA = NULL; -} - -HRESULT Create(int adapter, HWND wnd, int _resolution, int aa_mode, bool auto_depth) -{ - hWnd = wnd; - multisample = aa_mode; - resolution = _resolution; - auto_depth_stencil = auto_depth; - cur_adapter = adapter; - D3DPRESENT_PARAMETERS d3dpp; - - HRESULT hr = LoadD3DX9(); - if (FAILED(hr)) return hr; - - InitPP(adapter, resolution, aa_mode, &d3dpp); - - if (FAILED(D3D->CreateDevice( - adapter, - D3DDEVTYPE_HAL, - wnd, - D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, //doesn't seem to make a difference - &d3dpp, &dev))) - { - if (FAILED(D3D->CreateDevice( - adapter, - D3DDEVTYPE_HAL, - wnd, - D3DCREATE_SOFTWARE_VERTEXPROCESSING, - &d3dpp, &dev))) - { - MessageBox(wnd, - _T("Failed to initialize Direct3D."), - _T("Dolphin Direct3D Backend"), MB_OK | MB_ICONERROR); - return E_FAIL; - } - } - - dev->GetDeviceCaps(&caps); - dev->GetRenderTarget(0, &back_buffer); - if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND) - back_buffer_z = NULL; - SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE ); - SetRenderState(D3DRS_FILLMODE, g_Config.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID); - memset(m_Textures, 0, sizeof(m_Textures)); - memset(m_TextureStageStatesSet, 0, sizeof(m_TextureStageStatesSet)); - memset(m_RenderStatesSet, 0, sizeof(m_RenderStatesSet)); - memset(m_SamplerStatesSet, 0, sizeof(m_SamplerStatesSet)); - memset(m_TextureStageStatesChanged, 0, sizeof(m_TextureStageStatesChanged)); - memset(m_RenderStatesChanged, 0, sizeof(m_RenderStatesChanged)); - memset(m_SamplerStatesChanged, 0, sizeof(m_SamplerStatesChanged)); - m_VtxDecl = NULL; - m_PixelShader = NULL; - m_VertexShader = NULL; - m_index_buffer = NULL; - memset(m_stream_sources, 0, sizeof(m_stream_sources)); - m_index_buffer = NULL; - - m_VtxDeclChanged = false; - m_PixelShaderChanged = false; - m_VertexShaderChanged = false; - memset(m_stream_sources_Changed, 0 , sizeof(m_stream_sources_Changed)); - m_index_buffer_Changed = false; - // Device state would normally be set here - return S_OK; -} - -void Close() -{ - UnloadD3DX9(); - - if (back_buffer_z) - back_buffer_z->Release(); - back_buffer_z = NULL; - if( back_buffer ) - back_buffer->Release(); - back_buffer = NULL; - - ULONG references = dev->Release(); - if (references) - ERROR_LOG(VIDEO, "Unreleased references: %i.", references); - - dev = NULL; -} - -const D3DCAPS9 &GetCaps() -{ - return caps; -} - -// returns true if size was changed -bool FixTextureSize(int& width, int& height) -{ - int oldw = width, oldh = height; - - // conditional nonpow2 support should work fine for us - if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)) - { - // all texture dimensions need to be powers of two - width = (int)MakePow2((u32)width); - height = (int)MakePow2((u32)height); - } - if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) - { - width = height = max(width, height); - } - - width = min(width, (int)caps.MaxTextureWidth); - height = min(height, (int)caps.MaxTextureHeight); - - return (width != oldw) || (height != oldh); -} - -// returns true if format is supported -bool CheckTextureSupport(DWORD usage, D3DFORMAT tex_format) -{ - return D3D_OK == D3D->CheckDeviceFormat(cur_adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, usage, D3DRTYPE_TEXTURE, tex_format); -} - -bool CheckDepthStencilSupport(D3DFORMAT target_format, D3DFORMAT depth_format) -{ - return D3D_OK == D3D->CheckDepthStencilMatch(cur_adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, target_format, depth_format); -} - -D3DFORMAT GetSupportedDepthTextureFormat() -{ - for (int i = 0; i < sizeof(DepthFormats)/sizeof(D3DFORMAT); ++i) - if (CheckTextureSupport(D3DUSAGE_DEPTHSTENCIL, DepthFormats[i])) - return DepthFormats[i]; - - return D3DFMT_UNKNOWN; -} - -D3DFORMAT GetSupportedDepthSurfaceFormat(D3DFORMAT target_format) -{ - for (int i = 0; i < sizeof(DepthFormats)/sizeof(D3DFORMAT); ++i) - if (CheckDepthStencilSupport(target_format, DepthFormats[i])) - return DepthFormats[i]; - - return D3DFMT_UNKNOWN; -} - -const char *VertexShaderVersionString() -{ - int version = ((caps.VertexShaderVersion >> 8) & 0xFF); - return vsVersions[std::min(4, version)]; -} - -const char *PixelShaderVersionString() -{ - int version = ((caps.PixelShaderVersion >> 8) & 0xFF); - return psVersions[std::min(4, version)]; -} - -LPDIRECT3DSURFACE9 GetBackBufferSurface() -{ - return back_buffer; -} - -LPDIRECT3DSURFACE9 GetBackBufferDepthSurface() -{ - return back_buffer_z; -} - -void ShowD3DError(HRESULT err) -{ - switch (err) - { - case D3DERR_DEVICELOST: - PanicAlert("Device Lost"); - break; - case D3DERR_INVALIDCALL: - PanicAlert("Invalid Call"); - break; - case D3DERR_DRIVERINTERNALERROR: - PanicAlert("Driver Internal Error"); - break; - case D3DERR_OUTOFVIDEOMEMORY: - PanicAlert("Out of vid mem"); - break; - default: - // MessageBox(0,_T("Other error or success"),_T("ERROR"),0); - break; - } -} - -void Reset() -{ - if (dev) - { - // ForgetCachedState(); - - // Can't keep a pointer around to the backbuffer surface when resetting. - if (back_buffer_z) - back_buffer_z->Release(); - back_buffer_z = NULL; - back_buffer->Release(); - back_buffer = NULL; - - D3DPRESENT_PARAMETERS d3dpp; - InitPP(cur_adapter, resolution, multisample, &d3dpp); - HRESULT hr = dev->Reset(&d3dpp); - ShowD3DError(hr); - - dev->GetRenderTarget(0, &back_buffer); - if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND) - back_buffer_z = NULL; - ApplyCachedState(); - } -} - -int GetBackBufferWidth() -{ - return xres; -} - -int GetBackBufferHeight() -{ - return yres; -} - -bool BeginFrame() -{ - if (bFrameInProgress) - { - PanicAlert("BeginFrame WTF"); - return false; - } - bFrameInProgress = true; - if (dev) - { - dev->BeginScene(); - return true; - } - else - return false; -} - -void EndFrame() -{ - if (!bFrameInProgress) - { - PanicAlert("EndFrame WTF"); - return; - } - bFrameInProgress = false; - dev->EndScene(); -} - -void Present() -{ - if (dev) - { - dev->Present(NULL, NULL, NULL, NULL); - } -} - -void ApplyCachedState() -{ - for (int sampler = 0; sampler < 8; sampler++) - { - for (int type = 0; type < MaxSamplerTypes; type++) - { - if(m_SamplerStatesSet[sampler][type]) - dev->SetSamplerState(sampler, (D3DSAMPLERSTATETYPE)type, m_SamplerStates[sampler][type]); - } - } - - for (int rs = 0; rs < MaxRenderStates; rs++) - { - if (m_RenderStatesSet[rs]) - dev->SetRenderState((D3DRENDERSTATETYPE)rs, m_RenderStates[rs]); - } - - // We don't bother restoring these so let's just wipe the state copy - // so no stale state is around. - memset(m_Textures, 0, sizeof(m_Textures)); - memset(m_TextureStageStatesSet, 0, sizeof(m_TextureStageStatesSet)); - memset(m_TextureStageStatesChanged, 0, sizeof(m_TextureStageStatesChanged)); - m_VtxDecl = NULL; - m_PixelShader = NULL; - m_VertexShader = NULL; - memset(m_stream_sources, 0, sizeof(m_stream_sources)); - m_index_buffer = NULL; - m_VtxDeclChanged = false; - m_PixelShaderChanged = false; - m_VertexShaderChanged = false; - memset(m_stream_sources_Changed, 0 , sizeof(m_stream_sources_Changed)); - m_index_buffer_Changed = false; -} - -void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture) -{ - if (m_Textures[Stage] != pTexture) - { - m_Textures[Stage] = pTexture; - dev->SetTexture(Stage, pTexture); - } -} - -void RefreshRenderState(D3DRENDERSTATETYPE State) -{ - if(m_RenderStatesSet[State] && m_RenderStatesChanged[State]) - { - dev->SetRenderState(State, m_RenderStates[State]); - m_RenderStatesChanged[State] = false; - } -} - -void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value) -{ - if (m_RenderStates[State] != Value || !m_RenderStatesSet[State]) - { - m_RenderStates[State] = Value; - m_RenderStatesSet[State] = true; - m_RenderStatesChanged[State] = false; - dev->SetRenderState(State, Value); - } -} - -void ChangeRenderState(D3DRENDERSTATETYPE State, DWORD Value) -{ - if (m_RenderStates[State] != Value || !m_RenderStatesSet[State]) - { - m_RenderStatesChanged[State] = m_RenderStatesSet[State]; - dev->SetRenderState(State, Value); - } - else - { - m_RenderStatesChanged[State] = false; - } -} - -void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) -{ - if (m_TextureStageStates[Stage][Type] != Value || !m_TextureStageStatesSet[Stage][Type]) - { - m_TextureStageStates[Stage][Type] = Value; - m_TextureStageStatesSet[Stage][Type]=true; - m_TextureStageStatesChanged[Stage][Type]=false; - dev->SetTextureStageState(Stage, Type, Value); - } -} - -void RefreshTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type) -{ - if(m_TextureStageStatesSet[Stage][Type] && m_TextureStageStatesChanged[Stage][Type]) - { - dev->SetTextureStageState(Stage, Type, m_TextureStageStates[Stage][Type]); - m_TextureStageStatesChanged[Stage][Type] = false; - } -} - -void ChangeTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) -{ - if (m_TextureStageStates[Stage][Type] != Value || !m_TextureStageStatesSet[Stage][Type]) - { - m_TextureStageStatesChanged[Stage][Type] = m_TextureStageStatesSet[Stage][Type]; - dev->SetTextureStageState(Stage, Type, Value); - } - else - { - m_TextureStageStatesChanged[Stage][Type] = false; - } -} - -void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) -{ - if (m_SamplerStates[Sampler][Type] != Value || !m_SamplerStatesSet[Sampler][Type]) - { - m_SamplerStates[Sampler][Type] = Value; - m_SamplerStatesSet[Sampler][Type] = true; - m_SamplerStatesChanged[Sampler][Type] = false; - dev->SetSamplerState(Sampler, Type, Value); - } -} - -void RefreshSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type) -{ - if(m_SamplerStatesSet[Sampler][Type] && m_SamplerStatesChanged[Sampler][Type]) - { - dev->SetSamplerState(Sampler, Type, m_SamplerStates[Sampler][Type]); - m_SamplerStatesChanged[Sampler][Type] = false; - } -} - -void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) -{ - if (m_SamplerStates[Sampler][Type] != Value || !m_SamplerStatesSet[Sampler][Type]) - { - m_SamplerStatesChanged[Sampler][Type] = m_SamplerStatesSet[Sampler][Type]; - dev->SetSamplerState(Sampler, Type, Value); - } - else - { - m_SamplerStatesChanged[Sampler][Type] = false; - } -} - -void RefreshVertexDeclaration() -{ - if (m_VtxDeclChanged) - { - dev->SetVertexDeclaration(m_VtxDecl); - m_VtxDeclChanged = false; - } -} - -void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl) -{ - if (decl != m_VtxDecl) - { - dev->SetVertexDeclaration(decl); - m_VtxDecl = decl; - m_VtxDeclChanged = false; - } -} - -void ChangeVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl) -{ - if (decl != m_VtxDecl) { - dev->SetVertexDeclaration(decl); - m_VtxDeclChanged = true; - } -} - -void ChangeVertexShader(LPDIRECT3DVERTEXSHADER9 shader) -{ - if (shader != m_VertexShader) - { - dev->SetVertexShader(shader); - m_VertexShaderChanged = true; - } -} - -void RefreshVertexShader() -{ - if (m_VertexShaderChanged) - { - dev->SetVertexShader(m_VertexShader); - m_VertexShaderChanged = false; - } -} - -void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader) -{ - if (shader != m_VertexShader) - { - dev->SetVertexShader(shader); - m_VertexShader = shader; - m_VertexShaderChanged = false; - } -} - -void RefreshPixelShader() -{ - if (m_PixelShaderChanged) - { - dev->SetPixelShader(m_PixelShader); - m_PixelShaderChanged = false; - } -} - -void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader) -{ - if (shader != m_PixelShader) - { - dev->SetPixelShader(shader); - m_PixelShader = shader; - m_PixelShaderChanged = false; - } -} - -void ChangePixelShader(LPDIRECT3DPIXELSHADER9 shader) -{ - if (shader != m_PixelShader) - { - dev->SetPixelShader(shader); - m_PixelShaderChanged = true; - } -} - -void SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) -{ - if (m_stream_sources[StreamNumber].OffsetInBytes != OffsetInBytes - || m_stream_sources[StreamNumber].pStreamData != pStreamData - || m_stream_sources[StreamNumber].Stride != Stride) - { - m_stream_sources[StreamNumber].OffsetInBytes = OffsetInBytes; - m_stream_sources[StreamNumber].pStreamData = pStreamData; - m_stream_sources[StreamNumber].Stride = Stride; - dev->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride); - m_stream_sources_Changed[StreamNumber] = false; - } -} - -void ChangeStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) -{ - if (m_stream_sources[StreamNumber].OffsetInBytes != OffsetInBytes - || m_stream_sources[StreamNumber].pStreamData != pStreamData - || m_stream_sources[StreamNumber].Stride != Stride) - { - dev->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride); - m_stream_sources_Changed[StreamNumber] = true; - } - -} - -void RefreshStreamSource(UINT StreamNumber) -{ - if (m_PixelShaderChanged) - { - dev->SetStreamSource( - StreamNumber, - m_stream_sources[StreamNumber].pStreamData, - m_stream_sources[StreamNumber].OffsetInBytes, - m_stream_sources[StreamNumber].Stride); - m_stream_sources_Changed[StreamNumber] = false; - } -} - -void SetIndices(LPDIRECT3DINDEXBUFFER9 pIndexData) -{ - if(pIndexData != m_index_buffer) - { - m_index_buffer = pIndexData; - dev->SetIndices(pIndexData); - m_index_buffer_Changed = false; - } -} - -void ChangeIndices(LPDIRECT3DINDEXBUFFER9 pIndexData) -{ - if(pIndexData != m_index_buffer) - { - dev->SetIndices(pIndexData); - m_index_buffer_Changed = true; - } -} - -void RefreshIndices() -{ - if (m_index_buffer_Changed) - { - dev->SetIndices(m_index_buffer); - m_index_buffer_Changed = false; - } -} - - - -} // namespace - -} // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h deleted file mode 100644 index b5a664998950..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#pragma once - -#include -#include - -#include - -#include "Common.h" - -namespace DX9 -{ - -namespace D3D -{ - -// From http://developer.amd.com/gpu_assets/Advanced%20DX9%20Capabilities%20for%20ATI%20Radeon%20Cards.pdf -// Magic FourCC's to unlock undocumented D3D9 features: - -// Z texture formats -#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z'))) -#define FOURCC_RAWZ ((D3DFORMAT)(MAKEFOURCC('R','A','W','Z'))) -#define FOURCC_DF24 ((D3DFORMAT)(MAKEFOURCC('D','F','2','4'))) -#define FOURCC_DF16 ((D3DFORMAT)(MAKEFOURCC('D','F','1','6'))) - -// Depth buffer resolve: -#define FOURCC_RESZ ((D3DFORMAT)(MAKEFOURCC('R','E','S','Z'))) -#define RESZ_CODE 0x7fa05000 - -// Null render target to do Z-only shadow maps: (probably not useful for Dolphin) -#define FOURCC_NULL ((D3DFORMAT)(MAKEFOURCC('N','U','L','L'))) - -bool IsATIDevice(); -bool IsIntelDevice(); -HRESULT Init(); -HRESULT Create(int adapter, HWND wnd, int resolution, int aa_mode, bool auto_depth); -void Close(); -void Shutdown(); - -// Direct access to the device. -extern LPDIRECT3DDEVICE9 dev; -extern bool bFrameInProgress; - -void Reset(); -bool BeginFrame(); -void EndFrame(); -void Present(); -bool CanUseINTZ(); - -int GetBackBufferWidth(); -int GetBackBufferHeight(); -LPDIRECT3DSURFACE9 GetBackBufferSurface(); -LPDIRECT3DSURFACE9 GetBackBufferDepthSurface(); -LPDIRECT3DVERTEXBUFFER9 GetquadVB(); -LPDIRECT3DVERTEXDECLARATION9 GetBasicvertexDecl(); -const D3DCAPS9 &GetCaps(); -const char *PixelShaderVersionString(); -const char *VertexShaderVersionString(); -void ShowD3DError(HRESULT err); - -// returns true if size was changed -bool FixTextureSize(int& width, int& height); - -// returns true if format is supported -bool CheckTextureSupport(DWORD usage, D3DFORMAT tex_format); -bool CheckDepthStencilSupport(D3DFORMAT target_format, D3DFORMAT depth_format); - -D3DFORMAT GetSupportedDepthTextureFormat(); -D3DFORMAT GetSupportedDepthSurfaceFormat(D3DFORMAT target_format); - -// The following are "filtered" versions of the corresponding D3Ddev-> functions. -void SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture); -void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value); -void RefreshRenderState(D3DRENDERSTATETYPE State); -void ChangeRenderState(D3DRENDERSTATETYPE State, DWORD Value); - -void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value); -void RefreshTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type); -void ChangeTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value); - -void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value); -void RefreshSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type); -void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value); - -void RefreshVertexDeclaration(); -void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl); -void ChangeVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl); - -void RefreshVertexShader(); -void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader); -void ChangeVertexShader(LPDIRECT3DVERTEXSHADER9 shader); - -void RefreshPixelShader(); -void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader); -void ChangePixelShader(LPDIRECT3DPIXELSHADER9 shader); - -void SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride); -void ChangeStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride); -void RefreshStreamSource(UINT StreamNumber); - -void SetIndices(LPDIRECT3DINDEXBUFFER9 pIndexData); -void ChangeIndices(LPDIRECT3DINDEXBUFFER9 pIndexData); -void RefreshIndices(); - -void ApplyCachedState(); - -// Utility functions for vendor specific hacks. So far, just the one. -void EnableAlphaToCoverage(); - -struct Resolution -{ - char name[32]; - int xres; - int yres; - std::set bitdepths; - std::set refreshes; -}; - -struct AALevel -{ - AALevel(const char *n, D3DMULTISAMPLE_TYPE m, int q) { - strncpy(name, n, 32); - name[31] = '\0'; - ms_setting = m; - qual_setting = q; - } - char name[32]; - D3DMULTISAMPLE_TYPE ms_setting; - int qual_setting; -}; - -struct Adapter -{ - D3DADAPTER_IDENTIFIER9 ident; - std::vector resolutions; - std::vector aa_levels; - bool supports_alpha_to_coverage; - - // Magic render targets, see the top of this file. - bool supports_intz; - bool supports_rawz; - bool supports_resz; - bool supports_null; -}; - -const Adapter &GetAdapter(int i); -const Adapter &GetCurAdapter(); -int GetNumAdapters(); - -} // namespace - -} // namespace DX9 - - -// Used to not require the SDK and runtime versions to match: -// Linking with d3dx9.lib makes the most recent d3dx9_xx.dll of the -// compiler's SDK an actually unnecessary requirement. -// Add any d3dx9 functions which you want to use here and load them in LoadD3DX9() -typedef HRESULT (WINAPI* D3DXSAVESURFACETOFILEATYPE)(LPCSTR, D3DXIMAGE_FILEFORMAT, LPDIRECT3DSURFACE9, CONST PALETTEENTRY*, CONST RECT*); -typedef HRESULT (WINAPI* D3DXSAVETEXTURETOFILEATYPE)(LPCSTR, D3DXIMAGE_FILEFORMAT, LPDIRECT3DBASETEXTURE9, CONST PALETTEENTRY*); -typedef HRESULT (WINAPI* D3DXCOMPILESHADERTYPE)(LPCSTR, UINT, CONST D3DXMACRO*, LPD3DXINCLUDE, LPCSTR, LPCSTR, DWORD, LPD3DXBUFFER*, LPD3DXBUFFER*, LPD3DXCONSTANTTABLE*); - -extern D3DXSAVESURFACETOFILEATYPE PD3DXSaveSurfaceToFileA; -extern D3DXSAVETEXTURETOFILEATYPE PD3DXSaveTextureToFileA; -extern D3DXCOMPILESHADERTYPE PD3DXCompileShader; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp deleted file mode 100644 index 8649ebfac242..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include -#include - -#include "VideoConfig.h" -#include "D3DShader.h" - -namespace DX9 -{ - -namespace D3D -{ - -// bytecode->shader. -LPDIRECT3DVERTEXSHADER9 CreateVertexShaderFromByteCode(const u8 *bytecode, int len) -{ - LPDIRECT3DVERTEXSHADER9 v_shader; - HRESULT hr = D3D::dev->CreateVertexShader((DWORD *)bytecode, &v_shader); - if (FAILED(hr)) - return NULL; - - return v_shader; -} - -// code->bytecode. -bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecodelen) -{ - LPD3DXBUFFER shaderBuffer = NULL; - LPD3DXBUFFER errorBuffer = NULL; - HRESULT hr = PD3DXCompileShader(code, len, 0, 0, "main", D3D::VertexShaderVersionString(), - 0, &shaderBuffer, &errorBuffer, 0); - if (FAILED(hr)) - { - static int num_failures = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "%sbad_vs_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file; - OpenFStream(file, szTemp, std::ios_base::out); - file << code; - file.close(); - - PanicAlert("Failed to compile vertex shader!\nThis usually happens when trying to use Dolphin with an outdated GPU or integrated GPU like the Intel GMA series.\n\nIf you're sure this is Dolphin's error anyway, post the contents of %s along with this error message at the forums.\n\nDebug info (%s):\n%s", - szTemp, - D3D::VertexShaderVersionString(), - (char*)errorBuffer->GetBufferPointer()); - - *bytecode = NULL; - *bytecodelen = 0; - } - else - { - *bytecodelen = shaderBuffer->GetBufferSize(); - *bytecode = new u8[*bytecodelen]; - memcpy(*bytecode, shaderBuffer->GetBufferPointer(), *bytecodelen); - } - - //cleanup - if (shaderBuffer) - shaderBuffer->Release(); - if (errorBuffer) - errorBuffer->Release(); - return SUCCEEDED(hr) ? true : false; -} - -// bytecode->shader -LPDIRECT3DPIXELSHADER9 CreatePixelShaderFromByteCode(const u8 *bytecode, int len) -{ - LPDIRECT3DPIXELSHADER9 p_shader; - HRESULT hr = D3D::dev->CreatePixelShader((DWORD *)bytecode, &p_shader); - if (FAILED(hr)) - return NULL; - - return p_shader; -} - -// code->bytecode -bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodelen) -{ - LPD3DXBUFFER shaderBuffer = 0; - LPD3DXBUFFER errorBuffer = 0; - - // Someone: - // For some reason, I had this kind of errors : "Shader uses texture addressing operations - // in a dependency chain that is too complex for the target shader model (ps_2_0) to handle." - HRESULT hr = PD3DXCompileShader(code, len, 0, 0, "main", D3D::PixelShaderVersionString(), - 0, &shaderBuffer, &errorBuffer, 0); - - if (FAILED(hr)) - { - static int num_failures = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "%sbad_ps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file; - OpenFStream(file, szTemp, std::ios_base::out); - file << code; - file.close(); - - PanicAlert("Failed to compile pixel shader!\nThis usually happens when trying to use Dolphin with an outdated GPU or integrated GPU like the Intel GMA series.\n\nIf you're sure this is Dolphin's error anyway, post the contents of %s along with this error message at the forums.\n\nDebug info (%s):\n%s", - szTemp, - D3D::PixelShaderVersionString(), - (char*)errorBuffer->GetBufferPointer()); - - *bytecode = NULL; - *bytecodelen = 0; - } - else - { - *bytecodelen = shaderBuffer->GetBufferSize(); - *bytecode = new u8[*bytecodelen]; - memcpy(*bytecode, shaderBuffer->GetBufferPointer(), *bytecodelen); - } - - //cleanup - if (shaderBuffer) - shaderBuffer->Release(); - if (errorBuffer) - errorBuffer->Release(); - return SUCCEEDED(hr) ? true : false; -} - -LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len) -{ - u8 *bytecode; - int bytecodelen; - if (CompileVertexShader(code, len, &bytecode, &bytecodelen)) - { - LPDIRECT3DVERTEXSHADER9 v_shader = CreateVertexShaderFromByteCode(bytecode, len); - delete [] bytecode; - return v_shader; - } - return NULL; -} - -LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char* code, unsigned int len) -{ - u8 *bytecode; - int bytecodelen; - if (CompilePixelShader(code, len, &bytecode, &bytecodelen)) - { - LPDIRECT3DPIXELSHADER9 p_shader = CreatePixelShaderFromByteCode(bytecode, len); - delete [] bytecode; - return p_shader; - } - return NULL; -} - -} // namespace - -} // namespace DX9 \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.h deleted file mode 100644 index 449f2dacea25..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#pragma once - -#include "D3DBase.h" - -namespace DX9 -{ - -namespace D3D -{ - LPDIRECT3DVERTEXSHADER9 CreateVertexShaderFromByteCode(const u8 *bytecode, int len); - LPDIRECT3DPIXELSHADER9 CreatePixelShaderFromByteCode(const u8 *bytecode, int len); - - // The returned bytecode buffers should be delete[]-d. - bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecodelen); - bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodelen); - - // Utility functions - LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len); - LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char *code, unsigned int len); -} - -} // namespace DX9 \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp deleted file mode 100644 index f16e308eefa0..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp +++ /dev/null @@ -1,406 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include "D3DBase.h" -#include "D3DTexture.h" - -#include "CPUDetect.h" - -#if _M_SSE >= 0x401 -#include -#include -#elif _M_SSE >= 0x301 && !(defined __GNUC__ && !defined __SSSE3__) -#include -#endif - -namespace DX9 -{ - -namespace D3D -{ - -void ConvertRGBA_BGRA_SSE2(u32 *dst, const int dstPitch, u32 *pIn, const int width, const int height, const int pitch) -{ - // Converts RGBA to BGRA: - // TODO: this would be totally unnecessary if we just change the TextureDecoder_RGBA to decode - // to BGRA instead. - for (int y = 0; y < height; y++, pIn += pitch) - { - u8 *pIn8 = (u8 *)pIn; - u8 *pBits = (u8 *)((u8*)dst + (y * dstPitch)); - - // Batch up loads/stores into 16 byte chunks to use SSE2 efficiently: - int sse2blocks = (width * 4) / 16; - int sse2remainder = (width * 4) & 15; - - // Do conversions in batches of 16 bytes: - if (sse2blocks > 0) - { - // Generate a constant of all FF bytes: - const __m128i allFFs128 = _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()); - __m128i *src128 = (__m128i *)pIn8; - __m128i *dst128 = (__m128i *)pBits; - - // Increment by 16 bytes at a time: - for (int i = 0; i < sse2blocks; ++i, ++dst128, ++src128) - { - // Load up 4 colors simultaneously: - __m128i rgba = _mm_loadu_si128(src128); - // Swap the R and B components: - // Isolate the B component and shift it left 16 bits: - // ABGR - const __m128i bMask = _mm_srli_epi32(allFFs128, 24); - const __m128i bNew = _mm_slli_epi32(_mm_and_si128(rgba, bMask), 16); - // Isolate the R component and shift it right 16 bits: - const __m128i rMask = _mm_slli_epi32(bMask, 16); - const __m128i rNew = _mm_srli_epi32(_mm_and_si128(rgba, rMask), 16); - // Now mask off the old R and B components from the rgba data to get 0g0a: - const __m128i _g_a = _mm_or_si128( - _mm_and_si128( - rgba, - _mm_or_si128( - _mm_slli_epi32(bMask, 8), - _mm_slli_epi32(rMask, 8) - ) - ), - _mm_or_si128(rNew, bNew) - ); - // Finally, OR up all the individual components to get BGRA: - const __m128i bgra = _mm_or_si128(_g_a, _mm_or_si128(rNew, bNew)); - _mm_storeu_si128(dst128, bgra); - } - } - - // Take the remainder colors at the end of the row that weren't able to - // be included into the last 16 byte chunk: - if (sse2remainder > 0) - { - for (int x = (sse2blocks * 16); x < (width * 4); x += 4) - { - pBits[x + 0] = pIn8[x + 2]; - pBits[x + 1] = pIn8[x + 1]; - pBits[x + 2] = pIn8[x + 0]; - pBits[x + 3] = pIn8[x + 3]; - } - } - } - - // Memory fence to make sure the stores are good: - _mm_mfence(); -} - -void ConvertRGBA_BGRA_SSSE3(u32 *dst, const int dstPitch, u32 *pIn, const int width, const int height, const int pitch) -{ - __m128i mask = _mm_set_epi8(15, 12, 13, 14, 11, 8, 9, 10, 7, 4, 5, 6, 3, 0, 1, 2); - for (int y = 0; y < height; y++, pIn += pitch) - { - u8 *pIn8 = (u8 *)pIn; - u8 *pBits = (u8 *)((u8*)dst + (y * dstPitch)); - - // Batch up loads/stores into 16 byte chunks to use SSE2 efficiently: - int ssse3blocks = (width * 4) / 16; - int ssse3remainder = (width * 4) & 15; - - // Do conversions in batches of 16 bytes: - if (ssse3blocks > 0) - { - __m128i *src128 = (__m128i *)pIn8; - __m128i *dst128 = (__m128i *)pBits; - - // Increment by 16 bytes at a time: - for (int i = 0; i < ssse3blocks; ++i, ++dst128, ++src128) - { - _mm_storeu_si128(dst128, _mm_shuffle_epi8(_mm_loadu_si128(src128), mask)); - } - } - - // Take the remainder colors at the end of the row that weren't able to - // be included into the last 16 byte chunk: - if (ssse3remainder > 0) - { - for (int x = (ssse3blocks * 16); x < (width * 4); x += 4) - { - pBits[x + 0] = pIn8[x + 2]; - pBits[x + 1] = pIn8[x + 1]; - pBits[x + 2] = pIn8[x + 0]; - pBits[x + 3] = pIn8[x + 3]; - } - } - } - - // Memory fence to make sure the stores are good: - _mm_mfence(); -} - -LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int levels) -{ - u32* pBuffer = (u32*)buffer; - LPDIRECT3DTEXTURE9 pTexture; - - // crazy bitmagic, sorry :) - bool isPow2 = !((width&(width-1)) || (height&(height-1))); - bool bExpand = false; - - if (fmt == D3DFMT_A8P8) { - fmt = D3DFMT_A8L8; - bExpand = true; - } - - HRESULT hr; - if (levels > 0) - hr = dev->CreateTexture(width, height, levels, 0, fmt, D3DPOOL_MANAGED, &pTexture, NULL); - else - hr = dev->CreateTexture(width, height, 0, D3DUSAGE_AUTOGENMIPMAP, fmt, D3DPOOL_MANAGED, &pTexture, NULL); - - if (FAILED(hr)) - return 0; - int level = 0; - D3DLOCKED_RECT Lock; - pTexture->LockRect(level, &Lock, NULL, 0); - switch (fmt) - { - case D3DFMT_L8: - case D3DFMT_A8: - case D3DFMT_A4L4: - { - const u8 *pIn = buffer; - for (int y = 0; y < height; y++) - { - u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch)); - memcpy(pBits, pIn, width); - pIn += pitch; - } - } - break; - case D3DFMT_R5G6B5: - { - const u16 *pIn = (u16*)buffer; - for (int y = 0; y < height; y++) - { - u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch)); - memcpy(pBits, pIn, width * 2); - pIn += pitch; - } - } - break; - case D3DFMT_A8L8: - { - if (bExpand) { // I8 - const u8 *pIn = buffer; - // TODO(XK): Find a better way that does not involve either unpacking - // or downsampling (i.e. A4L4) - for (int y = 0; y < height; y++) - { - u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch)); - for(int i = 0; i < width * 2; i += 2) { - pBits[i] = pIn[i / 2]; - pBits[i + 1] = pIn[i / 2]; - } - pIn += pitch; - } - } else { // IA8 - const u16 *pIn = (u16*)buffer; - - for (int y = 0; y < height; y++) - { - u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch)); - memcpy(pBits, pIn, width * 2); - pIn += pitch; - } - } - } - break; - case D3DFMT_A8R8G8B8: - { - if(pitch * 4 == Lock.Pitch && !swap_r_b) - { - memcpy(Lock.pBits,buffer,Lock.Pitch*height); - } - else - { - u32* pIn = pBuffer; - if (!swap_r_b) { - for (int y = 0; y < height; y++) - { - u32 *pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch)); - memcpy(pBits, pIn, width * 4); - pIn += pitch; - } - } else { -#if _M_SSE >= 0x301 - // Uses SSSE3 intrinsics to optimize RGBA -> BGRA swizzle: - if (cpu_info.bSSSE3) { - ConvertRGBA_BGRA_SSSE3((u32 *)Lock.pBits, Lock.Pitch, pIn, width, height, pitch); - } else -#endif - // Uses SSE2 intrinsics to optimize RGBA -> BGRA swizzle: - { - ConvertRGBA_BGRA_SSE2((u32 *)Lock.pBits, Lock.Pitch, pIn, width, height, pitch); - } -#if 0 - for (int y = 0; y < height; y++) - { - u8 *pIn8 = (u8 *)pIn; - u8 *pBits = (u8 *)((u8*)Lock.pBits + (y * Lock.Pitch)); - for (int x = 0; x < width * 4; x += 4) { - pBits[x + 0] = pIn8[x + 2]; - pBits[x + 1] = pIn8[x + 1]; - pBits[x + 2] = pIn8[x + 0]; - pBits[x + 3] = pIn8[x + 3]; - } - pIn += pitch; - } -#endif - } - } - } - break; - case D3DFMT_DXT1: - memcpy(Lock.pBits,buffer,((width+3)/4)*((height+3)/4)*8); - break; - default: - PanicAlert("D3D: Invalid texture format %i", fmt); - } - pTexture->UnlockRect(level); - return pTexture; -} - -LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFORMAT fmt) -{ - LPDIRECT3DTEXTURE9 pTexture; - // crazy bitmagic, sorry :) - bool isPow2 = !((width&(width-1)) || (height&(height-1))); - bool bExpand = false; - HRESULT hr; - // TODO(ector): Allow mipmaps for non-pow textures on newer cards? - // TODO(ector): Use the game-specified mipmaps? - if (!isPow2) - hr = dev->CreateTexture(width, height, 1, 0, fmt, D3DPOOL_MANAGED, &pTexture, NULL); - else - hr = dev->CreateTexture(width, height, 0, D3DUSAGE_AUTOGENMIPMAP, fmt, D3DPOOL_MANAGED, &pTexture, NULL); - - if (FAILED(hr)) - return 0; - return pTexture; -} - -void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int level) -{ - u32* pBuffer = (u32*)buffer; - D3DLOCKED_RECT Lock; - pTexture->LockRect(level, &Lock, NULL, 0); - u32* pIn = pBuffer; - - bool bExpand = false; - - if (fmt == D3DFMT_A8P8) { - fmt = D3DFMT_A8L8; - bExpand = true; - } - switch (fmt) - { - case D3DFMT_A8R8G8B8: - if(pitch * 4 == Lock.Pitch && !swap_r_b) - { - memcpy(Lock.pBits, pBuffer, Lock.Pitch*height); - } - else if (!swap_r_b) - { - for (int y = 0; y < height; y++) - { - u32 *pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch)); - memcpy(pBits, pIn, width * 4); - pIn += pitch; - } - } - else - { -#if _M_SSE >= 0x301 - // Uses SSSE3 intrinsics to optimize RGBA -> BGRA swizzle: - if (cpu_info.bSSSE3) { - ConvertRGBA_BGRA_SSSE3((u32 *)Lock.pBits, Lock.Pitch, pIn, width, height, pitch); - } else -#endif - // Uses SSE2 intrinsics to optimize RGBA -> BGRA swizzle: - { - ConvertRGBA_BGRA_SSE2((u32 *)Lock.pBits, Lock.Pitch, pIn, width, height, pitch); - } -#if 0 - for (int y = 0; y < height; y++) - { - u8 *pIn8 = (u8 *)pIn; - u8 *pBits = (u8 *)((u8*)Lock.pBits + (y * Lock.Pitch)); - for (int x = 0; x < width * 4; x += 4) - { - pBits[x + 0] = pIn8[x + 2]; - pBits[x + 1] = pIn8[x + 1]; - pBits[x + 2] = pIn8[x + 0]; - pBits[x + 3] = pIn8[x + 3]; - } - pIn += pitch; - } -#endif - } - break; - case D3DFMT_L8: - case D3DFMT_A8: - case D3DFMT_A4L4: - { - const u8 *pIn = buffer; - for (int y = 0; y < height; y++) - { - u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch)); - memcpy(pBits, pIn, width); - pIn += pitch; - } - } - break; - case D3DFMT_R5G6B5: - { - const u16 *pIn = (u16*)buffer; - for (int y = 0; y < height; y++) - { - u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch)); - memcpy(pBits, pIn, width * 2); - pIn += pitch; - } - } - break; - case D3DFMT_A8L8: - { - if (bExpand) { // I8 - const u8 *pIn = buffer; - // TODO(XK): Find a better way that does not involve either unpacking - // or downsampling (i.e. A4L4) - for (int y = 0; y < height; y++) - { - u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch)); - for(int i = 0; i < width * 2; i += 2) { - pBits[i] = pIn[i / 2]; - pBits[i + 1] = pIn[i / 2]; - } - pIn += pitch; - } - } else { // IA8 - const u16 *pIn = (u16*)buffer; - - for (int y = 0; y < height; y++) - { - u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch)); - memcpy(pBits, pIn, width * 2); - pIn += pitch; - } - } - } - break; - case D3DFMT_DXT1: - memcpy(Lock.pBits,buffer,((width+3)/4)*((height+3)/4)*8); - break; - } - pTexture->UnlockRect(level); -} - -} // namespace - -} // namespace DX9 \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.h deleted file mode 100644 index 54ed57000a9b..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#pragma once - -#include "D3DBase.h" - -namespace DX9 -{ - -namespace D3D -{ - LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt = D3DFMT_A8R8G8B8, bool swap_r_b = false, int levels = 1); - void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int level = 0); - LPDIRECT3DTEXTURE9 CreateRenderTarget(const int width, const int height); - LPDIRECT3DSURFACE9 CreateDepthStencilSurface(const int width, const int height); - LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFORMAT fmt); -} - -} // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp deleted file mode 100644 index 066f99ad3fb3..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp +++ /dev/null @@ -1,463 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include "Common.h" -#include "StringUtil.h" - -#include "D3DBase.h" -#include "D3DUtil.h" -#include "Render.h" -#include "PixelShaderCache.h" -#include "VertexShaderCache.h" - -namespace DX9 -{ - -namespace D3D -{ -CD3DFont font; - -#define MAX_NUM_VERTICES 50*6 -struct FONT2DVERTEX { - float x,y,z; - float rhw; - u32 color; - float tu, tv; -}; - -#define D3DFVF_FONT2DVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1) -#define D3DFVF_FONT3DVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_NORMAL|D3DFVF_TEX1) - -inline FONT2DVERTEX InitFont2DVertex(float x, float y, u32 color, float tu, float tv) -{ - FONT2DVERTEX v; v.x=x; v.y=y; v.z=0; v.rhw=1.0f; v.color = color; v.tu = tu; v.tv = tv; - return v; -} - -CD3DFont::CD3DFont() -{ - m_pTexture = NULL; - m_pVB = NULL; -} - -enum {m_dwTexWidth = 512, m_dwTexHeight = 512}; - -int CD3DFont::Init() -{ - // Create vertex buffer for the letters - HRESULT hr; - if (FAILED(hr = dev->CreateVertexBuffer(MAX_NUM_VERTICES*sizeof(FONT2DVERTEX), - D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_pVB, NULL))) - { - return hr; - } - m_fTextScale = 1.0f; // Draw fonts into texture without scaling - - // Prepare to create a bitmap - unsigned int* pBitmapBits; - BITMAPINFO bmi; - ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = (int)m_dwTexWidth; - bmi.bmiHeader.biHeight = -(int)m_dwTexHeight; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biBitCount = 32; - - // Create a DC and a bitmap for the font - HDC hDC = CreateCompatibleDC(NULL); - HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0); - SetMapMode(hDC, MM_TEXT); - - // Create a font. By specifying ANTIALIASED_QUALITY, we might get an - // antialiased font, but this is not guaranteed. - // We definitely don't want to get it cleartype'd, anyway. - int m_dwFontHeight = 24; - int nHeight = -MulDiv(m_dwFontHeight, int(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72); - int dwBold = FW_NORMAL; ///FW_BOLD - HFONT hFont = CreateFont(nHeight, 0, 0, 0, dwBold, 0, - FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, - CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, - VARIABLE_PITCH, _T("Tahoma")); - if (NULL == hFont) - return E_FAIL; - - HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap); - HGDIOBJ hOldFont = SelectObject(hDC, hFont); - - // Set text properties - SetTextColor(hDC, 0xFFFFFF); - SetBkColor (hDC, 0); - SetTextAlign(hDC, TA_TOP); - - // Loop through all printable characters and output them to the bitmap - // Meanwhile, keep track of the corresponding tex coords for each character. - int x = 0, y = 0; - char str[2] = "\0"; - for (int c = 0; c < 127 - 32; c++) - { - str[0] = c + 32; - SIZE size; - GetTextExtentPoint32A(hDC, str, 1, &size); - if ((int)(x+size.cx+1) > m_dwTexWidth) - { - x = 0; - y += size.cy + 1; - } - - ExtTextOutA(hDC, x+1, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL); - m_fTexCoords[c][0] = ((float)(x+0))/m_dwTexWidth; - m_fTexCoords[c][1] = ((float)(y+0))/m_dwTexHeight; - m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth; - m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight; - - x += size.cx + 3; // 3 to work around annoying ij conflict (part of the j ends up with the i) - } - - // Create a new texture for the font - // possible optimization: store the converted data in a buffer and fill the texture on creation. - // That way, we can use a static texture - hr = dev->CreateTexture(m_dwTexWidth, m_dwTexHeight, 1, D3DUSAGE_DYNAMIC, - D3DFMT_A4R4G4B4, D3DPOOL_DEFAULT, &m_pTexture, NULL); - if (FAILED(hr)) - { - PanicAlert("Failed to create font texture"); - return hr; - } - - // Lock the surface and write the alpha values for the set pixels - D3DLOCKED_RECT d3dlr; - m_pTexture->LockRect(0, &d3dlr, 0, D3DLOCK_DISCARD); - int bAlpha; // 4-bit measure of pixel intensity - - for (y = 0; y < m_dwTexHeight; y++) - { - u16 *pDst16 = (u16*)((u8 *)d3dlr.pBits + y * d3dlr.Pitch); - for (x = 0; x < m_dwTexWidth; x++) - { - bAlpha = ((pBitmapBits[m_dwTexWidth * y + x] & 0xff) >> 4); - pDst16[x] = (bAlpha << 12) | 0x0fff; - } - } - - // Done updating texture, so clean up used objects - m_pTexture->UnlockRect(0); - - SelectObject(hDC, hOldbmBitmap); - DeleteObject(hbmBitmap); - - SelectObject(hDC, hOldFont); - DeleteObject(hFont); - - return S_OK; -} - -int CD3DFont::Shutdown() -{ - m_pVB->Release(); - m_pVB = NULL; - m_pTexture->Release(); - m_pTexture = NULL; - return S_OK; -} - - -const int RS[6][2] = -{ - {D3DRS_ALPHABLENDENABLE, TRUE}, - {D3DRS_SRCBLEND, D3DBLEND_SRCALPHA}, - {D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA}, - {D3DRS_CULLMODE, D3DCULL_NONE}, - {D3DRS_ZENABLE, FALSE}, - {D3DRS_FOGENABLE, FALSE}, -}; -const int TS[6][2] = -{ - {D3DTSS_COLOROP, D3DTOP_MODULATE}, - {D3DTSS_COLORARG1, D3DTA_TEXTURE}, - {D3DTSS_COLORARG2, D3DTA_DIFFUSE }, - {D3DTSS_ALPHAOP, D3DTOP_MODULATE }, - {D3DTSS_ALPHAARG1, D3DTA_TEXTURE }, - {D3DTSS_ALPHAARG2, D3DTA_DIFFUSE }, -}; - -void RestoreShaders() -{ - D3D::SetTexture(0, 0); - D3D::RefreshStreamSource(0); - D3D::RefreshIndices(); - D3D::RefreshVertexDeclaration(); - D3D::RefreshPixelShader(); - D3D::RefreshVertexShader(); -} - -void RestoreRenderStates() -{ - RestoreShaders(); - for (int i = 0; i < 6; i++) - { - D3D::RefreshRenderState((_D3DRENDERSTATETYPE)RS[i][0]); - D3D::RefreshTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0])); - } -} - -void CD3DFont::SetRenderStates() -{ - D3D::SetTexture(0, m_pTexture); - - D3D::ChangePixelShader(0); - D3D::ChangeVertexShader(0); - D3D::ChangeVertexDeclaration(0); - dev->SetFVF(D3DFVF_FONT2DVERTEX); - - for (int i = 0; i < 6; i++) - { - D3D::ChangeRenderState((_D3DRENDERSTATETYPE)RS[i][0], RS[i][1]); - D3D::ChangeTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS[i][1]); - } -} - - -int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, float spacing, u32 dwColor, const char* strText) -{ - if (!m_pVB) - return 0; - - SetRenderStates(); - D3D::ChangeStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX)); - - float vpWidth = 1; - float vpHeight = 1; - - float sx = x*vpWidth-0.5f; - float sy = y*vpHeight-0.5f; - - float fStartX = sx; - - float invLineHeight = 1.0f / ((m_fTexCoords[0][3] - m_fTexCoords[0][1]) * m_dwTexHeight); - // Fill vertex buffer - FONT2DVERTEX* pVertices; - int dwNumTriangles = 0L; - m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD); - - const char *oldstrText=strText; - //First, let's measure the text - float tw=0; - float mx=0; - float maxx=0; - - while (*strText) - { - char c = *strText++; - - if (c == ('\n')) - mx = 0; - if (c < (' ')) - continue; - - float tx1 = m_fTexCoords[c-32][0]; - float tx2 = m_fTexCoords[c-32][2]; - - float w = (tx2-tx1)*m_dwTexWidth; - w *= (fXScale*vpHeight)*invLineHeight; - mx += w + spacing*fXScale*vpWidth; - if (mx > maxx) maxx = mx; - } - - float offset = -maxx/2; - strText = oldstrText; - - float wScale = (fXScale*vpHeight)*invLineHeight; - float hScale = (fYScale*vpHeight)*invLineHeight; - - // Let's draw it - while (*strText) - { - char c = *strText++; - - if (c == ('\n')) - { - sx = fStartX; - sy += fYScale*vpHeight; - } - if (c < (' ')) - continue; - - c -= 32; - float tx1 = m_fTexCoords[c][0]; - float ty1 = m_fTexCoords[c][1]; - float tx2 = m_fTexCoords[c][2]; - float ty2 = m_fTexCoords[c][3]; - - float w = (tx2-tx1)*m_dwTexWidth; - float h = (ty2-ty1)*m_dwTexHeight; - - w *= wScale; - h *= hScale; - - FONT2DVERTEX v[6]; - v[0] = InitFont2DVertex(sx, sy+h, dwColor, tx1, ty2); - v[1] = InitFont2DVertex(sx, sy, dwColor, tx1, ty1); - v[2] = InitFont2DVertex(sx+w, sy+h, dwColor, tx2, ty2); - v[3] = InitFont2DVertex(sx+w, sy, dwColor, tx2, ty1); - v[4] = v[2]; - v[5] = v[1]; - - memcpy(pVertices, v, 6*sizeof(FONT2DVERTEX)); - - pVertices+=6; - dwNumTriangles += 2; - - if (dwNumTriangles * 3 > (MAX_NUM_VERTICES - 6)) - { - // Unlock, render, and relock the vertex buffer - m_pVB->Unlock(); - dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, dwNumTriangles); - m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD); - dwNumTriangles = 0; - } - sx += w + spacing*fXScale*vpWidth; - } - - // Unlock and render the vertex buffer - m_pVB->Unlock(); - if (dwNumTriangles > 0) - dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, dwNumTriangles); - RestoreRenderStates(); - return S_OK; -} - -/* Explanation of texture copying via drawShadedTexQuad and drawShadedTexSubQuad: - From MSDN: "When rendering 2D output using pre-transformed vertices, - care must be taken to ensure that each texel area correctly corresponds - to a single pixel area, otherwise texture distortion can occur." - => We need to subtract 0.5 from the vertex positions to properly map texels to pixels. - HOWEVER, the MSDN article talks about D3DFVF_XYZRHW vertices, which bypass the programmable pipeline. - Since we're using D3DFVF_XYZW and the programmable pipeline though, the vertex positions - are normalized to [-1;+1], i.e. we need to scale the -0.5 offset by the texture dimensions. - For example see a texture with a width of 640 pixels: - "Expected" coordinate range when using D3DFVF_XYZRHW: [0;640] - Normalizing this coordinate range for D3DFVF_XYZW: [0;640]->[-320;320]->[-1;1] - i.e. we're subtracting width/2 and dividing by width/2 - BUT: The actual range when using D3DFVF_XYZRHW needs to be [-0.5;639.5] because of the need for exact texel->pixel mapping. - We can still apply the same normalizing procedure though: - [-0.5;639.5]->[-320-0.5;320-0.5]->[-1-0.5/320;1-0.5/320] - - So generally speaking the correct coordinate range is [-1-0.5/(w/2);1-0.5/(w/2)] - which can be simplified to [-1-1/w;1-1/w]. - - Note that while for D3DFVF_XYZRHW the y coordinate of the bottom of the screen is positive, - it's negative for D3DFVF_XYZW. This is why we need to _add_ 1/h for the second position component instead of subtracting it. - - For a detailed explanation of this read the MSDN article "Directly Mapping Texels to Pixels (Direct3D 9)". -*/ -void drawShadedTexQuad(IDirect3DTexture9 *texture, - const RECT *rSource, - int SourceWidth, - int SourceHeight, - int DestWidth, - int DestHeight, - IDirect3DPixelShader9 *PShader, - IDirect3DVertexShader9 *Vshader, - float Gamma) -{ - float sw = 1.0f /(float) SourceWidth; - float sh = 1.0f /(float) SourceHeight; - float dw = 1.0f /(float) DestWidth; - float dh = 1.0f /(float) DestHeight; - float u1=((float)rSource->left) * sw; - float u2=((float)rSource->right) * sw; - float v1=((float)rSource->top) * sh; - float v2=((float)rSource->bottom) * sh; - float g = 1.0f/Gamma; - - const struct Q2DVertex { float x,y,z,rhw,u,v,w,h,G; } coords[4] = { - {-1.0f - dw,-1.0f + dh, 0.0f,1.0f, u1, v2, sw, sh, g}, - {-1.0f - dw, 1.0f + dh, 0.0f,1.0f, u1, v1, sw, sh, g}, - { 1.0f - dw,-1.0f + dh, 0.0f,1.0f, u2, v2, sw, sh, g}, - { 1.0f - dw, 1.0f + dh, 0.0f,1.0f, u2, v1, sw, sh, g} - }; - D3D::ChangeVertexShader(Vshader); - D3D::ChangePixelShader(PShader); - D3D::SetTexture(0, texture); - D3D::ChangeVertexDeclaration(0); - dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2)); - dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex)); - RestoreShaders(); -} - -void drawShadedTexSubQuad(IDirect3DTexture9 *texture, - const MathUtil::Rectangle *rSource, - int SourceWidth, - int SourceHeight, - const MathUtil::Rectangle *rDest, - int DestWidth, - int DestHeight, - IDirect3DPixelShader9 *PShader, - IDirect3DVertexShader9 *Vshader, - float Gamma) -{ - float sw = 1.0f /(float) SourceWidth; - float sh = 1.0f /(float) SourceHeight; - float dw = 1.0f /(float) DestWidth; - float dh = 1.0f /(float) DestHeight; - float u1= rSource->left * sw; - float u2= rSource->right * sw; - float v1= rSource->top * sh; - float v2= rSource->bottom * sh; - float g = 1.0f/Gamma; - - struct Q2DVertex { float x,y,z,rhw,u,v,w,h,G; } coords[4] = { - { rDest->left - dw , rDest->top + dh, 1.0f,1.0f, u1, v2, sw, sh, g}, - { rDest->left - dw , rDest->bottom + dh, 1.0f,1.0f, u1, v1, sw, sh, g}, - { rDest->right - dw , rDest->top + dh, 1.0f,1.0f, u2, v2, sw, sh, g}, - { rDest->right - dw , rDest->bottom + dh, 1.0f,1.0f, u2, v1, sw, sh, g} - }; - D3D::ChangeVertexShader(Vshader); - D3D::ChangePixelShader(PShader); - D3D::SetTexture(0, texture); - D3D::ChangeVertexDeclaration(0); - dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2)); - dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex)); - RestoreShaders(); -} - -// Fills a certain area of the current render target with the specified color -// Z buffer disabled; destination coordinates normalized to (-1;1) -void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2) -{ - struct CQVertex { float x, y, z, rhw; u32 col; } coords[4] = { - { x1, y2, 0.f, 1.f, Color }, - { x2, y2, 0.f, 1.f, Color }, - { x1, y1, 0.f, 1.f, Color }, - { x2, y1, 0.f, 1.f, Color }, - }; - D3D::ChangeVertexShader(VertexShaderCache::GetClearVertexShader()); - D3D::ChangePixelShader(PixelShaderCache::GetClearProgram()); - D3D::ChangeVertexDeclaration(0); - dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE); - dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(CQVertex)); - RestoreShaders(); -} - -void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader) -{ - struct Q2DVertex { float x,y,z,rhw;u32 color;} coords[4] = { - {-1.0f, 1.0f, z, 1.0f, Color}, - { 1.0f, 1.0f, z, 1.0f, Color}, - { 1.0f, -1.0f, z, 1.0f, Color}, - {-1.0f, -1.0f, z, 1.0f, Color} - }; - D3D::ChangeVertexShader(Vshader); - D3D::ChangePixelShader(PShader); - D3D::ChangeVertexDeclaration(0); - dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE); - dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex)); - RestoreShaders(); -} - - -} // namespace - -} // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h deleted file mode 100644 index 35cc63a5f0e3..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#pragma once - -#include "D3DBase.h" -#include -#include - -namespace DX9 -{ - -namespace D3D -{ - // Font creation flags - #define D3DFONT_BOLD 0x0001 - #define D3DFONT_ITALIC 0x0002 - - // Font rendering flags - #define D3DFONT_CENTERED 0x0001 - - //a cut-down variant of the DXSDK CD3DFont class - class CD3DFont - { - LPDIRECT3DTEXTURE9 m_pTexture; // The d3d texture for this font - LPDIRECT3DVERTEXBUFFER9 m_pVB; // VertexBuffer for rendering text - //int m_dwTexWidth; // Texture dimensions - //int m_dwTexHeight; - float m_fTextScale; - float m_fTexCoords[128-32][4]; - - public: - CD3DFont(); - // 2D (no longer 3D) text drawing function - // Initializing and destroying device-dependent objects - void SetRenderStates(); - int Init(); - int Shutdown(); - int DrawTextScaled( float x, float y, - float fXScale, float fYScale, - float spacing, u32 dwColor, - const char* strText); - - - // Constructor / destructor - //~CD3DFont(); - }; - - extern CD3DFont font; - - void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1=0, float v1=0, float u2=1, float v2=1); - void drawShadedTexQuad(IDirect3DTexture9 *texture, - const RECT *rSource, - int SourceWidth, - int SourceHeight, - int DestWidth, - int DestHeight, - IDirect3DPixelShader9 *PShader, - IDirect3DVertexShader9 *Vshader, - float Gamma = 1.0f); - void drawShadedTexSubQuad(IDirect3DTexture9 *texture, - const MathUtil::Rectangle *rSource, - int SourceWidth, - int SourceHeight, - const MathUtil::Rectangle *rDest, - int DestWidth, - int DestHeight, - IDirect3DPixelShader9 *PShader, - IDirect3DVertexShader9 *Vshader, - float Gamma = 1.0f); - void drawClearQuad(u32 Color, float z, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader); - void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2); - - void SaveRenderStates(); - void RestoreRenderStates(); -} - -} // namespace DX9 \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp deleted file mode 100644 index 6b83b0e0d615..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include "D3DBase.h" -#include "Render.h" -#include "FramebufferManager.h" -#include "VideoConfig.h" -#include "PixelShaderCache.h" -#include "VertexShaderCache.h" -#include "TextureConverter.h" -#include "HW/Memmap.h" - -namespace DX9 -{ - -// TODO: this is probably somewhere else -#define SAFE_RELEASE(p) if (p) { (p)->Release(); (p) = NULL; } - -#undef CHECK -#define CHECK(hr, Message, ...) if (FAILED(hr)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); } - -inline void GetSurface(IDirect3DTexture9* texture, IDirect3DSurface9** surface) -{ - if (!texture) return; - texture->GetSurfaceLevel(0, surface); -} - -FramebufferManager::Efb FramebufferManager::s_efb; - -FramebufferManager::FramebufferManager() -{ - bool depth_textures_supported = true; - int target_width = Renderer::GetTargetWidth(); - int target_height = Renderer::GetTargetHeight(); - s_efb.color_surface_Format = D3DFMT_A8R8G8B8; - - // EFB color texture - primary render target - HRESULT hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb.color_surface_Format, - D3DPOOL_DEFAULT, &s_efb.color_texture, NULL); - GetSurface(s_efb.color_texture, &s_efb.color_surface); - CHECK(hr, "Create color texture (size: %dx%d; hr=%#x)", target_width, target_height, hr); - - // Render buffer for AccessEFB (color data) - hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, s_efb.color_surface_Format, - D3DPOOL_DEFAULT, &s_efb.colorRead_texture, NULL); - GetSurface(s_efb.colorRead_texture, &s_efb.color_ReadBuffer); - CHECK(hr, "Create Color Read Texture (hr=%#x)", hr); - - // AccessEFB - Sysmem buffer used to retrieve the pixel data from color_ReadBuffer - hr = D3D::dev->CreateOffscreenPlainSurface(1, 1, s_efb.color_surface_Format, D3DPOOL_SYSTEMMEM, &s_efb.color_OffScreenReadBuffer, NULL); - CHECK(hr, "Create offscreen color surface (hr=%#x)", hr); - - // Select a Z-buffer texture format with hardware support - s_efb.depth_surface_Format = D3D::GetSupportedDepthTextureFormat(); - if (s_efb.depth_surface_Format == D3DFMT_UNKNOWN) - { - // workaround for Intel GPUs etc: only create a depth _surface_ - depth_textures_supported = false; - s_efb.depth_surface_Format = D3D::GetSupportedDepthSurfaceFormat(s_efb.color_surface_Format); - ERROR_LOG(VIDEO, "No supported depth texture format found, disabling Z peeks for EFB access."); - } - - if (depth_textures_supported) - { - // EFB depth buffer - primary depth buffer - hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_DEPTHSTENCIL, s_efb.depth_surface_Format, - D3DPOOL_DEFAULT, &s_efb.depth_texture, NULL); - GetSurface(s_efb.depth_texture, &s_efb.depth_surface); - CHECK(hr, "Framebuffer depth texture (size: %dx%d; hr=%#x)", target_width, target_height, hr); - - // Render buffer for AccessEFB (depth data) - D3DFORMAT DepthTexFormats[2]; - DepthTexFormats[0] = D3DFMT_D24X8; - // This is expected to work on all hardware - DepthTexFormats[1] = D3DFMT_A8R8G8B8; - - for (int i = 0; i < 2; ++i) - { - if (D3D::CheckTextureSupport(D3DUSAGE_RENDERTARGET, DepthTexFormats[i])) - { - s_efb.depth_ReadBuffer_Format = DepthTexFormats[i]; - break; - } - } - hr = D3D::dev->CreateTexture(4, 4, 1, D3DUSAGE_RENDERTARGET, s_efb.depth_ReadBuffer_Format, - D3DPOOL_DEFAULT, &s_efb.depthRead_texture, NULL); - GetSurface(s_efb.depthRead_texture, &s_efb.depth_ReadBuffer); - CHECK(hr, "Create depth read texture (hr=%#x)", hr); - - // AccessEFB - Sysmem buffer used to retrieve the pixel data from depth_ReadBuffer - hr = D3D::dev->CreateOffscreenPlainSurface(4, 4, s_efb.depth_ReadBuffer_Format, D3DPOOL_SYSTEMMEM, &s_efb.depth_OffScreenReadBuffer, NULL); - CHECK(hr, "Create depth offscreen surface (hr=%#x)", hr); - } - else if (s_efb.depth_surface_Format) - { - // just create a depth surface - hr = D3D::dev->CreateDepthStencilSurface(target_width, target_height, s_efb.depth_surface_Format, D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb.depth_surface, NULL); - CHECK(hr, "Framebuffer depth surface (size: %dx%d; hr=%#x)", target_width, target_height, hr); - } - - // ReinterpretPixelData - EFB color data will be copy-converted to this texture and the buffers are swapped then - hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb.color_surface_Format, - D3DPOOL_DEFAULT, &s_efb.color_reinterpret_texture, NULL); - GetSurface(s_efb.color_reinterpret_texture, &s_efb.color_reinterpret_surface); - CHECK(hr, "Create color reinterpret texture (size: %dx%d; hr=%#x)", target_width, target_height, hr); -} - -FramebufferManager::~FramebufferManager() -{ - SAFE_RELEASE(s_efb.depth_surface); - SAFE_RELEASE(s_efb.color_surface); - SAFE_RELEASE(s_efb.color_ReadBuffer); - SAFE_RELEASE(s_efb.depth_ReadBuffer); - SAFE_RELEASE(s_efb.color_OffScreenReadBuffer); - SAFE_RELEASE(s_efb.depth_OffScreenReadBuffer); - SAFE_RELEASE(s_efb.color_texture); - SAFE_RELEASE(s_efb.colorRead_texture); - SAFE_RELEASE(s_efb.depth_texture); - SAFE_RELEASE(s_efb.depthRead_texture); - SAFE_RELEASE(s_efb.color_reinterpret_texture); - SAFE_RELEASE(s_efb.color_reinterpret_surface); - s_efb.color_surface_Format = D3DFMT_UNKNOWN; - s_efb.depth_surface_Format = D3DFMT_UNKNOWN; - s_efb.depth_ReadBuffer_Format = D3DFMT_UNKNOWN; -} - -XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height) -{ - LPDIRECT3DTEXTURE9 tex; - D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, - s_efb.color_surface_Format, D3DPOOL_DEFAULT, &tex, NULL); - - return new XFBSource(tex); -} - -void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) -{ - TargetRectangle targetSource; - - targetSource.top = ScaleToVirtualXfbHeight(sourceRc.top, Renderer::GetBackbufferHeight()); - targetSource.bottom = ScaleToVirtualXfbHeight(sourceRc.bottom, Renderer::GetBackbufferHeight()); - targetSource.left = ScaleToVirtualXfbWidth(sourceRc.left, Renderer::GetBackbufferWidth()); - targetSource.right = ScaleToVirtualXfbWidth(sourceRc.right, Renderer::GetBackbufferWidth()); - - *width = targetSource.right - targetSource.left; - *height = targetSource.bottom - targetSource.top; -} - -void XFBSource::Draw(const MathUtil::Rectangle &sourcerc, - const MathUtil::Rectangle &drawrc, int width, int height) const -{ - D3D::drawShadedTexSubQuad(texture, &sourcerc, texWidth, texHeight, &drawrc, width , height, - PixelShaderCache::GetColorCopyProgram(0), VertexShaderCache::GetSimpleVertexShader(0)); -} - -void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) -{ - TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, texture); -} - -void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma) -{ - u8* xfb_in_ram = Memory::GetPointer(xfbAddr); - if (!xfb_in_ram) - { - WARN_LOG(VIDEO, "Tried to copy to invalid XFB address"); - return; - } - - TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc); - TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(), targetRc, xfb_in_ram, fbWidth, fbHeight,Gamma); -} - -void XFBSource::CopyEFB(float Gamma) -{ - g_renderer->ResetAPIState(); // reset any game specific settings - - // Copy EFB data to XFB and restore render target again - LPDIRECT3DSURFACE9 Rendersurf = NULL; - texture->GetSurfaceLevel(0, &Rendersurf); - D3D::dev->SetDepthStencilSurface(NULL); - D3D::dev->SetRenderTarget(0, Rendersurf); - - D3DVIEWPORT9 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = texWidth; - vp.Height = texHeight; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - - RECT sourcerect; - sourcerect.bottom = sourceRc.bottom; - sourcerect.left = sourceRc.left; - sourcerect.right = sourceRc.right; - sourcerect.top = sourceRc.top; - - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - - D3D::drawShadedTexQuad( - FramebufferManager::GetEFBColorTexture(), - &sourcerect, - Renderer::GetTargetWidth(), - Renderer::GetTargetHeight(), - texWidth, - texHeight, - PixelShaderCache::GetColorCopyProgram( g_ActiveConfig.iMultisampleMode), - VertexShaderCache::GetSimpleVertexShader( g_ActiveConfig.iMultisampleMode), - Gamma); - - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); - D3D::SetTexture(0, NULL); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - - Rendersurf->Release(); - - g_renderer->RestoreAPIState(); -} - -} // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h deleted file mode 100644 index 66cdc2ec99a7..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#pragma once - -#include "D3DBase.h" -#include "FramebufferManagerBase.h" - -// On the GameCube, the game sends a request for the graphics processor to -// transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM -// called the XFB (External Framebuffer). The size and location of the XFB is -// decided at the time of the copy, and the format is always YUYV. The video -// interface is given a pointer to the XFB, which will be decoded and -// displayed on the TV. -// -// There are two ways for Dolphin to emulate this: -// -// Real XFB mode: -// -// Dolphin will behave like the GameCube and encode the EFB to -// a portion of GameCube RAM. The emulated video interface will decode the data -// for output to the screen. -// -// Advantages: Behaves exactly like the GameCube. -// Disadvantages: Resolution will be limited. -// -// Virtual XFB mode: -// -// When a request is made to copy the EFB to an XFB, Dolphin -// will remember the RAM location and size of the XFB in a Virtual XFB list. -// The video interface will look up the XFB in the list and use the enhanced -// data stored there, if available. -// -// Advantages: Enables high resolution graphics, better than real hardware. -// Disadvantages: If the GameCube CPU writes directly to the XFB (which is -// possible but uncommon), the Virtual XFB will not capture this information. - -namespace DX9 -{ - -struct XFBSource : public XFBSourceBase -{ - XFBSource(LPDIRECT3DTEXTURE9 tex) : texture(tex) {} - ~XFBSource() { texture->Release(); } - - void Draw(const MathUtil::Rectangle &sourcerc, - const MathUtil::Rectangle &drawrc, int width, int height) const; - void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight); - void CopyEFB(float Gamma); - - LPDIRECT3DTEXTURE9 const texture; -}; - -class FramebufferManager : public FramebufferManagerBase -{ -public: - FramebufferManager(); - ~FramebufferManager(); - - static LPDIRECT3DTEXTURE9 GetEFBColorTexture() { return s_efb.color_texture; } - static LPDIRECT3DTEXTURE9 GetEFBDepthTexture() { return s_efb.depth_texture; } - - static LPDIRECT3DSURFACE9 GetEFBColorRTSurface() { return s_efb.color_surface; } - static LPDIRECT3DSURFACE9 GetEFBDepthRTSurface() { return s_efb.depth_surface; } - - static LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface() { return s_efb.color_OffScreenReadBuffer; } - static LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface() { return s_efb.depth_OffScreenReadBuffer; } - - static D3DFORMAT GetEFBDepthRTSurfaceFormat() { return s_efb.depth_surface_Format; } - static D3DFORMAT GetEFBColorRTSurfaceFormat() { return s_efb.color_surface_Format; } - static D3DFORMAT GetEFBDepthReadSurfaceFormat() { return s_efb.depth_ReadBuffer_Format; } - - static LPDIRECT3DSURFACE9 GetEFBColorReadSurface() { return s_efb.color_ReadBuffer; } - static LPDIRECT3DSURFACE9 GetEFBDepthReadSurface() { return s_efb.depth_ReadBuffer; } - - static LPDIRECT3DTEXTURE9 GetEFBColorReinterpretTexture() { return s_efb.color_reinterpret_texture; } - static LPDIRECT3DSURFACE9 GetEFBColorReinterpretSurface() { return s_efb.color_reinterpret_surface; } - static void SwapReinterpretTexture() - { - LPDIRECT3DSURFACE9 swapsurf = GetEFBColorReinterpretSurface(); - LPDIRECT3DTEXTURE9 swaptex = GetEFBColorReinterpretTexture(); - s_efb.color_reinterpret_surface = GetEFBColorRTSurface(); - s_efb.color_reinterpret_texture = GetEFBColorTexture(); - s_efb.color_surface = swapsurf; - s_efb.color_texture = swaptex; - } - -private: - XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height); - void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc); - - void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma); - - static struct Efb - { - Efb() : color_texture(NULL), colorRead_texture(NULL), depth_texture(NULL), depthRead_texture(NULL), - color_reinterpret_texture(NULL), color_reinterpret_surface(NULL), - depth_surface(NULL), color_surface(NULL), color_ReadBuffer(NULL), depth_ReadBuffer(NULL), - color_OffScreenReadBuffer(NULL), depth_OffScreenReadBuffer(NULL), - color_surface_Format(D3DFMT_UNKNOWN), depth_surface_Format(D3DFMT_UNKNOWN), - depth_ReadBuffer_Format(D3DFMT_UNKNOWN) {} - - LPDIRECT3DTEXTURE9 color_texture;//Texture that contains the color data of the render target - LPDIRECT3DTEXTURE9 colorRead_texture;//1 pixel texture for temporal data store - LPDIRECT3DTEXTURE9 depth_texture;//Texture that contains the depth data of the render target - LPDIRECT3DTEXTURE9 depthRead_texture;//4 pixel texture for temporal data store - - LPDIRECT3DTEXTURE9 color_reinterpret_texture;//buffer used for ReinterpretPixelData - LPDIRECT3DSURFACE9 color_reinterpret_surface;//corresponding surface - - LPDIRECT3DSURFACE9 depth_surface;//Depth Surface - LPDIRECT3DSURFACE9 color_surface;//Color Surface - LPDIRECT3DSURFACE9 color_ReadBuffer;//Surface 0 of colorRead_texture - LPDIRECT3DSURFACE9 depth_ReadBuffer;//Surface 0 of depthRead_texture - LPDIRECT3DSURFACE9 color_OffScreenReadBuffer;//System memory Surface that can be locked to retrieve the data - LPDIRECT3DSURFACE9 depth_OffScreenReadBuffer;//System memory Surface that can be locked to retrieve the data - - D3DFORMAT color_surface_Format;//Format of the color Surface - D3DFORMAT depth_surface_Format;//Format of the Depth Surface - D3DFORMAT depth_ReadBuffer_Format;//Format of the Depth color Read Surface - } s_efb; -}; - -} // namespace DX9 \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Globals.h b/Source/Plugins/Plugin_VideoDX9/Src/Globals.h deleted file mode 100644 index 89800694e80e..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/Globals.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#ifndef _GLOBALS_H_ -#define _GLOBALS_H_ - -#include "Common.h" -#include "VideoConfig.h" -#include "main.h" - -#include "VideoCommon.h" - -#endif // _GLOBALS_H_ \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp deleted file mode 100644 index 69de7e0a58ac..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include "D3DBase.h" - -#include "x64Emitter.h" -#include "x64ABI.h" -#include "MemoryUtil.h" -#include "VertexShaderGen.h" - -#include "CPMemory.h" -#include "NativeVertexFormat.h" -#include "VertexManager.h" - -namespace DX9 -{ - -class D3DVertexFormat : public NativeVertexFormat -{ - LPDIRECT3DVERTEXDECLARATION9 d3d_decl; - -public: - D3DVertexFormat() : d3d_decl(NULL) {} - ~D3DVertexFormat(); - virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); - virtual void SetupVertexPointers(); - -#if defined(_DEBUG) || defined(DEBUGFAST) - D3DVERTEXELEMENT9 elements[32]; - int num_elements; -#endif -}; - -NativeVertexFormat* VertexManager::CreateNativeVertexFormat() -{ - return new D3DVertexFormat(); -} - -void DX9::VertexManager::GetElements(NativeVertexFormat* format, D3DVERTEXELEMENT9** elems, int* num) -{ -#if defined(_DEBUG) || defined(DEBUGFAST) - *elems = ((D3DVertexFormat*)format)->elements; - *num = ((D3DVertexFormat*)format)->num_elements; -#else - *elems = NULL; - *num = 0; -#endif -} - -D3DVertexFormat::~D3DVertexFormat() -{ - if (d3d_decl) - { - d3d_decl->Release(); - d3d_decl = NULL; - } -} - -D3DDECLTYPE VarToD3D(VarType t, int size) -{ - if (t < 0 || t > 4) { - PanicAlert("VarToD3D: Invalid VarType %i", t); - } - static const D3DDECLTYPE lookup1[5] = { - D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_FLOAT1, - }; - static const D3DDECLTYPE lookup2[5] = { - D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_SHORT2N, D3DDECLTYPE_USHORT2N, D3DDECLTYPE_FLOAT2, - }; - static const D3DDECLTYPE lookup3[5] = { - D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_FLOAT3, - }; - // Sadly, D3D9 has no SBYTE4N. D3D10 does, though. - static const D3DDECLTYPE lookup4[5] = { - D3DDECLTYPE_UNUSED, D3DDECLTYPE_UBYTE4N, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_FLOAT4, - }; - D3DDECLTYPE retval = D3DDECLTYPE_UNUSED; - switch (size) - { - case 1: retval = lookup1[t]; break; - case 2: retval = lookup2[t]; break; - case 3: retval = lookup3[t]; break; - case 4: retval = lookup4[t]; break; - default: break; - } - if (retval == D3DDECLTYPE_UNUSED) { - PanicAlert("VarToD3D: Invalid type/size combo %i , %i", (int)t, size); - } - return retval; -} - -void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) -{ - vertex_stride = _vtx_decl.stride; - - D3DVERTEXELEMENT9 elems[32]; - memset(elems, 0, sizeof(elems)); - - // There's only one stream and it's 0, so the above memset takes care of that - no need to set Stream. - // Same for method. - - // So, here we go. First position: - int elem_idx = 0; - elems[elem_idx].Offset = 0; // Positions are always first, at position 0. Always float3. - elems[elem_idx].Type = D3DDECLTYPE_FLOAT3; - elems[elem_idx].Usage = D3DDECLUSAGE_POSITION; - ++elem_idx; - - for (int i = 0; i < 3; i++) - { - if (_vtx_decl.normal_offset[i] > 0) - { - elems[elem_idx].Offset = _vtx_decl.normal_offset[i]; - elems[elem_idx].Type = VarToD3D(_vtx_decl.normal_gl_type, _vtx_decl.normal_gl_size); - elems[elem_idx].Usage = D3DDECLUSAGE_NORMAL; - elems[elem_idx].UsageIndex = i; - ++elem_idx; - } - } - - for (int i = 0; i < 2; i++) - { - if (_vtx_decl.color_offset[i] > 0) - { - elems[elem_idx].Offset = _vtx_decl.color_offset[i]; - elems[elem_idx].Type = VarToD3D(_vtx_decl.color_gl_type, 4); - elems[elem_idx].Usage = D3DDECLUSAGE_COLOR; - elems[elem_idx].UsageIndex = i; - ++elem_idx; - } - } - - for (int i = 0; i < 8; i++) - { - if (_vtx_decl.texcoord_offset[i] > 0) - { - elems[elem_idx].Offset = _vtx_decl.texcoord_offset[i]; - elems[elem_idx].Type = VarToD3D(_vtx_decl.texcoord_gl_type[i], _vtx_decl.texcoord_size[i]); - elems[elem_idx].Usage = D3DDECLUSAGE_TEXCOORD; - elems[elem_idx].UsageIndex = i; - ++elem_idx; - } - } - - if (_vtx_decl.posmtx_offset != -1) - { - elems[elem_idx].Offset = _vtx_decl.posmtx_offset; - elems[elem_idx].Usage = D3DDECLUSAGE_BLENDINDICES; - elems[elem_idx].Type = D3DDECLTYPE_D3DCOLOR; - elems[elem_idx].UsageIndex = 0; - ++elem_idx; - } - - // End marker - elems[elem_idx].Stream = 0xff; - elems[elem_idx].Type = D3DDECLTYPE_UNUSED; - ++elem_idx; - - if (FAILED(DX9::D3D::dev->CreateVertexDeclaration(elems, &d3d_decl))) - { - PanicAlert("Failed to create D3D vertex declaration!"); - return; - } -#if defined(_DEBUG) || defined(DEBUGFAST) - memcpy(&elements, elems, sizeof(elems)); - num_elements = elem_idx; -#endif -} - -void D3DVertexFormat::SetupVertexPointers() -{ - if (d3d_decl) - DX9::D3D::SetVertexDeclaration(d3d_decl); - else - ERROR_LOG(VIDEO, "Invalid D3D decl"); -} - -} // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp deleted file mode 100644 index 3e6f058fddf0..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp +++ /dev/null @@ -1,169 +0,0 @@ -#include "RenderBase.h" - -#include "D3DBase.h" -#include "PerfQuery.h" - -namespace DX9 { - -PerfQuery::PerfQuery() - : m_query_read_pos() - , m_query_count() -{ - -} - -PerfQuery::~PerfQuery() -{ - -} - -void PerfQuery::CreateDeviceObjects() -{ - for (int i = 0; i != ArraySize(m_query_buffer); ++i) - { - D3D::dev->CreateQuery(D3DQUERYTYPE_OCCLUSION, &m_query_buffer[i].query); - } - ResetQuery(); -} -void PerfQuery::DestroyDeviceObjects() -{ - for (int i = 0; i != ArraySize(m_query_buffer); ++i) - { - m_query_buffer[i].query->Release(); - } -} - -void PerfQuery::EnableQuery(PerfQueryGroup type) -{ - if (!ShouldEmulate()) - return; - // Is this sane? - if (m_query_count > ArraySize(m_query_buffer) / 2) - WeakFlush(); - - if (ArraySize(m_query_buffer) == m_query_count) - { - // TODO - FlushOne(); - ERROR_LOG(VIDEO, "Flushed query buffer early!"); - } - - // start query - if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) - { - auto& entry = m_query_buffer[(m_query_read_pos + m_query_count) % ArraySize(m_query_buffer)]; - entry.query->Issue(D3DISSUE_BEGIN); - entry.query_type = type; - ++m_query_count; - } -} - -void PerfQuery::DisableQuery(PerfQueryGroup type) -{ - if (!ShouldEmulate()) - return; - // stop query - if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) - { - auto& entry = m_query_buffer[(m_query_read_pos + m_query_count + ArraySize(m_query_buffer)-1) % ArraySize(m_query_buffer)]; - entry.query->Issue(D3DISSUE_END); - } -} - -void PerfQuery::ResetQuery() -{ - m_query_count = 0; - std::fill_n(m_results, ArraySize(m_results), 0); -} - -u32 PerfQuery::GetQueryResult(PerfQueryType type) -{ - if (!ShouldEmulate()) - return 0; - u32 result = 0; - - if (type == PQ_ZCOMP_INPUT_ZCOMPLOC || type == PQ_ZCOMP_OUTPUT_ZCOMPLOC) - { - result = m_results[PQG_ZCOMP_ZCOMPLOC]; - } - else if (type == PQ_ZCOMP_INPUT || type == PQ_ZCOMP_OUTPUT) - { - result = m_results[PQG_ZCOMP]; - } - else if (type == PQ_BLEND_INPUT) - { - result = m_results[PQG_ZCOMP] + m_results[PQG_ZCOMP_ZCOMPLOC]; - } - else if (type == PQ_EFB_COPY_CLOCKS) - { - result = m_results[PQG_EFB_COPY_CLOCKS]; - } - - return result / 4; -} - -void PerfQuery::FlushOne() -{ - if (!ShouldEmulate()) - return; - auto& entry = m_query_buffer[m_query_read_pos]; - - DWORD result = 0; - HRESULT hr = S_FALSE; - while (hr != S_OK && hr != D3DERR_DEVICELOST) - { - // TODO: Might cause us to be stuck in an infinite loop! - hr = entry.query->GetData(&result, sizeof(result), D3DGETDATA_FLUSH); - } - - // NOTE: Reported pixel metrics should be referenced to native resolution - m_results[entry.query_type] += (u32)((u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight()); - - m_query_read_pos = (m_query_read_pos + 1) % ArraySize(m_query_buffer); - --m_query_count; -} - -// TODO: could selectively flush things, but I don't think that will do much -void PerfQuery::FlushResults() -{ - if (!ShouldEmulate()) - return; - while (!IsFlushed()) - FlushOne(); -} - -void PerfQuery::WeakFlush() -{ - if (!ShouldEmulate()) - return; - while (!IsFlushed()) - { - auto& entry = m_query_buffer[m_query_read_pos]; - - DWORD result = 0; - HRESULT hr = entry.query->GetData(&result, sizeof(result), 0); - - if (hr == S_OK) - { - // NOTE: Reported pixel metrics should be referenced to native resolution - m_results[entry.query_type] += (u32)((u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight()); - - m_query_read_pos = (m_query_read_pos + 1) % ArraySize(m_query_buffer); - --m_query_count; - } - else - { - break; - } - } -} - -bool PerfQuery::IsFlushed() const -{ - if (!ShouldEmulate()) - return true; - return 0 == m_query_count; -} - - -} // namespace diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.h b/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.h deleted file mode 100644 index 9b8f63765567..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _PERFQUERY_H_ -#define _PERFQUERY_H_ - -#include "PerfQueryBase.h" - -namespace DX9 { - -class PerfQuery : public PerfQueryBase -{ -public: - PerfQuery(); - ~PerfQuery(); - - void EnableQuery(PerfQueryGroup type); - void DisableQuery(PerfQueryGroup type); - void ResetQuery(); - u32 GetQueryResult(PerfQueryType type); - void FlushResults(); - bool IsFlushed() const; - void CreateDeviceObjects(); - void DestroyDeviceObjects(); - -private: - struct ActiveQuery - { - IDirect3DQuery9* query; - PerfQueryGroup query_type; - }; - - void WeakFlush(); - // Only use when non-empty - void FlushOne(); - - // when testing in SMS: 64 was too small, 128 was ok - static const int PERF_QUERY_BUFFER_SIZE = 512; - - ActiveQuery m_query_buffer[PERF_QUERY_BUFFER_SIZE]; - int m_query_read_pos; - - // TODO: sloppy - volatile int m_query_count; - volatile u32 m_results[PQG_NUM_MEMBERS]; -}; - -} // namespace - -#endif // _PERFQUERY_H_ diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp deleted file mode 100644 index ea6503e9e0b5..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ /dev/null @@ -1,449 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include -#include -#include - -#include "Common.h" -#include "Hash.h" -#include "FileUtil.h" -#include "LinearDiskCache.h" - -#include "Globals.h" -#include "D3DBase.h" -#include "D3DShader.h" -#include "Statistics.h" -#include "VideoConfig.h" -#include "PixelShaderGen.h" -#include "PixelShaderManager.h" -#include "PixelShaderCache.h" -#include "VertexLoader.h" -#include "BPMemory.h" -#include "XFMemory.h" -#include "ImageWrite.h" -#include "Debugger.h" -#include "ConfigManager.h" - -namespace DX9 -{ - -PixelShaderCache::PSCache PixelShaderCache::PixelShaders; -const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry; -PixelShaderUid PixelShaderCache::last_uid; -UidChecker PixelShaderCache::pixel_uid_checker; - -static LinearDiskCache g_ps_disk_cache; -static std::set unique_shaders; - -#define MAX_SSAA_SHADERS 3 -enum -{ - COPY_TYPE_DIRECT, - COPY_TYPE_MATRIXCOLOR, - NUM_COPY_TYPES -}; -enum -{ - DEPTH_CONVERSION_TYPE_NONE, - DEPTH_CONVERSION_TYPE_ON, - NUM_DEPTH_CONVERSION_TYPES -}; - -static LPDIRECT3DPIXELSHADER9 s_CopyProgram[NUM_COPY_TYPES][NUM_DEPTH_CONVERSION_TYPES][MAX_SSAA_SHADERS]; -static LPDIRECT3DPIXELSHADER9 s_ClearProgram = NULL; -static LPDIRECT3DPIXELSHADER9 s_rgba6_to_rgb8 = NULL; -static LPDIRECT3DPIXELSHADER9 s_rgb8_to_rgba6 = NULL; - -class PixelShaderCacheInserter : public LinearDiskCacheReader -{ -public: - void Read(const PixelShaderUid &key, const u8 *value, u32 value_size) - { - PixelShaderCache::InsertByteCode(key, value, value_size, false); - } -}; - -LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorMatrixProgram(int SSAAMode) -{ - return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; -} - -LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetDepthMatrixProgram(int SSAAMode, bool depthConversion) -{ - return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][depthConversion ? DEPTH_CONVERSION_TYPE_ON : DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; -} - -LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorCopyProgram(int SSAAMode) -{ - return s_CopyProgram[COPY_TYPE_DIRECT][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; -} - -LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetClearProgram() -{ - return s_ClearProgram; -} - -static LPDIRECT3DPIXELSHADER9 s_rgb8 = NULL; -static LPDIRECT3DPIXELSHADER9 s_rgba6 = NULL; - -LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGBA6ToRGB8() -{ - const char code[] = - { - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - " out float4 ocol0 : COLOR0,\n" - " in float2 uv0 : TEXCOORD0){\n" - " ocol0 = tex2D(samp0,uv0);\n" - " float4 src6 = round(ocol0 * 63.f);\n" - " ocol0.r = floor(src6.r*4.f) + floor(src6.g/16.f);\n" // dst8r = (src6r<<2)|(src6g>>4); - " ocol0.g = frac(src6.g/16.f)*16.f*16.f + floor(src6.b/4.f);\n" // dst8g = ((src6g&0xF)<<4)|(src6b>>2); - " ocol0.b = frac(src6.b/4.f)*4.f*64.f + src6.a;\n" // dst8b = ((src6b&0x3)<<6)|src6a; - " ocol0.a = 255.f;\n" - " ocol0 /= 255.f;\n" - "}\n" - }; - - if (!s_rgba6_to_rgb8) - s_rgba6_to_rgb8 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); - - return s_rgba6_to_rgb8; -} - -LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGB8ToRGBA6() -{ - /* old code here for reference - const char code[] = - { - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - " out float4 ocol0 : COLOR0,\n" - " in float2 uv0 : TEXCOORD0){\n" - " ocol0 = tex2D(samp0,uv0);\n" - " float4 src8 = round(ocol0*255.f);\n" - " ocol0.r = floor(src8.r/4.f);\n" // dst6r = src8r>>2; - " ocol0.g = frac(src8.r/4.f)*4.f*16.f + floor(src8.g/16.f);\n" // dst6g = ((src8r&0x3)<<4)|(src8g>>4); - " ocol0.b = frac(src8.g/16.f)*16.f*4.f + floor(src8.b/64.f);\n" // dst6b = ((src8g&0xF)<<2)|(src8b>>6); - " ocol0.a = frac(src8.b/64.f)*64.f;\n" // dst6a = src8b&0x3F; - " ocol0 /= 63.f;\n" - "}\n" - }; - */ - const char code[] = - { - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - "out float4 ocol0 : COLOR0,\n" - "in float2 uv0 : TEXCOORD0){\n" - "float4 temp1 = float4(1.0f/4.0f,1.0f/16.0f,1.0f/64.0f,0.0f);\n" - "float4 temp2 = float4(1.0f,64.0f,255.0f,1.0f/63.0f);\n" - "float4 src8 = round(tex2D(samp0,uv0)*temp2.z) * temp1;\n" - "ocol0 = (frac(src8.wxyz) * temp2.xyyy + floor(src8)) * temp2.w;\n" - "}\n" - }; - if (!s_rgb8_to_rgba6) s_rgb8_to_rgba6 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); - return s_rgb8_to_rgba6; -} - -#define WRITE p+=sprintf - -static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConversionType, int SSAAMode) -{ - //Used for Copy/resolve the color buffer - //Color conversion Programs - //Depth copy programs - // this should create the same shaders as before (plus some extras added for DF16), just... more manageably than listing the full program for each combination - char text[3072]; - - locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation - locale_t old_locale = uselocale(locale); // Apply the locale for this thread - text[sizeof(text) - 1] = 0x7C; // canary - - char* p = text; - WRITE(p, "// Copy/Color Matrix/Depth Matrix shader (matrix=%d, depth=%d, ssaa=%d)\n", copyMatrixType, depthConversionType, SSAAMode); - - WRITE(p, "uniform sampler samp0 : register(s0);\n"); - if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) - WRITE(p, "uniform float4 cColMatrix[7] : register(c%d);\n", C_COLORMATRIX); - WRITE(p, "void main(\n" - "out float4 ocol0 : COLOR0,\n"); - - switch(SSAAMode % MAX_SSAA_SHADERS) - { - case 0: // 1 Sample - WRITE(p, "in float2 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1){\n" - "float4 texcol = tex2D(samp0,uv0.xy);\n"); - break; - case 1: // 4 Samples in 4x SSAA buffer - WRITE(p, "in float4 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1,\n" - "in float4 uv2 : TEXCOORD2,\n" - "in float4 uv3 : TEXCOORD3){\n" - "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); - break; - case 2: // 4 Samples in 9x SSAA buffer - WRITE(p, "in float4 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1,\n" - "in float4 uv2 : TEXCOORD2,\n" - "in float4 uv3 : TEXCOORD3){\n" - "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); - break; - } - - if(depthConversionType != DEPTH_CONVERSION_TYPE_NONE) - { - // Watch out for the fire fumes effect in Metroid it's really sensitive to this, - // the lighting in RE0 is also way beyond sensitive since the "good value" is hardcoded and Dolphin is almost always off. - WRITE(p, "float4 EncodedDepth = frac(texcol.r * (16777215.f/16777216.f) * float4(1.0f,256.0f,256.0f*256.0f,1.0f));\n" - "texcol = floor(EncodedDepth * float4(256.f,256.f,256.f,15.0f)) / float4(255.0f,255.0f,255.0f,15.0f);\n"); - } - else - { - //Apply Gamma Correction - WRITE(p, "texcol = pow(texcol,uv1.xxxx);\n"); - } - - if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) - { - if(depthConversionType == DEPTH_CONVERSION_TYPE_NONE) - WRITE(p, "texcol = round(texcol * cColMatrix[5])*cColMatrix[6];\n"); - - WRITE(p, "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"); - } - else - WRITE(p, "ocol0 = texcol;\n"); - - WRITE(p, "}\n"); - if (text[sizeof(text) - 1] != 0x7C) - PanicAlert("PixelShaderCache copy shader generator - buffer too small, canary has been eaten!"); - - uselocale(old_locale); // restore locale - freelocale(locale); - return D3D::CompileAndCreatePixelShader(text, (int)strlen(text)); -} - -void PixelShaderCache::Init() -{ - last_entry = NULL; - - //program used for clear screen - { - char pprog[3072]; - sprintf(pprog, "void main(\n" - "out float4 ocol0 : COLOR0,\n" - " in float4 incol0 : COLOR0){\n" - "ocol0 = incol0;\n" - "}\n"); - s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); - } - - int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF); - int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); - - // other screen copy/convert programs - for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) - { - for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) - { - for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) - { - if(ssaaMode && !s_CopyProgram[copyMatrixType][depthType][ssaaMode-1] - || depthType && !s_CopyProgram[copyMatrixType][depthType-1][ssaaMode] - || copyMatrixType && !s_CopyProgram[copyMatrixType-1][depthType][ssaaMode]) - { - // if it failed at a lower setting, it's going to fail here for the same reason it did there, - // so skip this attempt to avoid duplicate error messages. - s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; - } - else - { - s_CopyProgram[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode); - } - } - } - } - - Clear(); - - if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) - File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); - - SETSTAT(stats.numPixelShadersCreated, 0); - SETSTAT(stats.numPixelShadersAlive, 0); - - char cache_filename[MAX_PATH]; - sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); - PixelShaderCacheInserter inserter; - g_ps_disk_cache.OpenAndRead(cache_filename, inserter); - - if (g_Config.bEnableShaderDebugging) - Clear(); -} - -// ONLY to be used during shutdown. -void PixelShaderCache::Clear() -{ - for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++) - iter->second.Destroy(); - PixelShaders.clear(); - pixel_uid_checker.Invalidate(); - - last_entry = NULL; -} - -void PixelShaderCache::Shutdown() -{ - for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) - for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) - for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) - if(s_CopyProgram[copyMatrixType][depthType][ssaaMode] - && (copyMatrixType == 0 || s_CopyProgram[copyMatrixType][depthType][ssaaMode] != s_CopyProgram[copyMatrixType-1][depthType][ssaaMode])) - s_CopyProgram[copyMatrixType][depthType][ssaaMode]->Release(); - - for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) - for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) - for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) - s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; - - if (s_ClearProgram) s_ClearProgram->Release(); - s_ClearProgram = NULL; - if (s_rgb8_to_rgba6) s_rgb8_to_rgba6->Release(); - s_rgb8_to_rgba6 = NULL; - if (s_rgba6_to_rgb8) s_rgba6_to_rgb8->Release(); - s_rgba6_to_rgb8 = NULL; - - - Clear(); - g_ps_disk_cache.Sync(); - g_ps_disk_cache.Close(); - - unique_shaders.clear(); -} - -bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) -{ - const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30; - PixelShaderUid uid; - GetPixelShaderUid(uid, dstAlphaMode, API_D3D9, components); - if (g_ActiveConfig.bEnableShaderDebugging) - { - PixelShaderCode code; - GeneratePixelShaderCode(code, dstAlphaMode, API_D3D9, components); - pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p"); - } - - // Check if the shader is already set - if (last_entry) - { - if (uid == last_uid) - { - GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - return last_entry->shader != NULL; - } - } - - last_uid = uid; - - // Check if the shader is already in the cache - PSCache::iterator iter; - iter = PixelShaders.find(uid); - if (iter != PixelShaders.end()) - { - const PSCacheEntry &entry = iter->second; - last_entry = &entry; - - if (entry.shader) D3D::SetPixelShader(entry.shader); - GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - return (entry.shader != NULL); - } - - - // Need to compile a new shader - PixelShaderCode code; - GeneratePixelShaderCode(code, dstAlphaMode, api, components); - - if (g_ActiveConfig.bEnableShaderDebugging) - { - u32 code_hash = HashAdler32((const u8 *)code.GetBuffer(), strlen(code.GetBuffer())); - unique_shaders.insert(code_hash); - SETSTAT(stats.numUniquePixelShaders, unique_shaders.size()); - } - -#if defined(_DEBUG) || defined(DEBUGFAST) - if (g_ActiveConfig.iLog & CONF_SAVESHADERS) { - static int counter = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); - - SaveData(szTemp, code.GetBuffer()); - } -#endif - - u8 *bytecode = 0; - int bytecodelen = 0; - if (!D3D::CompilePixelShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) { - GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); - return false; - } - - // Insert the bytecode into the caches - g_ps_disk_cache.Append(uid, bytecode, bytecodelen); - - // And insert it into the shader cache. - bool success = InsertByteCode(uid, bytecode, bytecodelen, true); - delete [] bytecode; - - if (g_ActiveConfig.bEnableShaderDebugging && success) - { - PixelShaders[uid].code = code.GetBuffer(); - } - - GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - return success; -} - -bool PixelShaderCache::InsertByteCode(const PixelShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) -{ - LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); - - // Make an entry in the table - PSCacheEntry newentry; - newentry.shader = shader; - PixelShaders[uid] = newentry; - last_entry = &PixelShaders[uid]; - - if (!shader) { - // INCSTAT(stats.numPixelShadersFailed); - return false; - } - - INCSTAT(stats.numPixelShadersCreated); - SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); - if (activate) - { - D3D::SetPixelShader(shader); - } - return true; -} - -void Renderer::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) -{ - float f[4] = { f1, f2, f3, f4 }; - DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); -} - -void Renderer::SetPSConstant4fv(unsigned int const_number, const float *f) -{ - DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); -} - -void Renderer::SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f) -{ - DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, count); -} - -} // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h deleted file mode 100644 index 733a68233a62..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#pragma once - -#include "Common.h" -#include "LinearDiskCache.h" -#include "D3DBase.h" - -#include - -#include "PixelShaderGen.h" -#include "VertexShaderGen.h" - -namespace DX9 -{ - -typedef u32 tevhash; - -tevhash GetCurrentTEV(); - -class PixelShaderCache -{ -private: - struct PSCacheEntry - { - LPDIRECT3DPIXELSHADER9 shader; - bool owns_shader; - - std::string code; - - PSCacheEntry() : shader(NULL), owns_shader(true) {} - void Destroy() - { - if (shader && owns_shader) - shader->Release(); - shader = NULL; - } - }; - - typedef std::map PSCache; - - static PSCache PixelShaders; - static const PSCacheEntry *last_entry; - static PixelShaderUid last_uid; - static UidChecker pixel_uid_checker; - - static void Clear(); - -public: - static void Init(); - static void Shutdown(); - static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 componets); - static bool InsertByteCode(const PixelShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate); - static LPDIRECT3DPIXELSHADER9 GetColorMatrixProgram(int SSAAMode); - static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram(int SSAAMode); - static LPDIRECT3DPIXELSHADER9 GetDepthMatrixProgram(int SSAAMode, bool depthConversion); - static LPDIRECT3DPIXELSHADER9 GetClearProgram(); - static LPDIRECT3DPIXELSHADER9 ReinterpRGBA6ToRGB8(); - static LPDIRECT3DPIXELSHADER9 ReinterpRGB8ToRGBA6(); -}; - -} // namespace DX9 \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp deleted file mode 100644 index b70ed2d48b8b..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ /dev/null @@ -1,1386 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include -#include - -#include "StringUtil.h" -#include "Common.h" -#include "Atomic.h" -#include "FileUtil.h" -#include "Thread.h" -#include "Timer.h" -#include "Statistics.h" -#include "Host.h" - -#include "VideoConfig.h" -#include "main.h" -#include "VertexManager.h" -#include "PixelEngine.h" -#include "Render.h" -#include "OpcodeDecoding.h" -#include "BPStructs.h" -#include "XFStructs.h" -#include "D3DUtil.h" -#include "VertexShaderManager.h" -#include "PixelShaderManager.h" -#include "VertexShaderCache.h" -#include "PixelShaderCache.h" -#include "VertexLoaderManager.h" -#include "TextureCache.h" -#include "EmuWindow.h" -#include "AVIDump.h" -#include "OnScreenDisplay.h" -#include "FramebufferManager.h" -#include "Fifo.h" -#include "TextureConverter.h" -#include "DLCache.h" -#include "Debugger.h" -#include "Core.h" -#include "Movie.h" -#include "BPFunctions.h" -#include "FPSCounter.h" -#include "ConfigManager.h" -#include "PerfQuery.h" -#include - - -namespace DX9 -{ - -static int s_fps = 0; - -static u32 s_blendMode; -static u32 s_LastAA; -static bool IS_AMD; -static float m_fMaxPointSize; -static bool s_vsync; -static char *st; - -static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL; - - -void SetupDeviceObjects() -{ - D3D::font.Init(); - VertexLoaderManager::Init(); - g_framebuffer_manager = new FramebufferManager; - - VertexShaderManager::Dirty(); - PixelShaderManager::Dirty(); - TextureConverter::Init(); - - // To avoid shader compilation stutters, read back all shaders from cache. - VertexShaderCache::Init(); - PixelShaderCache::Init(); - g_vertex_manager->CreateDeviceObjects(); - ((PerfQuery*)g_perf_query)->CreateDeviceObjects(); - // Texture cache will recreate themselves over time. -} - -// Kill off all POOL_DEFAULT device objects. -void TeardownDeviceObjects() -{ - if(ScreenShootMEMSurface) - ScreenShootMEMSurface->Release(); - ScreenShootMEMSurface = NULL; - D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); - delete g_framebuffer_manager; - ((PerfQuery*)g_perf_query)->DestroyDeviceObjects(); - D3D::font.Shutdown(); - TextureCache::Invalidate(); - VertexLoaderManager::Shutdown(); - VertexShaderCache::Shutdown(); - PixelShaderCache::Shutdown(); - TextureConverter::Shutdown(); - g_vertex_manager->DestroyDeviceObjects(); -} - -// Init functions -Renderer::Renderer() -{ - InitFPSCounter(); - - st = new char[32768]; - - int fullScreenRes, x, y, w_temp, h_temp; - s_blendMode = 0; - // Multisample Anti-aliasing hasn't been implemented yet use supersamling instead - int backbuffer_ms_mode = 0; - - Host_GetRenderWindowSize(x, y, w_temp, h_temp); - - for (fullScreenRes = 0; fullScreenRes < (int)D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size(); fullScreenRes++) - { - if ((D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].xres == w_temp) && - (D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].yres == h_temp)) - break; - } - if (fullScreenRes == D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size()) - fullScreenRes = 0; - - D3D::Create(g_ActiveConfig.iAdapter, EmuWindow::GetWnd(), - fullScreenRes, backbuffer_ms_mode, false); - - IS_AMD = D3D::IsATIDevice(); - - // Decide framebuffer size - s_backbuffer_width = D3D::GetBackBufferWidth(); - s_backbuffer_height = D3D::GetBackBufferHeight(); - - FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH); - FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT); - - UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); - - s_LastAA = g_ActiveConfig.iMultisampleMode; - int SupersampleCoeficient = (s_LastAA % 3) + 1; - - s_LastEFBScale = g_ActiveConfig.iEFBScale; - CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient); - - // Make sure to use valid texture sizes - D3D::FixTextureSize(s_target_width, s_target_height); - - // We're not using fixed function. - // Let's just set the matrices to identity to be sure. - D3DXMATRIX mtx; - D3DXMatrixIdentity(&mtx); - D3D::dev->SetTransform(D3DTS_VIEW, &mtx); - D3D::dev->SetTransform(D3DTS_WORLD, &mtx); - - SetupDeviceObjects(); - - for (int stage = 0; stage < 8; stage++) - D3D::SetSamplerState(stage, D3DSAMP_MAXANISOTROPY, 1 << g_ActiveConfig.iMaxAnisotropy); - - D3DVIEWPORT9 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = s_backbuffer_width; - vp.Height = s_backbuffer_height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0); - - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - vp.X = 0; - vp.Y = 0; - vp.Width = s_target_width; - vp.Height = s_target_height; - D3D::dev->SetViewport(&vp); - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); - D3D::BeginFrame(); - D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true); - D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); - D3D::SetRenderState(D3DRS_POINTSCALEENABLE,false); - m_fMaxPointSize = D3D::GetCaps().MaxPointSize; - // Handle VSync on/off - s_vsync = g_ActiveConfig.IsVSync(); -} - -Renderer::~Renderer() -{ - TeardownDeviceObjects(); - D3D::EndFrame(); - D3D::Present(); - D3D::Close(); - - delete[] st; -} - -void Renderer::RenderText(const char *text, int left, int top, u32 color) -{ - D3D::font.DrawTextScaled((float)left, (float)top, 20, 20, 0.0f, color, text); -} - -TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) -{ - TargetRectangle result; - result.left = EFBToScaledX(rc.left); - result.top = EFBToScaledY(rc.top); - result.right = EFBToScaledX(rc.right); - result.bottom = EFBToScaledY(rc.bottom); - return result; -} - -} - -void formatBufferDump(const u8* in, u8* out, int w, int h, int p) -{ - for (int y = 0; y < h; y++) - { - auto line = in + (h - y - 1) * p; - for (int x = 0; x < w; x++) - { - memcpy(out, line, 3); - out += 3; - line += 4; - } - } -} - -namespace DX9 -{ - -// With D3D, we have to resize the backbuffer if the window changed -// size. -bool Renderer::CheckForResize() -{ - while (EmuWindow::IsSizing()) - Sleep(10); - - if (EmuWindow::GetParentWnd()) - { - // Re-stretch window to parent window size again, if it has a parent window. - RECT rcParentWindow; - GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow); - int width = rcParentWindow.right - rcParentWindow.left; - int height = rcParentWindow.bottom - rcParentWindow.top; - if (width != Renderer::GetBackbufferWidth() || height != Renderer::GetBackbufferHeight()) - MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE); - } - - RECT rcWindow; - GetClientRect(EmuWindow::GetWnd(), &rcWindow); - int client_width = rcWindow.right - rcWindow.left; - int client_height = rcWindow.bottom - rcWindow.top; - - // Sanity check - if ((client_width != Renderer::GetBackbufferWidth() || - client_height != Renderer::GetBackbufferHeight()) && - client_width >= 4 && client_height >= 4) - { - TeardownDeviceObjects(); - - D3D::Reset(); - s_backbuffer_width = D3D::GetBackBufferWidth(); - s_backbuffer_height = D3D::GetBackBufferHeight(); - if(ScreenShootMEMSurface) - ScreenShootMEMSurface->Release(); - D3D::dev->CreateOffscreenPlainSurface(Renderer::GetBackbufferWidth(), Renderer::GetBackbufferHeight(), - D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); - - return true; - } - - return false; -} - -void Renderer::SetScissorRect(const TargetRectangle& rc) -{ - D3D::dev->SetScissorRect(rc.AsRECT()); -} - -void Renderer::SetColorMask() -{ - // Only enable alpha channel if it's supported by the current EFB format - DWORD color_mask = 0; - if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL) - { - if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) - color_mask = D3DCOLORWRITEENABLE_ALPHA; - if (bpmem.blendmode.colorupdate) - color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - } - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); -} - -// This function allows the CPU to directly access the EFB. -// There are EFB peeks (which will read the color or depth of a pixel) -// and EFB pokes (which will change the color or depth of a pixel). -// -// The behavior of EFB peeks can only be modified by: -// - GX_PokeAlphaRead -// The behavior of EFB pokes can be modified by: -// - GX_PokeAlphaMode (TODO) -// - GX_PokeAlphaUpdate (TODO) -// - GX_PokeBlendMode (TODO) -// - GX_PokeColorUpdate (TODO) -// - GX_PokeDither (TODO) -// - GX_PokeDstAlpha (TODO) -// - GX_PokeZMode (TODO) -u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) -{ - if (!g_ActiveConfig.bEFBAccessEnable) - return 0; - - if (type == POKE_Z) - { - static bool alert_only_once = true; - if (!alert_only_once) return 0; - PanicAlert("EFB: Poke Z not implemented (tried to poke z value %#x at (%d,%d))", poke_data, x, y); - alert_only_once = false; - return 0; - } - - // if depth textures aren't supported by the hardware, just return - if (type == PEEK_Z) - if (FramebufferManager::GetEFBDepthTexture() == NULL) - return 0; - - // We're using three surfaces here: - // - pEFBSurf: EFB Surface. Source surface when peeking, destination surface when poking. - // - pBufferRT: A render target surface. When peeking, we render a textured quad to this surface. - // - pSystemBuf: An offscreen surface. Used to retrieve the pixel data from pBufferRT. - LPDIRECT3DSURFACE9 pEFBSurf, pBufferRT, pSystemBuf; - if(type == PEEK_Z || type == POKE_Z) - { - pEFBSurf = FramebufferManager::GetEFBDepthRTSurface(); - pBufferRT = FramebufferManager::GetEFBDepthReadSurface(); - pSystemBuf = FramebufferManager::GetEFBDepthOffScreenRTSurface(); - } - else //if(type == PEEK_COLOR || type == POKE_COLOR) - { - pEFBSurf = FramebufferManager::GetEFBColorRTSurface(); - pBufferRT = FramebufferManager::GetEFBColorReadSurface(); - pSystemBuf = FramebufferManager::GetEFBColorOffScreenRTSurface(); - } - - // Buffer not found alert - if (!pEFBSurf) { - PanicAlert("No %s!", (type == PEEK_Z || type == POKE_Z) ? "Z-Buffer" : "Color EFB"); - return 0; - } - - // Convert EFB dimensions to the ones of our render target - EFBRectangle efbPixelRc; - efbPixelRc.left = x; - efbPixelRc.top = y; - efbPixelRc.right = x + 1; - efbPixelRc.bottom = y + 1; - - TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc); - - HRESULT hr; - RECT RectToLock; - RectToLock.bottom = targetPixelRc.bottom; - RectToLock.left = targetPixelRc.left; - RectToLock.right = targetPixelRc.right; - RectToLock.top = targetPixelRc.top; - if (type == PEEK_Z) - { - // TODO: why is D3DFMT_D24X8 singled out here? why not D3DFMT_D24X4S4/D24S8/D24FS8/D32/D16/D15S1 too, or none of them? - if (FramebufferManager::GetEFBDepthRTSurfaceFormat() == D3DFMT_D24X8) - return 0; - - RECT PixelRect; - PixelRect.bottom = 4; - PixelRect.left = 0; - PixelRect.right = 4; - PixelRect.top = 0; - RectToLock.bottom+=2; - RectToLock.right+=1; - RectToLock.top-=1; - RectToLock.left-=2; - if ((RectToLock.bottom - RectToLock.top) > 4) - RectToLock.bottom--; - if ((RectToLock.right - RectToLock.left) > 4) - RectToLock.left++; - - ResetAPIState(); // Reset any game specific settings - D3D::dev->SetDepthStencilSurface(NULL); - D3D::dev->SetRenderTarget(0, pBufferRT); - - // Stretch picture with increased internal resolution - D3DVIEWPORT9 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = 4; - vp.Height = 4; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - - float colmat[28] = {0.0f}; - colmat[0] = colmat[5] = colmat[10] = 1.0f; - PixelShaderManager::SetColorMatrix(colmat); // set transformation - LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBDepthTexture(); - - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - - D3DFORMAT bformat = FramebufferManager::GetEFBDepthRTSurfaceFormat(); - - D3D::drawShadedTexQuad( - read_texture, - &RectToLock, - Renderer::GetTargetWidth(), - Renderer::GetTargetHeight(), - 4, 4, - PixelShaderCache::GetDepthMatrixProgram(0, bformat != FOURCC_RAWZ), - VertexShaderCache::GetSimpleVertexShader(0)); - - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - RestoreAPIState(); - - // Retrieve the pixel data to the local memory buffer - RectToLock.bottom = 4; - RectToLock.left = 0; - RectToLock.right = 4; - RectToLock.top = 0; - D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf); - - // EFB data successfully retrieved, now get the pixel data - D3DLOCKED_RECT drect; - pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY); - u32 z = ((u32*)drect.pBits)[6]; // 24 bit depth value - pSystemBuf->UnlockRect(); - - // if Z is in 16 bit format you must return a 16 bit integer - if(bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) { - z >>= 8; - } - - return z; - } - else if(type == PEEK_COLOR) - { - // We can't directly StretchRect to System buf because is not supported by all implementations - // this is the only safe path that works in most cases - hr = D3D::dev->StretchRect(pEFBSurf, &RectToLock, pBufferRT, NULL, D3DTEXF_NONE); - D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf); - - // EFB data successfully retrieved, now get the pixel data - RectToLock.bottom = 1; - RectToLock.left = 0; - RectToLock.right = 1; - RectToLock.top = 0; - - D3DLOCKED_RECT drect; - pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY); - u32 ret = ((u32*)drect.pBits)[0]; - pSystemBuf->UnlockRect(); - - // check what to do with the alpha channel (GX_PokeAlphaRead) - PixelEngine::UPEAlphaReadReg alpha_read_mode; - PixelEngine::Read16((u16&)alpha_read_mode, PE_ALPHAREAD); - - if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) - { - ret = RGBA8ToRGBA6ToRGBA8(ret); - } - else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) - { - ret = RGBA8ToRGB565ToRGBA8(ret); - } - if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24) - { - ret |= 0xFF000000; - } - - if(alpha_read_mode.ReadMode == 2) return ret; // GX_READ_NONE - else if(alpha_read_mode.ReadMode == 1) return (ret | 0xFF000000); // GX_READ_FF - else return (ret & 0x00FFFFFF); // GX_READ_00 - } - else //if(type == POKE_COLOR) - { - // TODO: Speed this up by batching pokes? - ResetAPIState(); - D3D::drawColorQuad(poke_data, - (float)RectToLock.left * 2.f / (float)Renderer::GetTargetWidth() - 1.f, - - (float)RectToLock.top * 2.f / (float)Renderer::GetTargetHeight() + 1.f, - (float)RectToLock.right * 2.f / (float)Renderer::GetTargetWidth() - 1.f, - - (float)RectToLock.bottom * 2.f / (float)Renderer::GetTargetHeight() + 1.f); - RestoreAPIState(); - return 0; - } -} - -// Viewport correction: -// Say you want a viewport at (ix, iy) with size (iw, ih), -// but your viewport must be clamped at (ax, ay) with size (aw, ah). -// Just multiply the projection matrix with the following to get the same -// effect: -// [ (iw/aw) 0 0 ((iw - 2*(ax-ix)) / aw - 1) ] -// [ 0 (ih/ah) 0 ((-ih + 2*(ay-iy)) / ah + 1) ] -// [ 0 0 1 0 ] -// [ 0 0 0 1 ] -static void ViewportCorrectionMatrix(Matrix44& result, - float ix, float iy, float iw, float ih, // Intended viewport (x, y, width, height) - float ax, float ay, float aw, float ah) // Actual viewport (x, y, width, height) -{ - Matrix44::LoadIdentity(result); - if (aw == 0.f || ah == 0.f) - return; - result.data[4*0+0] = iw / aw; - result.data[4*0+3] = (iw - 2.f * (ax - ix)) / aw - 1.f; - result.data[4*1+1] = ih / ah; - result.data[4*1+3] = (-ih + 2.f * (ay - iy)) / ah + 1.f; -} - -// Called from VertexShaderManager -void Renderer::UpdateViewport(Matrix44& vpCorrection) -{ - // reversed gxsetviewport(xorig, yorig, width, height, nearz, farz) - // [0] = width/2 - // [1] = height/2 - // [2] = 16777215 * (farz - nearz) - // [3] = xorig + width/2 + 342 - // [4] = yorig + height/2 + 342 - // [5] = 16777215 * farz - - int scissorXOff = bpmem.scissorOffset.x * 2; - int scissorYOff = bpmem.scissorOffset.y * 2; - - // TODO: ceil, floor or just cast to int? - int intendedX = EFBToScaledX((int)ceil(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff)); - int intendedY = EFBToScaledY((int)ceil(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff)); - int intendedWd = EFBToScaledX((int)ceil(2.0f * xfregs.viewport.wd)); - int intendedHt = EFBToScaledY((int)ceil(-2.0f * xfregs.viewport.ht)); - if (intendedWd < 0) - { - intendedX += intendedWd; - intendedWd = -intendedWd; - } - if (intendedHt < 0) - { - intendedY += intendedHt; - intendedHt = -intendedHt; - } - - // In D3D, the viewport rectangle must fit within the render target. - int X = intendedX; - if (X < 0) - X = 0; - int Y = intendedY; - if (Y < 0) - Y = 0; - int Wd = intendedWd; - if (X + Wd > GetTargetWidth()) - Wd = GetTargetWidth() - X; - int Ht = intendedHt; - if (Y + Ht > GetTargetHeight()) - Ht = GetTargetHeight() - Y; - - // If GX viewport is off the render target, we must clamp our viewport - // within the bounds. Use the correction matrix to compensate. - ViewportCorrectionMatrix(vpCorrection, - (float)intendedX, (float)intendedY, (float)intendedWd, (float)intendedHt, - (float)X, (float)Y, (float)Wd, (float)Ht); - - D3DVIEWPORT9 vp; - vp.X = X; - vp.Y = Y; - vp.Width = Wd; - vp.Height = Ht; - - // Some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work - vp.MinZ = 0.0f; // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f; - vp.MaxZ = 1.0f; // xfregs.viewport.farZ / 16777216.0f; - D3D::dev->SetViewport(&vp); -} - -void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) -{ - // Reset rendering pipeline while keeping color masks and depth buffer settings - ResetAPIState(); - - DWORD color_mask = 0; - if (alphaEnable) - color_mask = D3DCOLORWRITEENABLE_ALPHA; - if (colorEnable) - color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, color_mask); - - if (zEnable) - { - D3D::ChangeRenderState(D3DRS_ZENABLE, TRUE); - D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, TRUE); - D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); - } - else - { - D3D::ChangeRenderState(D3DRS_ZENABLE, FALSE); - } - - // Update the viewport for clearing the target EFB rect - TargetRectangle targetRc = ConvertEFBRectangle(rc); - D3DVIEWPORT9 vp; - vp.X = targetRc.left; - vp.Y = targetRc.top; - vp.Width = targetRc.GetWidth(); - vp.Height = targetRc.GetHeight(); - vp.MinZ = 0.0; - vp.MaxZ = 1.0; - D3D::dev->SetViewport(&vp); - D3D::drawClearQuad(color, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); - RestoreAPIState(); -} - -void Renderer::ReinterpretPixelData(unsigned int convtype) -{ - RECT source; - SetRect(&source, 0, 0, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight()); - - LPDIRECT3DPIXELSHADER9 pixel_shader; - if (convtype == 0) pixel_shader = PixelShaderCache::ReinterpRGB8ToRGBA6(); - else if (convtype == 2) pixel_shader = PixelShaderCache::ReinterpRGBA6ToRGB8(); - else - { - ERROR_LOG(VIDEO, "Trying to reinterpret pixel data with unsupported conversion type %d", convtype); - return; - } - - // convert data and set the target texture as our new EFB - g_renderer->ResetAPIState(); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorReinterpretSurface()); - D3DVIEWPORT9 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = g_renderer->GetTargetWidth(); - vp.Height = g_renderer->GetTargetHeight(); - vp.MinZ = 0.0; - vp.MaxZ = 1.0; - D3D::dev->SetViewport(&vp); - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture(), &source, - g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), - g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), - pixel_shader, VertexShaderCache::GetSimpleVertexShader(0)); - FramebufferManager::SwapReinterpretTexture(); - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - g_renderer->RestoreAPIState(); -} - -void Renderer::SetBlendMode(bool forceUpdate) -{ - // Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel - // Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1. - bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; - //bDstAlphaPass is taken into account because the ability to disable alpha composition is - //really useful for debugging shader and blending errors - bool use_DstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && target_has_alpha; - bool use_DualSource = use_DstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; - const D3DBLEND d3dSrcFactors[8] = - { - D3DBLEND_ZERO, - D3DBLEND_ONE, - D3DBLEND_DESTCOLOR, - D3DBLEND_INVDESTCOLOR, - (use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA, - (use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA, - (target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE, - (target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO - }; - const D3DBLEND d3dDestFactors[8] = - { - D3DBLEND_ZERO, - D3DBLEND_ONE, - D3DBLEND_SRCCOLOR, - D3DBLEND_INVSRCCOLOR, - (use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA, - (use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA, - (target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE, - (target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO - }; - - if (bpmem.blendmode.logicopenable && !forceUpdate) - { - D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE , false); - return; - } - - bool blend_enable = bpmem.blendmode.subtract || bpmem.blendmode.blendenable; - D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, blend_enable); - D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, blend_enable && g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction); - if (blend_enable) - { - D3DBLENDOP op = D3DBLENDOP_ADD; - u32 srcidx = bpmem.blendmode.srcfactor; - u32 dstidx = bpmem.blendmode.dstfactor; - if (bpmem.blendmode.subtract) - { - op = D3DBLENDOP_REVSUBTRACT; - srcidx = GX_BL_ONE; - dstidx = GX_BL_ONE; - } - D3D::SetRenderState(D3DRS_BLENDOP, op); - D3D::SetRenderState(D3DRS_SRCBLEND, d3dSrcFactors[srcidx]); - D3D::SetRenderState(D3DRS_DESTBLEND, d3dDestFactors[dstidx]); - if (g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction) - { - if (use_DualSource) - { - op = D3DBLENDOP_ADD; - srcidx = GX_BL_ONE; - dstidx = GX_BL_ZERO; - } - else - { - // we can't use D3DBLEND_DESTCOLOR or D3DBLEND_INVDESTCOLOR for source in alpha channel so use their alpha equivalent instead - if (srcidx == GX_BL_DSTCLR) srcidx = GX_BL_DSTALPHA; - if (srcidx == GX_BL_INVDSTCLR) srcidx = GX_BL_INVDSTALPHA; - // we can't use D3DBLEND_SRCCOLOR or D3DBLEND_INVSRCCOLOR for destination in alpha channel so use their alpha equivalent instead - if (dstidx == GX_BL_SRCCLR) dstidx = GX_BL_SRCALPHA; - if (dstidx == GX_BL_INVSRCCLR) dstidx = GX_BL_INVSRCALPHA; - } - D3D::SetRenderState(D3DRS_BLENDOPALPHA, op); - D3D::SetRenderState(D3DRS_SRCBLENDALPHA, d3dSrcFactors[srcidx]); - D3D::SetRenderState(D3DRS_DESTBLENDALPHA, d3dDestFactors[dstidx]); - } - } -} - -bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &dst_rect) -{ - HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); - if(FAILED(hr)) - { - PanicAlert("Error dumping surface data."); - return false; - } - hr = PD3DXSaveSurfaceToFileA(filename.c_str(), D3DXIFF_PNG, ScreenShootMEMSurface, NULL, dst_rect.AsRECT()); - if(FAILED(hr)) - { - PanicAlert("Error saving screen."); - return false; - } - OSD::AddMessage(StringFromFormat("Saved %i x %i %s", dst_rect.GetWidth(), dst_rect.GetHeight(), filename.c_str())); - - return true; -} - -// This function has the final picture. We adjust the aspect ratio here. -void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) -{ - if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) - { - if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) - AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); - - Core::Callback_VideoCopiedToXFB(false); - return; - } - - u32 xfbCount = 0; - const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); - if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) - { - if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) - AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); - - Core::Callback_VideoCopiedToXFB(false); - return; - } - - ResetAPIState(); - - if(g_ActiveConfig.bAnaglyphStereo) - { - static bool RightFrame = false; - if(RightFrame) - { - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN); - VertexShaderManager::ResetView(); - VertexShaderManager::TranslateView(-0.001f * g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); - VertexShaderManager::RotateView(-0.0001f *g_ActiveConfig.iAnaglyphFocalAngle,0.0f); - RightFrame = false; - } - else - { - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED); - VertexShaderManager::ResetView(); - VertexShaderManager::TranslateView(0.001f *g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); - VertexShaderManager::RotateView(0.0001f * g_ActiveConfig.iAnaglyphFocalAngle,0.0f); - RightFrame = true; - } - } - - // Prepare to copy the XFBs to our backbuffer - D3D::dev->SetDepthStencilSurface(NULL); - D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - - UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); - D3DVIEWPORT9 vp; - - // Clear full target screen (edges, borders etc) - if(g_ActiveConfig.bAnaglyphStereo) { - // use a clear quad to keep old red or blue/green data - vp.X = 0; - vp.Y = 0; - vp.Width = s_backbuffer_width; - vp.Height = s_backbuffer_height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - D3D::drawClearQuad(0, 1.0, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); - } - else - { - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); - } - - int X = GetTargetRectangle().left; - int Y = GetTargetRectangle().top; - int Width = GetTargetRectangle().right - GetTargetRectangle().left; - int Height = GetTargetRectangle().bottom - GetTargetRectangle().top; - - // Sanity check - if (X < 0) X = 0; - if (Y < 0) Y = 0; - if (X > s_backbuffer_width) X = s_backbuffer_width; - if (Y > s_backbuffer_height) Y = s_backbuffer_height; - if (Width < 0) Width = 0; - if (Height < 0) Height = 0; - if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X; - if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y; - - vp.X = X; - vp.Y = Y; - vp.Width = Width; - vp.Height = Height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - - D3D::dev->SetViewport(&vp); - - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - - const XFBSourceBase* xfbSource = NULL; - - if(g_ActiveConfig.bUseXFB) - { - // draw each xfb source - // Render to the real buffer now. - for (u32 i = 0; i < xfbCount; ++i) - { - xfbSource = xfbSourceList[i]; - - MathUtil::Rectangle sourceRc; - - sourceRc.left = 0; - sourceRc.top = 0; - sourceRc.right = (float)xfbSource->texWidth; - sourceRc.bottom = (float)xfbSource->texHeight; - - MathUtil::Rectangle drawRc; - - if (g_ActiveConfig.bUseRealXFB) - { - drawRc.top = -1; - drawRc.bottom = 1; - drawRc.left = -1; - drawRc.right = 1; - } - else - { - // use virtual xfb with offset - int xfbHeight = xfbSource->srcHeight; - int xfbWidth = xfbSource->srcWidth; - int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2); - - drawRc.bottom = 1.0f - (2.0f * (hOffset) / (float)fbHeight); - drawRc.top = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight); - drawRc.left = -(xfbWidth / (float)fbWidth); - drawRc.right = (xfbWidth / (float)fbWidth); - - // The following code disables auto stretch. Kept for reference. - // scale draw area for a 1 to 1 pixel mapping with the draw target - //float vScale = (float)fbHeight / (float)GetTargetRectangle().GetHeight(); - //float hScale = (float)fbWidth / (float)GetTargetRectangle().GetWidth(); - //drawRc.top *= vScale; - //drawRc.bottom *= vScale; - //drawRc.left *= hScale; - //drawRc.right *= hScale; - } - - xfbSource->Draw(sourceRc, drawRc, Width, Height); - } - } - else - { - TargetRectangle targetRc = ConvertEFBRectangle(rc); - LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBColorTexture(); - D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(), - Renderer::GetTargetWidth(),Renderer::GetTargetHeight(), - Width,Height, - PixelShaderCache::GetColorCopyProgram(g_ActiveConfig.iMultisampleMode), - VertexShaderCache::GetSimpleVertexShader(g_ActiveConfig.iMultisampleMode),Gamma); - - } - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); - - if(g_ActiveConfig.bAnaglyphStereo) - { - DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); - } - - vp.X = 0; - vp.Y = 0; - vp.Width = s_backbuffer_width; - vp.Height = s_backbuffer_height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - - // Save screenshot - if (s_bScreenshot) - { - std::lock_guard lk(s_criticalScreenshot); - SaveScreenshot(s_sScreenshotName, GetTargetRectangle()); - s_bScreenshot = false; - } - - // Dump frames - static int w = 0, h = 0; - if (g_ActiveConfig.bDumpFrames) - { - static int s_recordWidth; - static int s_recordHeight; - - HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); - if (!bLastFrameDumped) - { - s_recordWidth = GetTargetRectangle().GetWidth(); - s_recordHeight = GetTargetRectangle().GetHeight(); - bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight); - if (!bAVIDumping) - { - PanicAlert("Error dumping frames to AVI."); - } - else - { - char msg [255]; - sprintf_s(msg,255, "Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", - File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), s_recordWidth, s_recordHeight); - OSD::AddMessage(msg, 2000); - } - } - if (bAVIDumping) - { - D3DLOCKED_RECT rect; - if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, GetTargetRectangle().AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) - { - if (frame_data.empty() || w != s_recordWidth || h != s_recordHeight) - { - frame_data.resize(3 * s_recordWidth * s_recordHeight); - w = s_recordWidth; - h = s_recordHeight; - } - formatBufferDump((const u8*)rect.pBits, &frame_data[0], s_recordWidth, s_recordHeight, rect.Pitch); - AVIDump::AddFrame(&frame_data[0], GetTargetRectangle().GetWidth(), GetTargetRectangle().GetHeight()); - ScreenShootMEMSurface->UnlockRect(); - } - } - bLastFrameDumped = true; - } - else - { - if (bLastFrameDumped && bAVIDumping) - { - std::vector().swap(frame_data); - w = h = 0; - AVIDump::Stop(); - bAVIDumping = false; - OSD::AddMessage("Stop dumping frames to AVI", 2000); - } - bLastFrameDumped = false; - } - - // Finish up the current frame, print some stats - if (g_ActiveConfig.bShowFPS) - { - char fps[20]; - StringCchPrintfA(fps, 20, "FPS: %d\n", s_fps); - D3D::font.DrawTextScaled(0, 0, 20, 20, 0.0f, 0xFF00FFFF, fps); - } - - if (SConfig::GetInstance().m_ShowLag) - { - char lag[10]; - StringCchPrintfA(lag, 10, "Lag: %llu\n", Movie::g_currentLagCount); - D3D::font.DrawTextScaled(0, 18, 20, 20, 0.0f, 0xFF00FFFF, lag); - } - - if (g_ActiveConfig.bShowInputDisplay) - { - char inputDisplay[1000]; - StringCchPrintfA(inputDisplay, 1000, Movie::GetInputDisplay().c_str()); - D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, inputDisplay); - } - - Renderer::DrawDebugText(); - - if (g_ActiveConfig.bOverlayStats) - { - Statistics::ToString(st); - D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, st); - } - else if (g_ActiveConfig.bOverlayProjStats) - { - Statistics::ToStringProj(st); - D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, st); - } - - OSD::DrawMessages(); - D3D::EndFrame(); - ++frameCount; - - GFX_DEBUGGER_PAUSE_AT(NEXT_FRAME, true); - - DLCache::ProgressiveCleanup(); - TextureCache::Cleanup(); - // Flip/present backbuffer to frontbuffer here - D3D::Present(); - // Enable configuration changes - UpdateActiveConfig(); - TextureCache::OnConfigChanged(g_ActiveConfig); - - SetWindowSize(fbWidth, fbHeight); - - const bool windowResized = CheckForResize(); - - bool xfbchanged = false; - - if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight) - { - xfbchanged = true; - unsigned int w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth; - unsigned int h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight; - FramebufferManagerBase::SetLastXfbWidth(w); - FramebufferManagerBase::SetLastXfbHeight(h); - } - - u32 newAA = g_ActiveConfig.iMultisampleMode; - - if (xfbchanged || windowResized || s_LastEFBScale != g_ActiveConfig.iEFBScale || s_LastAA != newAA) - { - s_LastAA = newAA; - - UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); - - int SupersampleCoeficient = (s_LastAA % 3) + 1; - - s_LastEFBScale = g_ActiveConfig.iEFBScale; - CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient); - - D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); - if (windowResized) - { - // device objects lost, so recreate all of them - SetupDeviceObjects(); - } - else - { - // just resize the frame buffer - delete g_framebuffer_manager; - g_framebuffer_manager = new FramebufferManager; - } - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); - SetLineWidth(); - } - - if (XFBWrited) - s_fps = UpdateFPSCounter(); - - // Begin new frame - // Set default viewport and scissor, for the clear to work correctly - // New frame - stats.ResetFrame(); - - // Handle vsync changes during execution - if(s_vsync != g_ActiveConfig.IsVSync()) - { - s_vsync = g_ActiveConfig.IsVSync(); - TeardownDeviceObjects(); - D3D::Reset(); - // device objects lost, so recreate all of them - SetupDeviceObjects(); - } - D3D::BeginFrame(); - RestoreAPIState(); - - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - VertexShaderManager::SetViewportChanged(); - - Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB)); - XFBWrited = false; -} - -void Renderer::ApplyState(bool bUseDstAlpha) -{ - if (bUseDstAlpha) - { - // If we get here we are sure that we are using dst alpha pass. (bpmem.dstalpha.enable) - // Alpha write is enabled. (because bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) - // We must disable blend because we want to write alpha value directly to the alpha channel without modifications. - D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); - D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false); - if(bpmem.zmode.testenable && bpmem.zmode.updateenable) - { - // This is needed to draw to the correct pixels in multi-pass algorithms - // to avoid z-fighting and grants that you write to the same pixels - // affected by the last pass - D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, false); - D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); - } - } -} - -void Renderer::RestoreState() -{ - D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE); - D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); - if(bpmem.zmode.testenable && bpmem.zmode.updateenable) - { - D3D::RefreshRenderState(D3DRS_ZWRITEENABLE); - D3D::RefreshRenderState(D3DRS_ZFUNC); - } - // TODO: Enable this code. Caused glitches for me however (neobrain) - // for (unsigned int i = 0; i < 8; ++i) - // D3D::dev->SetTexture(i, NULL); -} - -// ALWAYS call RestoreAPIState for each ResetAPIState call you're doing -void Renderer::ResetAPIState() -{ - D3D::SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - D3D::SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - D3D::SetRenderState(D3DRS_ZENABLE, FALSE); - D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); -} - -void Renderer::RestoreAPIState() -{ - // Gets us back into a more game-like state. - D3D::SetRenderState(D3DRS_FILLMODE, g_ActiveConfig.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID); - D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); - VertexShaderManager::SetViewportChanged(); - BPFunctions::SetScissor(); - if (bpmem.zmode.testenable) { - D3D::SetRenderState(D3DRS_ZENABLE, TRUE); - if (bpmem.zmode.updateenable) - D3D::SetRenderState(D3DRS_ZWRITEENABLE, TRUE); - } - SetColorMask(); - SetLogicOpMode(); - SetGenerationMode(); -} - -void Renderer::SetGenerationMode() -{ - const D3DCULL d3dCullModes[4] = - { - D3DCULL_NONE, - D3DCULL_CCW, - D3DCULL_CW, - D3DCULL_CCW - }; - - D3D::SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]); -} - -void Renderer::SetDepthMode() -{ - const D3DCMPFUNC d3dCmpFuncs[8] = - { - D3DCMP_NEVER, - D3DCMP_LESS, - D3DCMP_EQUAL, - D3DCMP_LESSEQUAL, - D3DCMP_GREATER, - D3DCMP_NOTEQUAL, - D3DCMP_GREATEREQUAL, - D3DCMP_ALWAYS - }; - - if (bpmem.zmode.testenable) - { - D3D::SetRenderState(D3DRS_ZENABLE, TRUE); - D3D::SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable); - D3D::SetRenderState(D3DRS_ZFUNC, d3dCmpFuncs[bpmem.zmode.func]); - } - else - { - // if the test is disabled write is disabled too - D3D::SetRenderState(D3DRS_ZENABLE, FALSE); - D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - } -} - -void Renderer::SetLogicOpMode() -{ - // D3D9 doesn't support logic blending, so this is a huge hack - - // 0 0x00 - // 1 Source & destination - // 2 Source & ~destination - // 3 Source - // 4 ~Source & destination - // 5 Destination - // 6 Source ^ destination = Source & ~destination | ~Source & destination - // 7 Source | destination - // 8 ~(Source | destination) - // 9 ~(Source ^ destination) = ~Source & ~destination | Source & destination - // 10 ~Destination - // 11 Source | ~destination - // 12 ~Source - // 13 ~Source | destination - // 14 ~(Source & destination) - // 15 0xff - const D3DBLENDOP d3dLogicOpop[16] = - { - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_SUBTRACT, - D3DBLENDOP_ADD, - D3DBLENDOP_REVSUBTRACT, - D3DBLENDOP_ADD, - D3DBLENDOP_MAX, - D3DBLENDOP_ADD, - D3DBLENDOP_MAX, - D3DBLENDOP_MAX, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD - }; - const D3DBLEND d3dLogicOpSrcFactors[16] = - { - D3DBLEND_ZERO, - D3DBLEND_DESTCOLOR, - D3DBLEND_ONE, - D3DBLEND_ONE, - D3DBLEND_DESTCOLOR, - D3DBLEND_ZERO, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_ONE, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_ONE - }; - const D3DBLEND d3dLogicOpDestFactors[16] = - { - D3DBLEND_ZERO, - D3DBLEND_ZERO, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ZERO, - D3DBLEND_ONE, - D3DBLEND_ONE, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ONE, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_SRCCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ONE, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ONE - }; - - if (bpmem.blendmode.logicopenable) - { - D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, true); - D3D::SetRenderState(D3DRS_BLENDOP, d3dLogicOpop[bpmem.blendmode.logicmode]); - D3D::SetRenderState(D3DRS_SRCBLEND, d3dLogicOpSrcFactors[bpmem.blendmode.logicmode]); - D3D::SetRenderState(D3DRS_DESTBLEND, d3dLogicOpDestFactors[bpmem.blendmode.logicmode]); - } - else - { - SetBlendMode(true); - } -} - -void Renderer::SetDitherMode() -{ - D3D::SetRenderState(D3DRS_DITHERENABLE, bpmem.blendmode.dither); -} - -void Renderer::SetLineWidth() -{ - // We can't change line width in D3D unless we use ID3DXLine - float fratio = xfregs.viewport.wd != 0 ? Renderer::EFBToScaledXf(1.f) : 1.0f; - float psize = bpmem.lineptwidth.pointsize * fratio / 6.0f; - psize = psize > 0 ? psize : 1.0f; - if (psize > m_fMaxPointSize) - { - psize = m_fMaxPointSize; - } - D3D::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize)); - D3D::SetRenderState(D3DRS_POINTSIZE_MIN, *((DWORD*)&psize)); - D3D::SetRenderState(D3DRS_POINTSIZE_MAX, *((DWORD*)&psize)); -} - -void Renderer::SetSamplerState(int stage, int texindex) -{ - const D3DTEXTUREFILTERTYPE d3dMipFilters[4] = - { - D3DTEXF_NONE, - D3DTEXF_POINT, - D3DTEXF_LINEAR, - D3DTEXF_NONE, //reserved - }; - const D3DTEXTUREADDRESS d3dClamps[4] = - { - D3DTADDRESS_CLAMP, - D3DTADDRESS_WRAP, - D3DTADDRESS_MIRROR, - D3DTADDRESS_WRAP //reserved - }; - - const FourTexUnits &tex = bpmem.tex[texindex]; - const TexMode0 &tm0 = tex.texMode0[stage]; - const TexMode1 &tm1 = tex.texMode1[stage]; - - D3DTEXTUREFILTERTYPE min, mag, mip; - if (g_ActiveConfig.bForceFiltering) - { - min = mag = mip = D3DTEXF_LINEAR; - } - else - { - min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT; - mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT; - mip = d3dMipFilters[tm0.min_filter & 3]; - } - if (texindex) - stage += 4; - - if (mag == D3DTEXF_LINEAR && min == D3DTEXF_LINEAR && g_ActiveConfig.iMaxAnisotropy) - { - min = D3DTEXF_ANISOTROPIC; - } - D3D::SetSamplerState(stage, D3DSAMP_MINFILTER, min); - D3D::SetSamplerState(stage, D3DSAMP_MAGFILTER, mag); - D3D::SetSamplerState(stage, D3DSAMP_MIPFILTER, mip); - - D3D::SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]); - D3D::SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]); - - float lodbias = (s32)tm0.lod_bias / 32.0f; - D3D::SetSamplerState(stage, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lodbias); - D3D::SetSamplerState(stage, D3DSAMP_MAXMIPLEVEL, tm1.min_lod >> 4); -} - -void Renderer::SetInterlacingMode() -{ - // TODO -} - -} // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.h b/Source/Plugins/Plugin_VideoDX9/Src/Render.h deleted file mode 100644 index cc53d36e89fa..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.h +++ /dev/null @@ -1,63 +0,0 @@ - -#ifndef _RENDER_H_ -#define _RENDER_H_ - -#include "RenderBase.h" - -namespace DX9 -{ - -class Renderer : public ::Renderer -{ -public: - Renderer(); - ~Renderer(); - - void SetColorMask(); - void SetBlendMode(bool forceUpdate); - void SetScissorRect(const TargetRectangle& rc); - void SetGenerationMode(); - void SetDepthMode(); - void SetLogicOpMode(); - void SetDitherMode(); - void SetLineWidth(); - void SetSamplerState(int stage,int texindex); - void SetInterlacingMode(); - - void ApplyState(bool bUseDstAlpha); - void RestoreState(); - - void RenderText(const char* pstr, int left, int top, u32 color); - - u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data); - - void ResetAPIState(); - void RestoreAPIState(); - - TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc); - - void Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma); - - void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z); - - void ReinterpretPixelData(unsigned int convtype); - - void UpdateViewport(Matrix44& vpCorrection); - - bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc); - - static bool CheckForResize(); - - void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4); - void SetPSConstant4fv(unsigned int const_number, const float *f); - void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f); - - void SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4); - void SetVSConstant4fv(unsigned int const_number, const float *f); - void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f); - void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f); -}; - -} // namespace DX9 - -#endif diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp deleted file mode 100644 index ce8b1acaf5a8..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include - -#include "Globals.h" -#include "Statistics.h" -#include "MemoryUtil.h" -#include "Hash.h" -#include "HW/Memmap.h" - -#include "CommonPaths.h" -#include "FileUtil.h" - -#include "D3DBase.h" -#include "D3DTexture.h" -#include "D3DUtil.h" -#include "FramebufferManager.h" -#include "PixelShaderCache.h" -#include "PixelShaderManager.h" -#include "VertexShaderManager.h" -#include "VertexShaderCache.h" - -#include "Render.h" - -#include "TextureDecoder.h" -#include "TextureCache.h" -#include "HiresTextures.h" -#include "TextureConverter.h" -#include "Debugger.h" - -extern int frameCount; - -namespace DX9 -{ - -TextureCache::TCacheEntry::~TCacheEntry() -{ - texture->Release(); -} - -void TextureCache::TCacheEntry::Bind(unsigned int stage) -{ - D3D::SetTexture(stage, texture); -} - -bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level) -{ - IDirect3DSurface9* surface; - HRESULT hr = texture->GetSurfaceLevel(level, &surface); - if (FAILED(hr)) - return false; - - hr = PD3DXSaveSurfaceToFileA(filename, D3DXIFF_PNG, surface, NULL, NULL); - surface->Release(); - - return SUCCEEDED(hr); -} - -void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int level) -{ - D3D::ReplaceTexture2D(texture, temp, width, height, expanded_width, d3d_fmt, swap_r_b, level); -} - -void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat, - unsigned int srcFormat, const EFBRectangle& srcRect, - bool isIntensity, bool scaleByHalf, unsigned int cbufid, - const float *colmat) -{ - g_renderer->ResetAPIState(); // reset any game specific settings - - const LPDIRECT3DTEXTURE9 read_texture = (srcFormat == PIXELFMT_Z24) ? - FramebufferManager::GetEFBDepthTexture() : - FramebufferManager::GetEFBColorTexture(); - - if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture) - { - LPDIRECT3DSURFACE9 Rendersurf = NULL; - texture->GetSurfaceLevel(0, &Rendersurf); - D3D::dev->SetDepthStencilSurface(NULL); - D3D::dev->SetRenderTarget(0, Rendersurf); - - D3DVIEWPORT9 vp; - - // Stretch picture with increased internal resolution - vp.X = 0; - vp.Y = 0; - vp.Width = virtual_width; - vp.Height = virtual_height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - RECT destrect; - destrect.bottom = virtual_height; - destrect.left = 0; - destrect.right = virtual_width; - destrect.top = 0; - - PixelShaderManager::SetColorMatrix(colmat); // set transformation - TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); - RECT sourcerect; - sourcerect.bottom = targetSource.bottom; - sourcerect.left = targetSource.left; - sourcerect.right = targetSource.right; - sourcerect.top = targetSource.top; - - if (srcFormat == PIXELFMT_Z24) - { - if (scaleByHalf || g_ActiveConfig.iMultisampleMode) - { - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - } - else - { - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - } - } - else - { - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - } - - D3DFORMAT bformat = FramebufferManager::GetEFBDepthRTSurfaceFormat(); - int SSAAMode = g_ActiveConfig.iMultisampleMode; - - D3D::drawShadedTexQuad(read_texture, &sourcerect, - Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), - virtual_width, virtual_height, - // TODO: why is D3DFMT_D24X8 singled out here? why not D3DFMT_D24X4S4/D24S8/D24FS8/D32/D16/D15S1 too, or none of them? - PixelShaderCache::GetDepthMatrixProgram(SSAAMode, (srcFormat == PIXELFMT_Z24) && bformat != FOURCC_RAWZ && bformat != D3DFMT_D24X8), - VertexShaderCache::GetSimpleVertexShader(SSAAMode)); - - Rendersurf->Release(); - } - - if (!g_ActiveConfig.bCopyEFBToTexture) - { - int encoded_size = TextureConverter::EncodeToRamFromTexture( - addr, - read_texture, - Renderer::GetTargetWidth(), - Renderer::GetTargetHeight(), - srcFormat == PIXELFMT_Z24, - isIntensity, - dstFormat, - scaleByHalf, - srcRect); - - u8* dst = Memory::GetPointer(addr); - u64 hash = GetHash64(dst,encoded_size,g_ActiveConfig.iSafeTextureCache_ColorSamples); - - // Mark texture entries in destination address range dynamic unless caching is enabled and the texture entry is up to date - if (!g_ActiveConfig.bEFBCopyCacheEnable) - TextureCache::MakeRangeDynamic(addr,encoded_size); - else if (!TextureCache::Find(addr, hash)) - TextureCache::MakeRangeDynamic(addr,encoded_size); - - this->hash = hash; - } - - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); - D3D::SetTexture(0, NULL); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - - g_renderer->RestoreAPIState(); -} - -TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt) -{ - D3DFORMAT d3d_fmt; - bool swap_r_b = false; - - switch (pcfmt) - { - case PC_TEX_FMT_BGRA32: - d3d_fmt = D3DFMT_A8R8G8B8; - break; - - case PC_TEX_FMT_RGBA32: - d3d_fmt = D3DFMT_A8R8G8B8; - swap_r_b = true; - break; - - case PC_TEX_FMT_RGB565: - d3d_fmt = D3DFMT_R5G6B5; - break; - - case PC_TEX_FMT_IA4_AS_IA8: - d3d_fmt = D3DFMT_A8L8; - break; - - case PC_TEX_FMT_I8: - case PC_TEX_FMT_I4_AS_I8: - // A hack which means the format is a packed - // 8-bit intensity texture. It is unpacked - // to A8L8 in D3DTexture.cpp - d3d_fmt = D3DFMT_A8P8; - break; - - case PC_TEX_FMT_IA8: - d3d_fmt = D3DFMT_A8L8; - break; - - case PC_TEX_FMT_DXT1: - d3d_fmt = D3DFMT_DXT1; - break; - } - - TCacheEntry* entry = new TCacheEntry(D3D::CreateTexture2D(temp, width, height, expanded_width, d3d_fmt, swap_r_b, tex_levels)); - entry->swap_r_b = swap_r_b; - entry->d3d_fmt = d3d_fmt; - - entry->Load(width, height, expanded_width, 0); - - return entry; -} - -TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture( - unsigned int scaled_tex_w, unsigned int scaled_tex_h) -{ - LPDIRECT3DTEXTURE9 texture; - D3D::dev->CreateTexture(scaled_tex_w, scaled_tex_h, 1, D3DUSAGE_RENDERTARGET, - D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0); - - return new TCacheEntry(texture); -} - -} diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h deleted file mode 100644 index 5c711129f14a..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#ifndef _TEXTURECACHE_H -#define _TEXTURECACHE_H - - -#include - -#include "D3DBase.h" -#include "VideoCommon.h" -#include "BPMemory.h" - -#include "TextureCacheBase.h" - -namespace DX9 -{ - -class TextureCache : public ::TextureCache -{ -private: - struct TCacheEntry : TCacheEntryBase - { - const LPDIRECT3DTEXTURE9 texture; - - D3DFORMAT d3d_fmt; - bool swap_r_b; - - TCacheEntry(LPDIRECT3DTEXTURE9 _tex) : texture(_tex) {} - ~TCacheEntry(); - - void Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int levels); - - void FromRenderTarget(u32 dstAddr, unsigned int dstFormat, - unsigned int srcFormat, const EFBRectangle& srcRect, - bool isIntensity, bool scaleByHalf, unsigned int cbufid, - const float *colmat); - - void Bind(unsigned int stage); - bool Save(const char filename[], unsigned int level); - }; - - TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt); - - TCacheEntryBase* CreateRenderTargetTexture(unsigned int scaled_tex_w, unsigned int scaled_tex_h); -}; - -} - -#endif diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp deleted file mode 100644 index aff12af2c3d3..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp +++ /dev/null @@ -1,462 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -// Fast image conversion using OpenGL shaders. -// This kind of stuff would be a LOT nicer with OpenCL. - -#include "TextureConverter.h" -#include "TextureConversionShader.h" -#include "PixelShaderCache.h" -#include "VertexShaderManager.h" -#include "VertexShaderCache.h" -#include "FramebufferManager.h" -#include "Globals.h" -#include "VideoConfig.h" -#include "ImageWrite.h" -#include "Render.h" -#include "TextureCache.h" -#include "Math.h" -#include "FileUtil.h" -#include "HW/Memmap.h" - -namespace DX9 -{ - -namespace TextureConverter -{ -struct TransformBuffer -{ - LPDIRECT3DTEXTURE9 FBTexture; - LPDIRECT3DSURFACE9 RenderSurface; - LPDIRECT3DSURFACE9 ReadSurface; - int Width; - int Height; -}; -const u32 NUM_TRANSFORM_BUFFERS = 16; -static TransformBuffer TrnBuffers[NUM_TRANSFORM_BUFFERS]; -static u32 WorkingBuffers = 0; - -static LPDIRECT3DPIXELSHADER9 s_rgbToYuyvProgram = NULL; -static LPDIRECT3DPIXELSHADER9 s_yuyvToRgbProgram = NULL; - -// Not all slots are taken - but who cares. -const u32 NUM_ENCODING_PROGRAMS = 64; -static LPDIRECT3DPIXELSHADER9 s_encodingPrograms[NUM_ENCODING_PROGRAMS]; -static bool s_encodingProgramsFailed[NUM_ENCODING_PROGRAMS]; - -void CreateRgbToYuyvProgram() -{ - // Output is BGRA because that is slightly faster than RGBA. - char* FProgram = new char[2048]; - sprintf(FProgram,"uniform float4 blkDims : register(c%d);\n" - "uniform float4 textureDims : register(c%d);\n" - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - " out float4 ocol0 : COLOR0,\n" - " in float2 uv0 : TEXCOORD0,\n" - " in float uv2 : TEXCOORD1)\n" - "{\n" - " float2 uv1 = float2((uv0.x + 1.0f)/ blkDims.z, uv0.y / blkDims.w);\n" - " float3 c0 = tex2D(samp0, uv0.xy / blkDims.zw).rgb;\n" - " float3 c1 = tex2D(samp0, uv1).rgb;\n" - " c0 = pow(c0,uv2.xxx);\n" - " c1 = pow(c1,uv2.xxx);\n" - " float3 y_const = float3(0.257f,0.504f,0.098f);\n" - " float3 u_const = float3(-0.148f,-0.291f,0.439f);\n" - " float3 v_const = float3(0.439f,-0.368f,-0.071f);\n" - " float4 const3 = float4(0.0625f,0.5f,0.0625f,0.5f);\n" - " float3 c01 = (c0 + c1) * 0.5f;\n" - " ocol0 = float4(dot(c1,y_const),dot(c01,u_const),dot(c0,y_const),dot(c01, v_const)) + const3;\n" - "}\n",C_COLORMATRIX,C_COLORMATRIX+1); - - s_rgbToYuyvProgram = D3D::CompileAndCreatePixelShader(FProgram, (int)strlen(FProgram)); - if (!s_rgbToYuyvProgram) { - ERROR_LOG(VIDEO, "Failed to create RGB to YUYV fragment program"); - } - delete [] FProgram; -} - -void CreateYuyvToRgbProgram() -{ - char* FProgram = new char[2048]; - sprintf(FProgram,"uniform float4 blkDims : register(c%d);\n" - "uniform float4 textureDims : register(c%d);\n" - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - " out float4 ocol0 : COLOR0,\n" - " in float2 uv0 : TEXCOORD0)\n" - "{\n" - " float4 c0 = tex2D(samp0, uv0 / blkDims.zw).rgba;\n" - " float f = step(0.5, frac(uv0.x));\n" - " float y = lerp(c0.b, c0.r, f);\n" - " float yComp = 1.164f * (y - 0.0625f);\n" - " float uComp = c0.g - 0.5f;\n" - " float vComp = c0.a - 0.5f;\n" - - " ocol0 = float4(yComp + (1.596f * vComp),\n" - " yComp - (0.813f * vComp) - (0.391f * uComp),\n" - " yComp + (2.018f * uComp),\n" - " 1.0f);\n" - "}\n",C_COLORMATRIX,C_COLORMATRIX+1); - s_yuyvToRgbProgram = D3D::CompileAndCreatePixelShader(FProgram, (int)strlen(FProgram)); - if (!s_yuyvToRgbProgram) { - ERROR_LOG(VIDEO, "Failed to create YUYV to RGB fragment program"); - } - delete [] FProgram; -} - -LPDIRECT3DPIXELSHADER9 GetOrCreateEncodingShader(u32 format) -{ - if (format > NUM_ENCODING_PROGRAMS) - { - PanicAlert("Unknown texture copy format: 0x%x\n", format); - return s_encodingPrograms[0]; - } - - if (!s_encodingPrograms[format]) - { - if(s_encodingProgramsFailed[format]) - { - // we already failed to create a shader for this format, - // so instead of re-trying and showing the same error message every frame, just return. - return NULL; - } - - const char* shader = TextureConversionShader::GenerateEncodingShader(format,API_D3D9); - -#if defined(_DEBUG) || defined(DEBUGFAST) - if (g_ActiveConfig.iLog & CONF_SAVESHADERS && shader) { - static int counter = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "%senc_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); - - SaveData(szTemp, shader); - } -#endif - s_encodingPrograms[format] = D3D::CompileAndCreatePixelShader(shader, (int)strlen(shader)); - if (!s_encodingPrograms[format]) { - ERROR_LOG(VIDEO, "Failed to create encoding fragment program"); - s_encodingProgramsFailed[format] = true; - } - } - return s_encodingPrograms[format]; -} - -void Init() -{ - for (unsigned int i = 0; i < NUM_ENCODING_PROGRAMS; i++) - { - s_encodingPrograms[i] = NULL; - s_encodingProgramsFailed[i] = false; - } - for (unsigned int i = 0; i < NUM_TRANSFORM_BUFFERS; i++) - { - TrnBuffers[i].FBTexture = NULL; - TrnBuffers[i].RenderSurface = NULL; - TrnBuffers[i].ReadSurface = NULL; - TrnBuffers[i].Width = 0; - TrnBuffers[i].Height = 0; - } - CreateRgbToYuyvProgram(); - CreateYuyvToRgbProgram(); -} - -void Shutdown() -{ - if(s_rgbToYuyvProgram) - s_rgbToYuyvProgram->Release(); - s_rgbToYuyvProgram = NULL; - if(s_yuyvToRgbProgram) - s_yuyvToRgbProgram->Release(); - s_yuyvToRgbProgram=NULL; - - for (unsigned int i = 0; i < NUM_ENCODING_PROGRAMS; i++) - { - if(s_encodingPrograms[i]) - s_encodingPrograms[i]->Release(); - s_encodingPrograms[i] = NULL; - } - for (unsigned int i = 0; i < NUM_TRANSFORM_BUFFERS; i++) - { - if(TrnBuffers[i].RenderSurface != NULL) - TrnBuffers[i].RenderSurface->Release(); - TrnBuffers[i].RenderSurface = NULL; - - if(TrnBuffers[i].ReadSurface != NULL) - TrnBuffers[i].ReadSurface->Release(); - TrnBuffers[i].ReadSurface = NULL; - - if(TrnBuffers[i].FBTexture != NULL) - TrnBuffers[i].FBTexture->Release(); - TrnBuffers[i].FBTexture = NULL; - - TrnBuffers[i].Width = 0; - TrnBuffers[i].Height = 0; - } - WorkingBuffers = 0; -} - -void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, - u8* destAddr, int dstWidth, int dstHeight, int readStride, bool toTexture, bool linearFilter,float Gamma) -{ - HRESULT hr; - u32 index =0; - while(index < WorkingBuffers && (TrnBuffers[index].Width != dstWidth || TrnBuffers[index].Height != dstHeight)) - index++; - - LPDIRECT3DSURFACE9 s_texConvReadSurface = NULL; - LPDIRECT3DSURFACE9 Rendersurf = NULL; - - if (index >= WorkingBuffers) - { - if (WorkingBuffers < NUM_TRANSFORM_BUFFERS) - WorkingBuffers++; - if (index >= WorkingBuffers) - index--; - if (TrnBuffers[index].RenderSurface != NULL) - { - TrnBuffers[index].RenderSurface->Release(); - TrnBuffers[index].RenderSurface = NULL; - } - if (TrnBuffers[index].ReadSurface != NULL) - { - TrnBuffers[index].ReadSurface->Release(); - TrnBuffers[index].ReadSurface = NULL; - } - if (TrnBuffers[index].FBTexture != NULL) - { - TrnBuffers[index].FBTexture->Release(); - TrnBuffers[index].FBTexture = NULL; - } - TrnBuffers[index].Width = dstWidth; - TrnBuffers[index].Height = dstHeight; - D3D::dev->CreateTexture(dstWidth, dstHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, - D3DPOOL_DEFAULT, &TrnBuffers[index].FBTexture, NULL); - TrnBuffers[index].FBTexture->GetSurfaceLevel(0,&TrnBuffers[index].RenderSurface); - D3D::dev->CreateOffscreenPlainSurface(dstWidth, dstHeight, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &TrnBuffers[index].ReadSurface, NULL ); - } - - s_texConvReadSurface = TrnBuffers[index].ReadSurface; - Rendersurf = TrnBuffers[index].RenderSurface; - - hr = D3D::dev->SetDepthStencilSurface(NULL); - hr = D3D::dev->SetRenderTarget(0, Rendersurf); - - if (linearFilter) - { - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - } - else - { - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - } - - D3DVIEWPORT9 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = dstWidth; - vp.Height = dstHeight; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - hr = D3D::dev->SetViewport(&vp); - RECT SrcRect; - SrcRect.top = sourceRc.top; - SrcRect.left = sourceRc.left; - SrcRect.right = sourceRc.right; - SrcRect.bottom = sourceRc.bottom; - RECT DstRect; - DstRect.top = 0; - DstRect.left = 0; - DstRect.right = dstWidth; - DstRect.bottom = dstHeight; - - - // Draw... - D3D::drawShadedTexQuad(srcTexture,&SrcRect,1,1,dstWidth,dstHeight,shader,VertexShaderCache::GetSimpleVertexShader(0), Gamma); - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - // .. and then read back the results. - // TODO: make this less slow. - - hr = D3D::dev->GetRenderTargetData(Rendersurf,s_texConvReadSurface); - - D3DLOCKED_RECT drect; - hr = s_texConvReadSurface->LockRect(&drect, &DstRect, D3DLOCK_READONLY); - - int srcRowsPerBlockRow = readStride / (dstWidth*4); // 4 bytes per pixel - - int readLoops = dstHeight / srcRowsPerBlockRow; - const u8 *Source = (const u8*)drect.pBits; - for (int i = 0; i < readLoops; i++) - { - for (int j = 0; j < srcRowsPerBlockRow; ++j) - { - memcpy(destAddr + j*dstWidth*4, Source, dstWidth*4); - Source += drect.Pitch; - } - destAddr += bpmem.copyMipMapStrideChannels*32; - } - - hr = s_texConvReadSurface->UnlockRect(); -} - -int EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture, u32 SourceW, u32 SourceH, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) -{ - u32 format = copyfmt; - - if (bFromZBuffer) - { - format |= _GX_TF_ZTF; - if (copyfmt == 11) - format = GX_TF_Z16; - else if (format < GX_TF_Z8 || format > GX_TF_Z24X8) - format |= _GX_TF_CTF; - } - else - { - if (copyfmt > GX_TF_RGBA8 || (copyfmt < GX_TF_RGB565 && !bIsIntensityFmt)) - format |= _GX_TF_CTF; - } - - LPDIRECT3DPIXELSHADER9 texconv_shader = GetOrCreateEncodingShader(format); - if (!texconv_shader) - return 0; - - u8 *dest_ptr = Memory::GetPointer(address); - - int width = (source.right - source.left) >> bScaleByHalf; - int height = (source.bottom - source.top) >> bScaleByHalf; - - int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format); - - u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1; - u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1; - u16 samples = TextureConversionShader::GetEncodedSampleCount(format); - - // only copy on cache line boundaries - // extra pixels are copied but not displayed in the resulting texture - s32 expandedWidth = (width + blkW) & (~blkW); - s32 expandedHeight = (height + blkH) & (~blkH); - - float sampleStride = bScaleByHalf ? 2.f : 1.f; - TextureConversionShader::SetShaderParameters( - (float)expandedWidth, - (float)Renderer::EFBToScaledY(expandedHeight), // TODO: Why do we scale this? - (float)Renderer::EFBToScaledX(source.left), - (float)Renderer::EFBToScaledY(source.top), - Renderer::EFBToScaledXf(sampleStride), - Renderer::EFBToScaledYf(sampleStride), - (float)SourceW, - (float)SourceH); - - TargetRectangle scaledSource; - scaledSource.top = 0; - scaledSource.bottom = expandedHeight; - scaledSource.left = 0; - scaledSource.right = expandedWidth / samples; - int cacheBytes = 32; - if ((format & 0x0f) == 6) - cacheBytes = 64; - - int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); - EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0,1.0f); - return size_in_bytes; // TODO: D3D11 is calculating this value differently! -} - -void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight,float Gamma) -{ - TextureConversionShader::SetShaderParameters( - (float)dstWidth, - (float)dstHeight, - 0.0f, - 0.0f, - 1.0f, - 1.0f, - (float)Renderer::GetTargetWidth(), - (float)Renderer::GetTargetHeight()); - g_renderer->ResetAPIState(); - EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, - dstWidth / 2, dstHeight, dstWidth * 2, false, false,Gamma); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - g_renderer->RestoreAPIState(); -} - - -// Should be scale free. -void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE9 destTexture) -{ - u8* srcAddr = Memory::GetPointer(xfbAddr); - if (!srcAddr) - { - WARN_LOG(VIDEO, "Tried to decode from invalid memory address"); - return; - } - - int srcFmtWidth = srcWidth / 2; - - g_renderer->ResetAPIState(); // reset any game specific settings - LPDIRECT3DTEXTURE9 s_srcTexture = D3D::CreateTexture2D(srcAddr, srcFmtWidth, srcHeight, srcFmtWidth, D3DFMT_A8R8G8B8, false); - LPDIRECT3DSURFACE9 Rendersurf = NULL; - destTexture->GetSurfaceLevel(0,&Rendersurf); - D3D::dev->SetDepthStencilSurface(NULL); - D3D::dev->SetRenderTarget(0, Rendersurf); - - D3DVIEWPORT9 vp; - - // Stretch picture with increased internal resolution - vp.X = 0; - vp.Y = 0; - vp.Width = srcWidth; - vp.Height = srcHeight; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - RECT destrect; - destrect.bottom = srcHeight; - destrect.left = 0; - destrect.right = srcWidth; - destrect.top = 0; - - RECT sourcerect; - sourcerect.bottom = srcHeight; - sourcerect.left = 0; - sourcerect.right = srcFmtWidth; - sourcerect.top = 0; - - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - - TextureConversionShader::SetShaderParameters( - (float)srcFmtWidth, - (float)srcHeight, - 0.0f, - 0.0f, - 1.0f, - 1.0f, - (float)srcFmtWidth, - (float)srcHeight); - D3D::drawShadedTexQuad( - s_srcTexture, - &sourcerect, - 1, - 1, - srcWidth, - srcHeight, - s_yuyvToRgbProgram, - VertexShaderCache::GetSimpleVertexShader(0)); - - - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); - D3D::SetTexture(0,NULL); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - g_renderer->RestoreAPIState(); - Rendersurf->Release(); - s_srcTexture->Release(); -} - -} // namespace - -} // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.h b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.h deleted file mode 100644 index af23949f5c42..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#ifndef _TEXTURECONVERTER_H_ -#define _TEXTURECONVERTER_H_ - -#include "VideoCommon.h" -#include "D3DBase.h" -#include "D3DTexture.h" -#include "D3DUtil.h" -#include "D3DShader.h" - -namespace DX9 -{ - -// Converts textures between formats using shaders -// TODO: support multiple texture formats -namespace TextureConverter -{ - -void Init(); -void Shutdown(); - -void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, - u8* destAddr, int dstWidth, int dstHeight,float Gamma); - -void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE9 destTexture); - -// returns size of the encoded data (in bytes) -int EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture, u32 SourceW, u32 SourceH, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source); - - -} - -} // namespace DX9 - -#endif // _TEXTURECONVERTER_H_ diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp deleted file mode 100644 index dc79d68def77..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include "Common.h" -#include "FileUtil.h" - -#include "D3DBase.h" -#include "Fifo.h" -#include "Statistics.h" -#include "VertexManager.h" -#include "OpcodeDecoding.h" -#include "IndexGenerator.h" -#include "VertexShaderManager.h" -#include "VertexShaderCache.h" -#include "PixelShaderManager.h" -#include "PixelShaderCache.h" -#include "NativeVertexFormat.h" -#include "TextureCache.h" -#include "main.h" - -#include "BPStructs.h" -#include "XFStructs.h" -#include "Debugger.h" -#include "VideoConfig.h" - -// internal state for loading vertices -extern NativeVertexFormat *g_nativeVertexFmt; -namespace DX9 -{ -//This are the initially requeted size for the buffers expresed in elements -const u32 IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * sizeof(u16) * 8; -const u32 VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE; -const u32 MAX_VBUFFER_COUNT = 2; - -inline void DumpBadShaders() -{ -#if defined(_DEBUG) || defined(DEBUGFAST) - // TODO: Reimplement! - /* std::string error_shaders; - error_shaders.append(VertexShaderCache::GetCurrentShaderCode()); - error_shaders.append(PixelShaderCache::GetCurrentShaderCode()); - char filename[512] = "bad_shader_combo_0.txt"; - int which = 0; - while (File::Exists(filename)) - { - which++; - sprintf(filename, "bad_shader_combo_%i.txt", which); - } - File::WriteStringToFile(true, error_shaders, filename); - PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);*/ -#endif -} - -void VertexManager::CreateDeviceObjects() -{ - m_buffers_count = 0; - m_vertex_buffers = NULL; - m_index_buffers = NULL; - D3DCAPS9 DeviceCaps = D3D::GetCaps(); - u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride; - //Calculate Device Dependant size - m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE; - m_index_buffer_size = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; - //if device caps are not enough for Vbuffer fall back to vertex arrays - if (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return; - - m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT]; - m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT]; - - bool Fail = false; - for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) - { - m_vertex_buffers[m_current_vertex_buffer] = NULL; - m_index_buffers[m_current_vertex_buffer] = NULL; - } - for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) - { - if(FAILED( D3D::dev->CreateVertexBuffer( m_vertex_buffer_size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertex_buffers[m_current_vertex_buffer], NULL ) ) ) - { - Fail = true; - break; - } - if( FAILED( D3D::dev->CreateIndexBuffer( m_index_buffer_size * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_index_buffers[m_current_vertex_buffer], NULL ) ) ) - { - Fail = true; - return; - } - } - m_buffers_count = m_current_vertex_buffer; - m_current_vertex_buffer = 0; - m_current_index_buffer = 0; - m_index_buffer_cursor = m_index_buffer_size; - m_vertex_buffer_cursor = m_vertex_buffer_size; - m_current_stride = 0; - if (Fail) - { - m_buffers_count--; - if (m_buffers_count < 2) - { - //Error creating Vertex buffers. clean and fall to Vertex arrays - m_buffers_count = MAX_VBUFFER_COUNT; - DestroyDeviceObjects(); - } - } -} -void VertexManager::DestroyDeviceObjects() -{ - D3D::SetStreamSource( 0, NULL, 0, 0); - D3D::SetIndices(NULL); - for (int i = 0; i < MAX_VBUFFER_COUNT; i++) - { - if(m_vertex_buffers) - { - if (m_vertex_buffers[i]) - { - m_vertex_buffers[i]->Release(); - m_vertex_buffers[i] = NULL; - } - } - - if (m_index_buffers[i]) - { - m_index_buffers[i]->Release(); - m_index_buffers[i] = NULL; - } - } - if(m_vertex_buffers) - delete [] m_vertex_buffers; - if(m_index_buffers) - delete [] m_index_buffers; - m_vertex_buffers = NULL; - m_index_buffers = NULL; -} - -void VertexManager::PrepareDrawBuffers(u32 stride) -{ - if (!m_buffers_count) - { - return; - } - u8* pVertices; - u16* pIndices; - int datasize = IndexGenerator::GetNumVerts() * stride; - int TdataSize = IndexGenerator::GetTriangleindexLen(); - int LDataSize = IndexGenerator::GetLineindexLen(); - int IndexDataSize = TdataSize + LDataSize; - if(IndexDataSize) - { - DWORD LockMode = D3DLOCK_NOOVERWRITE; - m_vertex_buffer_cursor--; - m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; - if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize) - { - LockMode = D3DLOCK_DISCARD; - m_vertex_buffer_cursor = 0; - m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; - } - if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode))) - { - DestroyDeviceObjects(); - return; - } - memcpy(pVertices, s_pBaseBufferPointer, datasize); - m_vertex_buffers[m_current_vertex_buffer]->Unlock(); - - LockMode = D3DLOCK_NOOVERWRITE; - if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize) - { - LockMode = D3DLOCK_DISCARD; - m_index_buffer_cursor = 0; - m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; - } - - if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) - { - DestroyDeviceObjects(); - return; - } - if(TdataSize) - { - memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16)); - pIndices += TdataSize; - } - if(LDataSize) - { - memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16)); - pIndices += LDataSize; - } - m_index_buffers[m_current_index_buffer]->Unlock(); - } - if(m_current_stride != stride || m_vertex_buffer_cursor == 0) - { - m_current_stride = stride; - D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, m_current_stride); - } - if (m_index_buffer_cursor == 0) - { - D3D::SetIndices(m_index_buffers[m_current_index_buffer]); - } - - ADDSTAT(stats.thisFrame.bytesVertexStreamed, datasize); - ADDSTAT(stats.thisFrame.bytesIndexStreamed, IndexDataSize); -} - -void VertexManager::DrawVertexBuffer(int stride) -{ - int triangles = IndexGenerator::GetNumTriangles(); - int lines = IndexGenerator::GetNumLines(); - int points = IndexGenerator::GetNumPoints(); - int numverts = IndexGenerator::GetNumVerts(); - int StartIndex = m_index_buffer_cursor; - int basevertex = m_vertex_buffer_cursor / stride; - if (triangles > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_TRIANGLELIST, - basevertex, - 0, - numverts, - StartIndex, - triangles))) - { - DumpBadShaders(); - } - StartIndex += IndexGenerator::GetTriangleindexLen(); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (lines > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_LINELIST, - basevertex, - 0, - numverts, - StartIndex, - IndexGenerator::GetNumLines()))) - { - DumpBadShaders(); - } - StartIndex += IndexGenerator::GetLineindexLen(); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (points > 0) - { - //DrawIndexedPrimitive does not support point list so we have to draw them using DrawPrimitive - u16* PointIndexBuffer = GetPointIndexBuffer(); - int i = 0; - do - { - int count = i + 1; - while (count < points && PointIndexBuffer[count - 1] + 1 == PointIndexBuffer[count]) - { - count++; - } - if (FAILED(D3D::dev->DrawPrimitive( - D3DPT_POINTLIST, - basevertex + PointIndexBuffer[i], - count - i))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numDrawCalls); - i = count; - } while (i < points); - } - -} - -void VertexManager::DrawVertexArray(int stride) -{ - int triangles = IndexGenerator::GetNumTriangles(); - int lines = IndexGenerator::GetNumLines(); - int points = IndexGenerator::GetNumPoints(); - int numverts = IndexGenerator::GetNumVerts(); - if (triangles > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_TRIANGLELIST, - 0, numverts, triangles, - GetTriangleIndexBuffer(), - D3DFMT_INDEX16, - s_pBaseBufferPointer, - stride))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (lines > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_LINELIST, - 0, numverts, lines, - GetLineIndexBuffer(), - D3DFMT_INDEX16, - s_pBaseBufferPointer, - stride))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (points > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_POINTLIST, - 0, numverts, points, - GetPointIndexBuffer(), - D3DFMT_INDEX16, - s_pBaseBufferPointer, - stride))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } -} - -void VertexManager::vFlush() -{ - u32 usedtextures = 0; - for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) - if (bpmem.tevorders[i / 2].getEnable(i & 1)) - usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1); - - if (bpmem.genMode.numindstages > 0) - for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i) - if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) - usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt); - - for (unsigned int i = 0; i < 8; i++) - { - if (usedtextures & (1 << i)) - { - g_renderer->SetSamplerState(i & 3, i >> 2); - FourTexUnits &tex = bpmem.tex[i >> 2]; - TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i, - (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, - tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, - tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, - tex.texTlut[i&3].tlut_format, - (tex.texMode0[i&3].min_filter & 3), - (tex.texMode1[i&3].max_lod + 0xf) / 0x10, - tex.texImage1[i&3].image_type); - - if (tentry) - { - // 0s are probably for no manual wrapping needed. - PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0); - } - else - ERROR_LOG(VIDEO, "Error loading texture"); - } - } - - // set global constants - VertexShaderManager::SetConstants(); - PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components); - u32 stride = g_nativeVertexFmt->GetVertexStride(); - bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && - bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; - bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; - DSTALPHA_MODE AlphaMode = useDualSource ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE; - - if (!PixelShaderCache::SetShader(AlphaMode ,g_nativeVertexFmt->m_components)) - { - GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); - goto shader_fail; - } - if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components)) - { - GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set vertex shader\n");}); - goto shader_fail; - - } - PrepareDrawBuffers(stride); - g_nativeVertexFmt->SetupVertexPointers(); - g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); - if(m_buffers_count) - { - DrawVertexBuffer(stride); - } - else - { - DrawVertexArray(stride); - } - g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); - if (useDstAlpha && !useDualSource) - { - if (!PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS, g_nativeVertexFmt->m_components)) - { - GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); - goto shader_fail; - } - // update alpha only - g_renderer->ApplyState(true); - if(m_buffers_count) - { - DrawVertexBuffer(stride); - } - else - { - DrawVertexArray(stride); - } - g_renderer->RestoreState(); - } - GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); - -shader_fail: - if(m_buffers_count) - { - m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); - m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; - } -} - -} diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h deleted file mode 100644 index 81a1c58211ad..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#ifndef _VERTEXMANAGER_H -#define _VERTEXMANAGER_H - -#include "CPMemory.h" -#include "VertexLoader.h" - -#include "VertexManagerBase.h" - -namespace DX9 -{ - -class VertexManager : public ::VertexManager -{ -public: - NativeVertexFormat* CreateNativeVertexFormat(); - void GetElements(NativeVertexFormat* format, D3DVERTEXELEMENT9** elems, int* num); - void CreateDeviceObjects(); - void DestroyDeviceObjects(); -private: - u32 m_vertex_buffer_cursor; - u32 m_vertex_buffer_size; - u32 m_index_buffer_cursor; - u32 m_index_buffer_size; - u32 m_buffers_count; - u32 m_current_vertex_buffer; - u32 m_current_stride; - u32 m_current_index_buffer; - LPDIRECT3DVERTEXBUFFER9 *m_vertex_buffers; - LPDIRECT3DINDEXBUFFER9 *m_index_buffers; - void PrepareDrawBuffers(u32 stride); - void DrawVertexBuffer(int stride); - void DrawVertexArray(int stride); - // temp - void vFlush(); -}; - -} - -#endif diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp deleted file mode 100644 index 7c53bdfe2323..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ /dev/null @@ -1,293 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include - -#include "Common.h" -#include "FileUtil.h" -#include "LinearDiskCache.h" - -#include "Globals.h" -#include "D3DBase.h" -#include "D3DShader.h" -#include "Statistics.h" -#include "VideoConfig.h" -#include "VertexShaderCache.h" -#include "VertexLoader.h" -#include "BPMemory.h" -#include "XFMemory.h" -#include "Debugger.h" -#include "ConfigManager.h" - -namespace DX9 -{ - -VertexShaderCache::VSCache VertexShaderCache::vshaders; -const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry; -VertexShaderUid VertexShaderCache::last_uid; -UidChecker VertexShaderCache::vertex_uid_checker; - -#define MAX_SSAA_SHADERS 3 - -static LPDIRECT3DVERTEXSHADER9 SimpleVertexShader[MAX_SSAA_SHADERS]; -static LPDIRECT3DVERTEXSHADER9 ClearVertexShader; - -LinearDiskCache g_vs_disk_cache; - -LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexShader(int level) -{ - return SimpleVertexShader[level % MAX_SSAA_SHADERS]; -} - -LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader() -{ - return ClearVertexShader; -} - -// this class will load the precompiled shaders into our cache -class VertexShaderCacheInserter : public LinearDiskCacheReader -{ -public: - void Read(const VertexShaderUid &key, const u8 *value, u32 value_size) - { - VertexShaderCache::InsertByteCode(key, value, value_size, false); - } -}; - -void VertexShaderCache::Init() -{ - char* vProg = new char[2048]; - sprintf(vProg,"struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float2 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;\n" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0;\n" - "OUT.vTexCoord1 = inTEX2;\n" - "return OUT;\n" - "}\n"); - - SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - - sprintf(vProg,"struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float4 vColor0 : COLOR0;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n" - "{\n" - "VSOUTPUT OUT;\n" - "OUT.vPosition = inPosition;\n" - "OUT.vColor0 = inColor0;\n" - "return OUT;\n" - "}\n"); - - ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - sprintf(vProg, "struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float4 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "float4 vTexCoord2 : TEXCOORD2;\n" - "float4 vTexCoord3 : TEXCOORD3;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0.xyyx;\n" - "OUT.vTexCoord1 = inTEX2.x;\n" - "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.495f,-0.495f, 0.495f,-0.495f) * inTEX1.xyyx);\n" - "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.495f, 0.495f,-0.495f, 0.495f) * inTEX1.xyyx);\n" - "return OUT;\n" - "}\n"); - SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - - sprintf(vProg, "struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float4 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "float4 vTexCoord2 : TEXCOORD2;\n" - "float4 vTexCoord3 : TEXCOORD3;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0.xyyx;\n" - "OUT.vTexCoord1 = inTEX2.x;\n" - "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.9f,-0.45f, 0.9f,-0.45f) * inTEX1.xyyx);\n" - "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.9f, 0.45f,-0.9f, 0.45f) * inTEX1.xyyx);\n" - "return OUT;\n" - "}\n"); - SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - - Clear(); - delete [] vProg; - - if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) - File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); - - SETSTAT(stats.numVertexShadersCreated, 0); - SETSTAT(stats.numVertexShadersAlive, 0); - - char cache_filename[MAX_PATH]; - sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); - VertexShaderCacheInserter inserter; - g_vs_disk_cache.OpenAndRead(cache_filename, inserter); - - if (g_Config.bEnableShaderDebugging) - Clear(); - - last_entry = NULL; -} - -void VertexShaderCache::Clear() -{ - for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter) - iter->second.Destroy(); - vshaders.clear(); - vertex_uid_checker.Invalidate(); - - last_entry = NULL; -} - -void VertexShaderCache::Shutdown() -{ - for (int i = 0; i < MAX_SSAA_SHADERS; i++) - { - if (SimpleVertexShader[i]) - SimpleVertexShader[i]->Release(); - SimpleVertexShader[i] = NULL; - } - - if (ClearVertexShader) - ClearVertexShader->Release(); - ClearVertexShader = NULL; - - Clear(); - g_vs_disk_cache.Sync(); - g_vs_disk_cache.Close(); -} - -bool VertexShaderCache::SetShader(u32 components) -{ - VertexShaderUid uid; - GetVertexShaderUid(uid, components, API_D3D9); - if (g_ActiveConfig.bEnableShaderDebugging) - { - VertexShaderCode code; - GenerateVertexShaderCode(code, components, API_D3D9); - vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v"); - } - - if (last_entry) - { - if (uid == last_uid) - { - GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - return (last_entry->shader != NULL); - } - } - - last_uid = uid; - - VSCache::iterator iter = vshaders.find(uid); - if (iter != vshaders.end()) - { - const VSCacheEntry &entry = iter->second; - last_entry = &entry; - - if (entry.shader) D3D::SetVertexShader(entry.shader); - GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - return (entry.shader != NULL); - } - - VertexShaderCode code; - GenerateVertexShaderCode(code, components, API_D3D9); - - u8 *bytecode; - int bytecodelen; - if (!D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) - { - GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); - return false; - } - g_vs_disk_cache.Append(uid, bytecode, bytecodelen); - - bool success = InsertByteCode(uid, bytecode, bytecodelen, true); - if (g_ActiveConfig.bEnableShaderDebugging && success) - { - vshaders[uid].code = code.GetBuffer(); - } - delete [] bytecode; - GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - return success; -} - -bool VertexShaderCache::InsertByteCode(const VertexShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) { - LPDIRECT3DVERTEXSHADER9 shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen); - - // Make an entry in the table - VSCacheEntry entry; - entry.shader = shader; - - vshaders[uid] = entry; - last_entry = &vshaders[uid]; - if (!shader) - return false; - - INCSTAT(stats.numVertexShadersCreated); - SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); - if (activate) - { - D3D::SetVertexShader(shader); - return true; - } - return false; -} - -float VSConstantbuffer[4*C_VENVCONST_END]; - -void Renderer::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) -{ - float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; - VSConstantbuffer_pointer[0] = f1; - VSConstantbuffer_pointer[1] = f2; - VSConstantbuffer_pointer[2] = f3; - VSConstantbuffer_pointer[3] = f4; - DX9::D3D::dev->SetVertexShaderConstantF(const_number, VSConstantbuffer_pointer, 1); -} - -void Renderer::SetVSConstant4fv(unsigned int const_number, const float *f) -{ - DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, 1); -} - -void Renderer::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f) -{ - float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; - for (unsigned int i = 0; i < count; i++) - { - *VSConstantbuffer_pointer++ = *f++; - *VSConstantbuffer_pointer++ = *f++; - *VSConstantbuffer_pointer++ = *f++; - *VSConstantbuffer_pointer++ = 0.f; - } - DX9::D3D::dev->SetVertexShaderConstantF(const_number, &VSConstantbuffer[const_number], count); -} - -void Renderer::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f) -{ - DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, count); -} - -} // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h deleted file mode 100644 index 32fbea92be72..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#pragma once - -#include "D3DBase.h" - -#include -#include - -#include "D3DBase.h" -#include "VertexShaderGen.h" - -namespace DX9 -{ - -class VertexShaderCache -{ -private: - struct VSCacheEntry - { - LPDIRECT3DVERTEXSHADER9 shader; - - std::string code; - - VSCacheEntry() : shader(NULL) {} - void Destroy() - { - if (shader) - shader->Release(); - shader = NULL; - } - }; - - typedef std::map VSCache; - - static VSCache vshaders; - static const VSCacheEntry *last_entry; - static VertexShaderUid last_uid; - - static UidChecker vertex_uid_checker; - - static void Clear(); - -public: - static void Init(); - static void Shutdown(); - static bool SetShader(u32 components); - static LPDIRECT3DVERTEXSHADER9 GetSimpleVertexShader(int level); - static LPDIRECT3DVERTEXSHADER9 GetClearVertexShader(); - static bool InsertByteCode(const VertexShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate); - - static std::string GetCurrentShaderCode(); -}; - -} // namespace DX9 \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VideoBackend.h b/Source/Plugins/Plugin_VideoDX9/Src/VideoBackend.h deleted file mode 100644 index 5b7c54d326b6..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/VideoBackend.h +++ /dev/null @@ -1,29 +0,0 @@ - -#ifndef DX9_VIDEO_BACKEND_H_ -#define DX9_VIDEO_BACKEND_H_ - -#include "VideoBackendBase.h" - -namespace DX9 -{ - -class VideoBackend : public VideoBackendHardware -{ - bool Initialize(void *&); - void Shutdown(); - - std::string GetName(); - std::string GetDisplayName(); - - void Video_Prepare(); - void Video_Cleanup(); - - void ShowConfig(void* parent); - - void UpdateFPSDisplay(const char*); - unsigned int PeekMessages(); -}; - -} - -#endif diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp deleted file mode 100644 index eff3fd9d1c71..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include "Common.h" -#include "Atomic.h" -#include "Thread.h" -#include "LogManager.h" - -#if defined(HAVE_WX) && HAVE_WX -#include "VideoConfigDiag.h" -#endif // HAVE_WX - -#if defined(HAVE_WX) && HAVE_WX -#include "Debugger/DebuggerPanel.h" -#endif // HAVE_WX - -#include "MainBase.h" -#include "main.h" -#include "VideoConfig.h" -#include "Fifo.h" -#include "OpcodeDecoding.h" -#include "TextureCache.h" -#include "BPStructs.h" -#include "VertexManager.h" -#include "FramebufferManager.h" -#include "VertexLoaderManager.h" -#include "VertexShaderManager.h" -#include "PixelShaderManager.h" -#include "VertexShaderCache.h" -#include "PixelShaderCache.h" -#include "CommandProcessor.h" -#include "PixelEngine.h" -#include "OnScreenDisplay.h" -#include "D3DTexture.h" -#include "D3DUtil.h" -#include "EmuWindow.h" -#include "VideoState.h" -#include "Render.h" -#include "DLCache.h" -#include "IndexGenerator.h" -#include "IniFile.h" -#include "Core.h" -#include "Host.h" - -#include "ConfigManager.h" -#include "VideoBackend.h" -#include "PerfQuery.h" - -namespace DX9 -{ - -unsigned int VideoBackend::PeekMessages() -{ - MSG msg; - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) - { - if (msg.message == WM_QUIT) - return FALSE; - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return TRUE; -} - -void VideoBackend::UpdateFPSDisplay(const char *text) -{ - TCHAR temp[512]; - swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text); - EmuWindow::SetWindowText(temp); -} - -std::string VideoBackend::GetName() -{ - return "DX9"; -} - -std::string VideoBackend::GetDisplayName() -{ - return "Direct3D9 (deprecated)"; -} - -void InitBackendInfo() -{ - DX9::D3D::Init(); - D3DCAPS9 device_caps = DX9::D3D::GetCaps(); - const int shaderModel = ((device_caps.PixelShaderVersion >> 8) & 0xFF); - const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); - g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 : API_D3D9_SM30; - g_Config.backend_info.bUseRGBATextures = false; - g_Config.backend_info.bUseMinimalMipCount = true; - g_Config.backend_info.bSupports3DVision = true; - g_Config.backend_info.bSupportsPrimitiveRestart = false; // D3D9 does not support primitive restart - g_Config.backend_info.bSupportsSeparateAlphaFunction = device_caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND; - // Dual source blend disabled by default until a proper method to test for support is found - g_Config.backend_info.bSupports3DVision = true; - OSVERSIONINFO info; - ZeroMemory(&info, sizeof(OSVERSIONINFO)); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (GetVersionEx(&info)) - { - // dual source blending is only supported in windows 7 o newer. sorry xp users - // we cannot test for device caps because most drivers just declare the minimun caps - // and don't expose their support for some functionalities - g_Config.backend_info.bSupportsDualSourceBlend = g_Config.backend_info.bSupportsSeparateAlphaFunction && (info.dwPlatformId == VER_PLATFORM_WIN32_NT) && ((info.dwMajorVersion > 6) || ((info.dwMajorVersion == 6) && info.dwMinorVersion >= 1)); - } - else - { - g_Config.backend_info.bSupportsDualSourceBlend = false; - } - g_Config.backend_info.bSupportsFormatReinterpretation = true; - g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants; - g_Config.backend_info.bSupportsEarlyZ = false; - - // adapters - g_Config.backend_info.Adapters.clear(); - for (int i = 0; i < DX9::D3D::GetNumAdapters(); ++i) - g_Config.backend_info.Adapters.push_back(DX9::D3D::GetAdapter(i).ident.Description); - - // aamodes - g_Config.backend_info.AAModes.clear(); - if (g_Config.iAdapter < DX9::D3D::GetNumAdapters()) - { - const DX9::D3D::Adapter &adapter = DX9::D3D::GetAdapter(g_Config.iAdapter); - - for (int i = 0; i < (int)adapter.aa_levels.size(); ++i) - g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name); - } - - // Clear ppshaders string vector - g_Config.backend_info.PPShaders.clear(); - - DX9::D3D::Shutdown(); -} - -void VideoBackend::ShowConfig(void* parent) -{ -#if defined(HAVE_WX) && HAVE_WX - InitBackendInfo(); - VideoConfigDiag diag((wxWindow*)parent, _trans("Direct3D9"), "gfx_dx9"); - diag.ShowModal(); -#endif -} - -bool VideoBackend::Initialize(void *&window_handle) -{ - InitializeShared(); - InitBackendInfo(); - - frameCount = 0; - - g_Config.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_dx9.ini").c_str()); - g_Config.GameIniLoad(); - g_Config.UpdateProjectionHack(); - g_Config.VerifyValidity(); - // as only some driver/hardware configurations support dual source blending only enable it if is - // configured by user - g_Config.backend_info.bSupportsDualSourceBlend &= g_Config.bForceDualSourceBlend; - UpdateActiveConfig(); - - window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Loading - Please wait.")); - if (window_handle == NULL) - { - ERROR_LOG(VIDEO, "An error has occurred while trying to create the window."); - return false; - } - else if (FAILED(DX9::D3D::Init())) - { - MessageBox(GetActiveWindow(), _T("Unable to initialize Direct3D. Please make sure that you have the latest version of DirectX 9.0c correctly installed."), _T("Fatal Error"), MB_ICONERROR|MB_OK); - return false; - } - - s_BackendInitialized = true; - - return true; -} - -void VideoBackend::Video_Prepare() -{ - // Better be safe... - s_efbAccessRequested = FALSE; - s_FifoShuttingDown = FALSE; - s_swapRequested = FALSE; - - // internal interfaces - g_vertex_manager = new VertexManager; - g_perf_query = new PerfQuery; - g_renderer = new Renderer; - g_texture_cache = new TextureCache; - // VideoCommon - BPInit(); - Fifo_Init(); - IndexGenerator::Init(); - VertexLoaderManager::Init(); - OpcodeDecoder_Init(); - VertexShaderManager::Init(); - PixelShaderManager::Init(); - CommandProcessor::Init(); - PixelEngine::Init(); - DLCache::Init(); - // Notify the core that the video backend is ready - Host_Message(WM_USER_CREATE); -} - -void VideoBackend::Shutdown() -{ - s_BackendInitialized = false; - - // TODO: should be in Video_Cleanup - if (g_renderer) - { - s_efbAccessRequested = FALSE; - s_FifoShuttingDown = FALSE; - s_swapRequested = FALSE; - - // VideoCommon - DLCache::Shutdown(); - Fifo_Shutdown(); - CommandProcessor::Shutdown(); - PixelShaderManager::Shutdown(); - VertexShaderManager::Shutdown(); - OpcodeDecoder_Shutdown(); - VertexLoaderManager::Shutdown(); - - // internal interfaces - PixelShaderCache::Shutdown(); - VertexShaderCache::Shutdown(); - delete g_texture_cache; - delete g_renderer; - delete g_perf_query; - delete g_vertex_manager; - g_renderer = NULL; - g_texture_cache = NULL; - } - D3D::Shutdown(); -} - -void VideoBackend::Video_Cleanup() { -} - -} diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.h b/Source/Plugins/Plugin_VideoDX9/Src/main.h deleted file mode 100644 index 07d615b6e1d4..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#ifndef MAIN_H -#define MAIN_H - -#include - -#include "VideoBackend.h" -#include "Render.h" -#include "MainBase.h" - -#endif diff --git a/Source/Plugins/Plugin_VideoDX9/Src/stdafx.cpp b/Source/Plugins/Plugin_VideoDX9/Src/stdafx.cpp deleted file mode 100644 index b602b399250a..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/stdafx.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include "stdafx.h" diff --git a/Source/Plugins/Plugin_VideoDX9/Src/stdafx.h b/Source/Plugins/Plugin_VideoDX9/Src/stdafx.h deleted file mode 100644 index 2431184aafbd..000000000000 --- a/Source/Plugins/Plugin_VideoDX9/Src/stdafx.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#pragma once -#define _WIN32_WINNT 0x501 -#ifndef _WIN32_IE -#define _WIN32_IE 0x0500 // Default value is 0x0400 -#endif - -#include -#include