ITexture * VOODOO_METHODTYPE FrostAdapter::CreateTexture(_In_ const String & name, _In_ const TextureDesc pDesc)
        {
            GLuint texture;
            GLint texFmt, texIFmt, texType;

            switch (pDesc.Format)
            {
            case VSFmtRGBA8:
                texFmt = GL_RGBA;
                texIFmt = GL_RGBA8;
                texType = GL_UNSIGNED_BYTE;
                break;
            case VSFmtRGB8:
                texFmt = GL_RGB;
                texIFmt = GL_RGB8;
                texType = GL_UNSIGNED_BYTE;
                break;
            case VSFmtRGBA16F:
                texFmt = GL_RGBA;
                texIFmt = GL_RGBA16F;
                texType = GL_FLOAT;
                break;
            case VSFmtRGBA32F:
                texFmt = GL_RGBA;
                texIFmt = GL_RGBA32F;
                texType = GL_DOUBLE;
                break;
            case VSFmtD16:
                texFmt = GL_DEPTH_COMPONENT;
                texIFmt = GL_DEPTH_COMPONENT16;
                texType = GL_FLOAT;
                break;
            case VSFmtD32:
                texFmt = GL_DEPTH_COMPONENT;
                texIFmt = GL_DEPTH_COMPONENT32;
                texType = GL_DOUBLE;
                break;
            case VSFmtUnknown:
            default:
                m_Core->GetLogger()->LogMessage(VSLog_ModWarning, VOODOO_FROST_NAME, VSTR("Unable to resolve texture format."));
                return false;
            }

            glGenTextures(1, &texture);

            GLenum error = glGetError();

            while (error != GL_NO_ERROR)
            {
                m_Core->GetLogger()->LogMessage(VSLog_ModWarning, VOODOO_FROST_NAME, Format("OpenGL returned error %u: %S") << error << glGetString(error));
                error = glGetError();
            }

            glBindTexture(GL_TEXTURE_2D, texture);
            glTexImage2D(GL_TEXTURE_2D, 0, texIFmt, pDesc.Size.X, pDesc.Size.Y, 0, texFmt, texType, nullptr);
            glBindTexture(GL_TEXTURE_2D, 0);

            error = glGetError();
            while (error != GL_NO_ERROR)
            {
                m_Core->GetLogger()->LogMessage(VSLog_ModWarning, VOODOO_FROST_NAME, Format("OpenGL returned error %u: %S") << error << glGetString(error));
                error = glGetError();
            }

            if (glIsTexture(texture))
            {
                m_Core->GetLogger()->LogMessage(VSLog_ModDebug, VOODOO_FROST_NAME, Format("OpenGL texture %u created successfully.") << texture);
            }
            else
            {
                m_Core->GetLogger()->LogMessage(VSLog_ModDebug, VOODOO_FROST_NAME, Format("OpenGL create failed, returned texture %u.") << texture);
            }

            return new FrostTexture(m_Core, name, texture);
        }
Beispiel #2
0
	void Jit::Comp_SVQ(u32 op)
	{
		CONDITIONAL_DISABLE;

		int imm = (signed short)(op&0xFFFC);
		int vt = (((op >> 16) & 0x1f)) | ((op&1) << 5);
		int rs = _RS;

		bool doCheck = false;
		switch (op >> 26)
		{
		case 54: //lv.q
			{
				// CC might be set by slow path below, so load regs first.
				u8 vregs[4];
				GetVectorRegs(vregs, V_Quad, vt);
				fpr.MapRegsV(vregs, V_Quad, MAP_DIRTY | MAP_NOINIT);
				fpr.ReleaseSpillLocks();

				if (gpr.IsImm(rs)) {
					u32 addr = (imm + gpr.GetImm(rs)) & 0x3FFFFFFF;
					MOVI2R(R0, addr + (u32)Memory::base);
				} else {
					gpr.MapReg(rs);
					if (g_Config.bFastMemory) {
						SetR0ToEffectiveAddress(rs, imm);
					} else {
						SetCCAndR0ForSafeAddress(rs, imm, R1);
						doCheck = true;
					}
					ADD(R0, R0, R11);
				}

				for (int i = 0; i < 4; i++)
					VLDR(fpr.V(vregs[i]), R0, i * 4);

				if (doCheck) {
					SetCC(CC_EQ);
					MOVI2R(R0, 0);
					for (int i = 0; i < 4; i++)
						VMOV(fpr.V(vregs[i]), R0);
					SetCC(CC_AL);
				}
			}
			break;

		case 62: //sv.q
			{
				// CC might be set by slow path below, so load regs first.
				u8 vregs[4];
				GetVectorRegs(vregs, V_Quad, vt);
				fpr.MapRegsV(vregs, V_Quad, 0);
				fpr.ReleaseSpillLocks();

				if (gpr.IsImm(rs)) {
					u32 addr = (imm + gpr.GetImm(rs)) & 0x3FFFFFFF;
					MOVI2R(R0, addr + (u32)Memory::base);
				} else {
					gpr.MapReg(rs);
					if (g_Config.bFastMemory) {
						SetR0ToEffectiveAddress(rs, imm);
					} else {
						SetCCAndR0ForSafeAddress(rs, imm, R1);
						doCheck = true;
					}
					ADD(R0, R0, R11);
				}

				for (int i = 0; i < 4; i++)
					VSTR(fpr.V(vregs[i]), R0, i * 4);

				if (doCheck) {
					SetCC(CC_AL);
				}
			}
			break;

		default:
			DISABLE;
			break;
		}
	}
Beispiel #3
0
	void Jit::Comp_SV(u32 op) {
		CONDITIONAL_DISABLE;

		s32 imm = (signed short)(op&0xFFFC);
		int vt = ((op >> 16) & 0x1f) | ((op & 3) << 5);
		int rs = _RS;

		bool doCheck = false;
		switch (op >> 26)
		{
		case 50: //lv.s  // VI(vt) = Memory::Read_U32(addr);
			{
				// CC might be set by slow path below, so load regs first.
				fpr.MapRegV(vt, MAP_DIRTY | MAP_NOINIT);
				fpr.ReleaseSpillLocks();
				if (gpr.IsImm(rs)) {
					u32 addr = (imm + gpr.GetImm(rs)) & 0x3FFFFFFF;
					MOVI2R(R0, addr + (u32)Memory::base);
				} else {
					gpr.MapReg(rs);
					if (g_Config.bFastMemory) {
						SetR0ToEffectiveAddress(rs, imm);
					} else {
						SetCCAndR0ForSafeAddress(rs, imm, R1);
						doCheck = true;
					}
					ADD(R0, R0, R11);
				}
				VLDR(fpr.V(vt), R0, 0);
				if (doCheck) {
					SetCC(CC_EQ);
					MOVI2R(R0, 0);
					VMOV(fpr.V(vt), R0);
					SetCC(CC_AL);
				}
			}
			break;

		case 58: //sv.s   // Memory::Write_U32(VI(vt), addr);
			{
				// CC might be set by slow path below, so load regs first.
				fpr.MapRegV(vt);
				fpr.ReleaseSpillLocks();
				if (gpr.IsImm(rs)) {
					u32 addr = (imm + gpr.GetImm(rs)) & 0x3FFFFFFF;
					MOVI2R(R0, addr + (u32)Memory::base);
				} else {
					gpr.MapReg(rs);
					if (g_Config.bFastMemory) {
						SetR0ToEffectiveAddress(rs, imm);
					} else {
						SetCCAndR0ForSafeAddress(rs, imm, R1);
						doCheck = true;
					}
					ADD(R0, R0, R11);
				}
				VSTR(fpr.V(vt), R0, 0);
				if (doCheck) {
					SetCC(CC_AL);
				}
			}
			break;


		default:
			DISABLE;
		}
	}
Beispiel #4
0
void Jit::Comp_FPULS(u32 op)
{
	CONDITIONAL_DISABLE;

	s32 offset = (s16)(op & 0xFFFF);
	int ft = _FT;
	int rs = _RS;
	// u32 addr = R(rs) + offset;
	// logBlocks = 1;
	bool doCheck = false;
	switch(op >> 26)
	{
	case 49: //FI(ft) = Memory::Read_U32(addr); break; //lwc1
		fpr.SpillLock(ft);
		fpr.MapReg(ft, MAP_NOINIT | MAP_DIRTY);
		if (gpr.IsImm(rs)) {
			u32 addr = (offset + gpr.GetImm(rs)) & 0x3FFFFFFF;
			MOVI2R(R0, addr + (u32)Memory::base);
		} else {
			gpr.MapReg(rs);
			if (g_Config.bFastMemory) {
				SetR0ToEffectiveAddress(rs, offset);
			} else {
				SetCCAndR0ForSafeAddress(rs, offset, R1);
				doCheck = true;
			}
			ADD(R0, R0, R11);
		}
#ifdef __ARM_ARCH_7S__
		FixupBranch skip;
		if (doCheck) {
			skip = B_CC(CC_EQ);
		}
		VLDR(fpr.R(ft), R0, 0);
		if (doCheck) {
			SetJumpTarget(skip);
			SetCC(CC_AL);
		}
#else
		VLDR(fpr.R(ft), R0, 0);
		if (doCheck) {
			SetCC(CC_EQ);
			MOVI2R(R0, 0);
			VMOV(fpr.R(ft), R0);
			SetCC(CC_AL);
		}
#endif
		fpr.ReleaseSpillLocksAndDiscardTemps();
		break;

	case 57: //Memory::Write_U32(FI(ft), addr); break; //swc1
		fpr.MapReg(ft);
		if (gpr.IsImm(rs)) {
			u32 addr = (offset + gpr.GetImm(rs)) & 0x3FFFFFFF;
			MOVI2R(R0, addr + (u32)Memory::base);
		} else {
			gpr.MapReg(rs);
			if (g_Config.bFastMemory) {
				SetR0ToEffectiveAddress(rs, offset);
			} else {
				SetCCAndR0ForSafeAddress(rs, offset, R1);
				doCheck = true;
			}
			ADD(R0, R0, R11);
		}
#ifdef __ARM_ARCH_7S__
		FixupBranch skip2;
		if (doCheck) {
			skip2 = B_CC(CC_EQ);
		}
		VSTR(fpr.R(ft), R0, 0);
		if (doCheck) {
			SetJumpTarget(skip2);
			SetCC(CC_AL);
		}
#else
		VSTR(fpr.R(ft), R0, 0);
		if (doCheck) {
			SetCC(CC_AL);
		}
#endif
		break;

	default:
		Comp_Generic(op);
		return;
	}
}
Beispiel #5
0
    {
    public:
        VSParser();

        VOODOO_METHOD_(uint32_t, AddRef)() CONST;
        VOODOO_METHOD_(uint32_t, Release)() CONST;
        VOODOO_METHOD(QueryInterface)(_In_ CONST Uuid refid, _Outptr_result_maybenull_ IObject ** ppOut);
        VOODOO_METHOD_(String, ToString)() CONST;
        VOODOO_METHOD_(ICore *, GetCore)() CONST;

        VOODOO_METHOD(Add)(_In_ CONST String & name, _In_ CONST String & value, _In_ CONST VariableType type = VSVar_Normal);
        VOODOO_METHOD(Remove)(_In_ CONST String & name);
        VOODOO_METHOD_(String, Parse)(_In_ CONST String & input, _In_ CONST ParseFlags flags = VSParse_None) CONST;

        static const uint32_t VarMaxDepth    = 8;
        static const wchar_t  VarDelimPre    = VSTR('$');
        static const wchar_t  VarDelimStart  = VSTR('(');
        static const wchar_t  VarDelimEnd    = VSTR(')');
        static const wchar_t  VarMarkerState = VSTR(':');
        static const wchar_t  VarMarkerReq   = VSTR('!');
        static const wchar_t  VarMarkerDelay = VSTR('~');
        static const wchar_t  VarMarkerMode  = VSTR('@');
        static const wchar_t  VarMarkerModeD = VSTR(' ');
        static const wchar_t  VarMarkerModeM = VSTR('+');
        static const wchar_t  VarMarkerModeR = VSTR('-');

    private:
        // Private these to prevent copying internally (external libs never will).
        VSParser(CONST VSParser & other);
        VSParser & operator=(CONST VSParser & other);
        ~VSParser();
Beispiel #6
0
    _Check_return_ VOODOO_METHODDEF(VSCore::Init)(_In_z_ CONST wchar_t * config)
    {
        if (config)
        {
            m_Parser->Add(VSTR("config"), config, VSVar_System);
        }
        else
        {
            m_Parser->Add(VSTR("config"), VSTR("VoodooShader.xml"), VSVar_System);
        }

        // Load variables, built-in first
        {
            wchar_t buffer[MAX_PATH];	ZeroMemory(buffer, MAX_PATH);

            // Global path
            GetVoodooPath(buffer);
            m_Parser->Add(VSTR("path"), buffer, VSVar_System);

            // Bin prefix
            GetVoodooBinPrefix(buffer);
            m_Parser->Add(VSTR("prefix"), buffer, VSVar_System);

            // Framework bin path
            GetVoodooBinPath(buffer);
            m_Parser->Add(VSTR("binpath"), buffer, VSVar_System);

            // Target
            HMODULE pTarget = GetModuleHandle(NULL);
            GetModuleFileName(pTarget, buffer, MAX_PATH);
            m_Parser->Add(VSTR("target"), buffer, VSVar_System);

            // Local path
            PathRemoveFileSpec(buffer);
            PathAddBackslash(buffer);
            m_Parser->Add(VSTR("local"), buffer, VSVar_System);

            // Startup path
            GetCurrentDirectory(MAX_PATH, buffer);
            PathAddBackslash(buffer);
            m_Parser->Add(VSTR("startup"), buffer, VSVar_System);

            GetModuleFileName(gCoreHandle, buffer, MAX_PATH);
            m_Parser->Add(VSTR("core"), buffer, VSVar_System);
        }

        // Command line processing
        LPWSTR cmdline = GetCommandLine();
        m_Parser->Add(VSTR("args"), cmdline, VSVar_System);

        int cmdargc = 0;
        LPWSTR * cmdargv = CommandLineToArgvW(cmdline, &cmdargc);
        m_Parser->Add(VSTR("argc"), StringFormat(VSTR("%d")) << cmdargc, VSVar_System);
        for (int i = 0; i < cmdargc; ++i)
        {
            m_Parser->Add(StringFormat(VSTR("argv_%d")) << i, cmdargv[i], VSVar_System);
        }

        // Load the config
        try
        {
            m_ConfigFile = new pugi::xml_document();

            // Try loading the config file from each major location
            String configPath = m_Parser->Parse(VSTR("$(config)"), VSParse_PathCanon);
            pugi::xml_parse_result result = m_ConfigFile->load_file(configPath.GetData());

            if (!result)
            {
                configPath = m_Parser->Parse(VSTR("$(startup)\\$(config)"), VSParse_PathCanon);
                result = m_ConfigFile->load_file(configPath.GetData());
                if (!result)
                {
                    configPath = m_Parser->Parse(VSTR("$(local)\\$(config)"), VSParse_PathCanon);
                    result = m_ConfigFile->load_file(configPath.GetData());
                    if (!result)
                    {
                        configPath = m_Parser->Parse(VSTR("$(path)\\$(config)"), VSParse_PathCanon);
                        result = m_ConfigFile->load_file(configPath.GetData());
                        if (!result)
                        {
                            Throw(VOODOO_CORE_NAME, VSTR("Unable to find or parse config file."), nullptr);
                        }
                    }
                }
            }

            // Start setting things up
            pugi::xml_node configRoot = static_cast<pugi::xml_node>(*m_ConfigFile);
            pugi::xml_node globalNode = configRoot.select_single_node(L"/VoodooConfig/Global").node();
            if (!globalNode)
            {
                Throw(VOODOO_CORE_NAME, VSTR("Could not find global config node."), nullptr);
            }

            // Create query for node text, used multiple times
            pugi::xpath_query xpq_getName(L"./@name");
            pugi::xpath_query xpq_getText(L"./text()");

            // Load variables
            {
                pugi::xpath_query xpq_getVariables(L"./Variables/Variable");
                pugi::xpath_node_set nodes = xpq_getVariables.evaluate_node_set(globalNode);
                pugi::xpath_node_set::const_iterator iter = nodes.begin();

                while (iter != nodes.end())
                {
                    String name = xpq_getName.evaluate_string(*iter).c_str();
                    String value = xpq_getText.evaluate_string(*iter).c_str();

                    m_Parser->Add(name, value);

                    ++iter;
                }
            }

            // Open the logger as early as possible
            pugi::xpath_query logfQuery(L"./Log/File/text()");
            pugi::xpath_query logaQuery(L"./Log/Append/text()");
            pugi::xpath_query loglQuery(L"./Log/Level/text()");

            String logFile  = m_Parser->Parse(logfQuery.evaluate_string(globalNode));
            String logLevelStr = m_Parser->Parse(loglQuery.evaluate_string(globalNode));
            String logAppendStr = m_Parser->Parse(logaQuery.evaluate_string(globalNode));

            LogLevel logLevel = VSLog_Default;
            try
            {
                logLevel = (LogLevel)stoi(logLevelStr.ToString());
            }
            catch (const std::exception & exc)
            {
                UNREFERENCED_PARAMETER(exc);
                logLevel = VSLog_Default;
            }

            bool logAppend = logAppendStr.Compare(VSTR("true"), false) || logAppendStr.StartsWith("1");

            m_Logger->Open(logFile, logAppend);
            m_Logger->SetFilter(logLevel);

            // Log extended build information
            String configMsg = m_Parser->Parse(VSTR("Config loaded from '$(config)'."));
            m_Logger->LogMessage(VSLog_CoreNotice, VOODOO_CORE_NAME, configMsg);
            m_Logger->LogMessage(VSLog_CoreNotice, VOODOO_CORE_NAME, VOODOO_GLOBAL_COPYRIGHT_FULL);


            // Load plugins, starting with the core
            m_Server->LoadPlugin(this, VSTR("$(core)"));

            {
                pugi::xpath_query xpq_getPluginPaths(L"./Plugins/Path");
                pugi::xpath_query xpq_getFilter(L"./@filter");
                pugi::xpath_node_set nodes = xpq_getPluginPaths.evaluate_node_set(globalNode);
                pugi::xpath_node_set::const_iterator iter = nodes.begin();

                while (iter != nodes.end())
                {
                    String filter = xpq_getFilter.evaluate_string(*iter);
                    String path = xpq_getText.evaluate_string(*iter);

                    m_Server->LoadPath(this, path, filter);

                    ++iter;
                }
            }

            {
                pugi::xpath_query xpq_getPluginFiles(L"./Plugins/File");
                pugi::xpath_node_set nodes = xpq_getPluginFiles.evaluate_node_set(globalNode);
                pugi::xpath_node_set::const_iterator iter = nodes.begin();

                while (iter != nodes.end())
                {
                    String file = xpq_getText.evaluate_string(*iter);

                    m_Server->LoadPlugin(this, file);

                    ++iter;
                }
            }

            // Lookup classes
            pugi::xpath_query fsQuery(L"./Classes/FileSystem/text()");
            pugi::xpath_query hookQuery(L"./Classes/HookManager/text()");
            String fsClass = m_Parser->Parse(fsQuery.evaluate_string(globalNode).c_str());
            String hookClass = m_Parser->Parse(hookQuery.evaluate_string(globalNode).c_str());

            // Load less vital classes
            ObjectRef coreplugin = m_Server->CreateObject(this, hookClass);
            IHookManager * phm = nullptr;
            if (coreplugin && SUCCEEDED(coreplugin->QueryInterface(IID_IHookManager, (IObject**)&phm)) && phm)
            {
                m_HookManager = phm;
                phm->Release();
            }
            else
            {
                StringFormat fmt(VSTR("Unable to create hook manager (class %1%).")); fmt << hookClass;
                Throw(VOODOO_CORE_NAME, fmt, this);
            }

            coreplugin = m_Server->CreateObject(this, fsClass);
            IFileSystem * pfs = nullptr;
            if (coreplugin && SUCCEEDED(coreplugin->QueryInterface(IID_IFileSystem, (IObject**)&pfs)) && pfs)
            {
                m_FileSystem = pfs;
                pfs->Release();
            }
            else
            {
                StringFormat fmt(VSTR("Unable to create file system (class %1%).")); fmt << fsClass;
                Throw(VOODOO_CORE_NAME, fmt, this);
            }

            // ICore done loading
            m_Logger->LogMessage(VSLog_CoreInfo, VOODOO_CORE_NAME, VSTR("Core initialization complete."));

            // Call finalization events
            this->CallEvent(EventIds::Finalize, 0, nullptr);

            // Return
            return VSF_OK;
        }
        catch (const Exception & exc)
        {
            if (m_Logger)
            {
                m_Logger->LogMessage(VSLog_CoreError, VOODOO_CORE_NAME, 
                    StringFormat(VSTR("Exception during Core creation: %1%")) << exc.strwhat());
            } else {
                GlobalLog(VSTR("Unlogged exception during core creation: %S\n"), exc.what());
            }

            return VSF_FAIL;
        }
        catch (const std::exception & exc)
        {
            if (m_Logger)
            {
                m_Logger->LogMessage(VSLog_CoreError, VOODOO_CORE_NAME, 
                    StringFormat(VSTR("Error during Core creation: %1%")) << exc.what());
			} else {
				GlobalLog(VSTR("Unlogged exception during core creation: %S\n"), exc.what());
			}

            return VSF_FAIL;
        }
    }