示例#1
0
// Note
EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
{
	GLLoader::in_replayer = true;

	GSRendererType m_renderer;
	// Allow to easyly switch between SW/HW renderer -> this effectively removes the ability to select the renderer by function args
	m_renderer = static_cast<GSRendererType>(theApp.GetConfigI("Renderer"));
	// alternatively:
	// m_renderer = static_cast<GSRendererType>(renderer);

	if (m_renderer != GSRendererType::OGL_HW && m_renderer != GSRendererType::OGL_SW)
	{
		fprintf(stderr, "wrong renderer selected %d\n", static_cast<int>(m_renderer));
		return;
	}

	struct Packet {uint8 type, param; uint32 size, addr; vector<uint8> buff;};

	list<Packet*> packets;
	vector<uint8> buff;
	vector<float> stats;
	stats.clear();
	uint8 regs[0x2000];

	GSinit();

	GSsetBaseMem(regs);

	s_vsync = theApp.GetConfigB("vsync");

	void* hWnd = NULL;

	int err = _GSopen((void**)&hWnd, "", m_renderer);
	if (err != 0) {
		fprintf(stderr, "Error failed to GSopen\n");
		return;
	}
	if (s_gs->m_wnd == NULL) return;

	{ // Read .gs content
		std::string f(lpszCmdLine);
#ifdef LZMA_SUPPORTED
		GSDumpFile* file = (f.size() >= 4) && (f.compare(f.size()-3, 3, ".xz") == 0)
			? (GSDumpFile*) new GSDumpLzma(lpszCmdLine)
			: (GSDumpFile*) new GSDumpRaw(lpszCmdLine);
#else
		GSDumpFile* file = new GSDumpRaw(lpszCmdLine);
#endif

		uint32 crc;
		file->Read(&crc, 4);
		GSsetGameCRC(crc, 0);

		GSFreezeData fd;
		file->Read(&fd.size, 4);
		fd.data = new uint8[fd.size];
		file->Read(fd.data, fd.size);

		GSfreeze(FREEZE_LOAD, &fd);
		delete [] fd.data;

		file->Read(regs, 0x2000);

		GSvsync(1);


		while(!file->IsEof())
		{
			uint8 type;
			file->Read(&type, 1);

			Packet* p = new Packet();

			p->type = type;

			switch(type)
			{
			case 0:
				file->Read(&p->param, 1);
				file->Read(&p->size, 4);

				switch(p->param)
				{
				case 0:
					p->buff.resize(0x4000);
					p->addr = 0x4000 - p->size;
					file->Read(&p->buff[p->addr], p->size);
					break;
				case 1:
				case 2:
				case 3:
					p->buff.resize(p->size);
					file->Read(&p->buff[0], p->size);
					break;
				}

				break;

			case 1:
				file->Read(&p->param, 1);

				break;

			case 2:
				file->Read(&p->size, 4);

				break;

			case 3:
				p->buff.resize(0x2000);

				file->Read(&p->buff[0], 0x2000);

				break;
			}

			packets.push_back(p);
		}

		delete file;
	}

	sleep(1);

	//while(IsWindowVisible(hWnd))
	//FIXME map?
	int finished = theApp.GetConfigI("linux_replay");
	if (theApp.GetConfigI("dump")) {
		fprintf(stderr, "Dump is enabled. Replay will be disabled\n");
		finished = 1;
	}
	unsigned long frame_number = 0;
	unsigned long total_frame_nb = 0;
	while(finished > 0)
	{
		frame_number = 0;
		unsigned long start = timeGetTime();
		for(auto i = packets.begin(); i != packets.end(); i++)
		{
			Packet* p = *i;

			switch(p->type)
			{
				case 0:

					switch(p->param)
					{
						case 0: GSgifTransfer1(&p->buff[0], p->addr); break;
						case 1: GSgifTransfer2(&p->buff[0], p->size / 16); break;
						case 2: GSgifTransfer3(&p->buff[0], p->size / 16); break;
						case 3: GSgifTransfer(&p->buff[0], p->size / 16); break;
					}

					break;

				case 1:

					GSvsync(p->param);
					frame_number++;

					break;

				case 2:

					if(buff.size() < p->size) buff.resize(p->size);

					GSreadFIFO2(&buff[0], p->size / 16);

					break;

				case 3:

					memcpy(regs, &p->buff[0], 0x2000);

					break;
			}
		}

		// Ensure the rendering is complete to measure correctly the time.
		glFinish();

		if (finished > 90) {
			sleep(1);
		} else {
			unsigned long end = timeGetTime();
			frame_number = std::max(1ul, frame_number); // avoid a potential division by 0

			fprintf(stderr, "The %ld frames of the scene was render on %ldms\n", frame_number, end - start);
			fprintf(stderr, "A means of %fms by frame\n", (float)(end - start)/(float)frame_number);

			stats.push_back((float)(end - start));

			finished--;
			total_frame_nb += frame_number;
		}
	}

	if (theApp.GetConfigI("linux_replay") > 1) {
		// Print some nice stats
		// Skip first frame (shader compilation populate the result)
		// it divides by 10 the standard deviation...
		float n = (float)theApp.GetConfigI("linux_replay") - 1.0f;
		float mean = 0;
		float sd = 0;
		for (auto i = stats.begin()+1; i != stats.end(); i++) {
			mean += *i;
		}
		mean = mean/n;
		for (auto i = stats.begin()+1; i != stats.end(); i++) {
			sd += pow((*i)-mean, 2);
		}
		sd = sqrt(sd/n);

		fprintf(stderr, "\n\nMean: %fms\n", mean);
		fprintf(stderr, "Standard deviation: %fms\n", sd);
		fprintf(stderr, "Mean by frame: %fms (%ffps)\n", mean/(float)frame_number, 1000.0f*frame_number/mean);
		fprintf(stderr, "Standard deviatin by frame: %fms\n", sd/(float)frame_number);
	}
#ifdef ENABLE_OGL_DEBUG_MEM_BW
	total_frame_nb *= 1024;
	fprintf(stderr, "memory bandwith. T: %f KB/f. V: %f KB/f. U: %f KB/f\n",
			(float)g_real_texture_upload_byte/(float)total_frame_nb,
			(float)g_vertex_upload_byte/(float)total_frame_nb,
			(float)g_uniform_upload_byte/(float)total_frame_nb
		   );
#endif

	for(auto i = packets.begin(); i != packets.end(); i++)
	{
		delete *i;
	}

	packets.clear();

	sleep(1);

	GSclose();
	GSshutdown();
}
示例#2
0
static int _GSopen(void** dsp, const char* title, GSRendererType renderer, int threads = -1)
{
	GSDevice* dev = NULL;

	if(renderer == GSRendererType::Undefined)
	{
		renderer = static_cast<GSRendererType>(theApp.GetConfigI("Renderer"));
	}

	if(threads == -1)
	{
		threads = theApp.GetConfigI("extrathreads");
	}

	GSWnd* wnd[2] = { NULL, NULL };

	try
	{
		if (s_renderer != renderer)
		{
			// Emulator has made a render change request, which requires a completely
			// new s_gs -- if the emu doesn't save/restore the GS state across this
			// GSopen call then they'll get corrupted graphics, but that's not my problem.

			delete s_gs;

			s_gs = NULL;
		}

		const char* renderer_fullname = "";
		const char* renderer_mode = "";

		switch (renderer)
		{		
		case GSRendererType::DX9_SW:
		case GSRendererType::DX1011_SW:
		case GSRendererType::OGL_SW:
			renderer_mode = "(Software mode)";
			break;
		case GSRendererType::Null:
			renderer_mode = "(Null mode)";
			break;
		case GSRendererType::DX9_OpenCL:
		case GSRendererType::DX1011_OpenCL:
		case GSRendererType::OGL_OpenCL:
			renderer_mode = "(OpenCL)";
			break;
		default:
			renderer_mode = "(Hardware mode)";
			break;
		}

		switch (renderer)
		{
		default:
#ifdef _WIN32
		case GSRendererType::DX9_HW:
		case GSRendererType::DX9_SW:
		case GSRendererType::DX9_OpenCL:
			dev = new GSDevice9();
			s_renderer_name = " D3D9";
			renderer_fullname = "Direct3D9";
			break;
		case GSRendererType::DX1011_HW:
		case GSRendererType::DX1011_SW:
		case GSRendererType::DX1011_OpenCL:
			dev = new GSDevice11();
			s_renderer_name = " D3D11";
			renderer_fullname = "Direct3D11";
			break;
#endif
		case GSRendererType::Null:
			dev = new GSDeviceNull();
			s_renderer_name = " Null";
			renderer_fullname = "Null";
			break;
		case GSRendererType::OGL_HW:
		case GSRendererType::OGL_SW:
		case GSRendererType::OGL_OpenCL:
			dev = new GSDeviceOGL();
			s_renderer_name = " OGL";
			renderer_fullname = "OpenGL";
			break;
		}

		printf("Current Renderer: %s %s\n", renderer_fullname, renderer_mode);

		if (dev == NULL)
		{
			return -1;
		}

		if (s_gs == NULL)
		{
			switch (renderer)
			{
			default:
#ifdef _WIN32
			case GSRendererType::DX9_HW:
				s_gs = (GSRenderer*)new GSRendererDX9();
				s_renderer_type = " HW";
				break;
			case GSRendererType::DX1011_HW:
				s_gs = (GSRenderer*)new GSRendererDX11();
				s_renderer_type = " HW";
				break;
#endif
			case GSRendererType::OGL_HW:
				s_gs = (GSRenderer*)new GSRendererOGL();
				s_renderer_type = " HW";
				break;
			case GSRendererType::DX9_SW:
			case GSRendererType::DX1011_SW:
			case GSRendererType::OGL_SW:
				s_gs = new GSRendererSW(threads);
				s_renderer_type = " SW";
				break;
			case GSRendererType::Null:
				s_gs = new GSRendererNull();
				s_renderer_type = " Null";
				break;
			case GSRendererType::DX9_OpenCL:
			case GSRendererType::DX1011_OpenCL:
			case GSRendererType::OGL_OpenCL:
#ifdef ENABLE_OPENCL
				s_gs = new GSRendererCL();
				s_renderer_type = " OCL";
#else
				printf("GSdx error: OpenCL is disabled\n");
#endif
				break;
			}
			if (s_gs == NULL)
				return -1;

			s_renderer = renderer;
		}

		if (s_gs->m_wnd == NULL)
		{
#ifdef _WIN32
			switch (renderer)
			{
			case GSRendererType::OGL_HW:
			case GSRendererType::OGL_SW:
			case GSRendererType::OGL_OpenCL:
				s_gs->m_wnd = new GSWndWGL();
				break;
			default:
				s_gs->m_wnd = new GSWndDX();
				break;
			}
#else
#ifdef EGL_SUPPORTED
			wnd[0] = new GSWndEGL();
			wnd[1] = new GSWndOGL();
#else
			wnd[0] = new GSWndOGL();
#endif
#endif
		}
	}
	catch (std::exception& ex)
	{
		// Allowing std exceptions to escape the scope of the plugin callstack could
		// be problematic, because of differing typeids between DLL and EXE compilations.
		// ('new' could throw std::alloc)

		printf("GSdx error: Exception caught in GSopen: %s", ex.what());

		return -1;
	}

	s_gs->SetRegsMem(s_basemem);
	s_gs->SetIrqCallback(s_irq);
	s_gs->SetVSync(s_vsync);
	s_gs->SetFrameLimit(s_framelimit);

	if(*dsp == NULL)
	{
		// old-style API expects us to create and manage our own window:

		int w = theApp.GetConfigI("ModeWidth");
		int h = theApp.GetConfigI("ModeHeight");

#if defined(__unix__)
		for(uint32 i = 0; i < 2; i++) {
			try
			{
				if (wnd[i] == NULL) continue;

				wnd[i]->Create(title, w, h);
				s_gs->m_wnd = wnd[i];

				if (i == 0) delete wnd[1];

				break;
			}
			catch (GSDXRecoverableError)
			{
				wnd[i]->Detach();
				delete wnd[i];
			}
		}
		if (s_gs->m_wnd == NULL)
		{
			GSclose();

			return -1;
		}
#endif
#ifdef _WIN32
		if(!s_gs->CreateWnd(title, w, h))
		{
			GSclose();

			return -1;
		}
#endif

		s_gs->m_wnd->Show();

		*dsp = s_gs->m_wnd->GetDisplay();
	}
	else
	{
		s_gs->SetMultithreaded(true);

#if defined(__unix__)
		if (s_gs->m_wnd) {
			// A window was already attached to s_gs so we also
			// need to restore the window state (Attach)
			s_gs->m_wnd->Attach((void*)((uptr*)(dsp)+1), false);
		} else {
			// No window found, try to attach a GLX win and retry 
			// with EGL win if failed.
			for(uint32 i = 0; i < 2; i++) {
				try
				{
					if (wnd[i] == NULL) continue;

					wnd[i]->Attach((void*)((uptr*)(dsp)+1), false);
					s_gs->m_wnd = wnd[i];

					if (i == 0) delete wnd[1];

					break;
				}
				catch (GSDXRecoverableError)
				{
					wnd[i]->Detach();
					delete wnd[i];
				}
			}
		}
#endif
#ifdef _WIN32
		try
		{
			s_gs->m_wnd->Attach(*dsp, false);
		}
		catch (GSDXRecoverableError)
		{
			s_gs->m_wnd->Detach();
			delete s_gs->m_wnd;
			s_gs->m_wnd = NULL;
		}
#endif
		if (s_gs->m_wnd == NULL)
		{
			return -1;
		}
	}

	if(!s_gs->CreateDevice(dev))
	{
		// This probably means the user has DX11 configured with a video card that is only DX9
		// compliant.  Cound mean drivr issues of some sort also, but to be sure, that's the most
		// common cause of device creation errors. :)  --air

		GSclose();

		return -1;
	}

	if (renderer == GSRendererType::OGL_HW && theApp.GetConfigI("debug_glsl_shader") == 2) {
		printf("GSdx: test OpenGL shader. Please wait...\n\n");
		static_cast<GSDeviceOGL*>(s_gs->m_dev)->SelfShaderTest();
		printf("\nGSdx: test OpenGL shader done. It will now exit\n");
		return -1;
	}
	
	return 0;
}
示例#3
0
EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
	GSRendererType renderer = GSRendererType::Undefined;

	{
		char* start = lpszCmdLine;
		char* end = NULL;
		long n = strtol(lpszCmdLine, &end, 10);
		if(end > start) {renderer = static_cast<GSRendererType>(n); lpszCmdLine = end;}
	}

	while(*lpszCmdLine == ' ') lpszCmdLine++;

	::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS);

	if(FILE* fp = fopen(lpszCmdLine, "rb"))
	{
		Console console("GSdx", true);

		GSinit();

		uint8 regs[0x2000];
		GSsetBaseMem(regs);

		s_vsync = theApp.GetConfigB("vsync");

		HWND hWnd = NULL;

		_GSopen((void**)&hWnd, "", renderer);

		uint32 crc;
		fread(&crc, 4, 1, fp);
		GSsetGameCRC(crc, 0);

		GSFreezeData fd;
		fread(&fd.size, 4, 1, fp);
		fd.data = new uint8[fd.size];
		fread(fd.data, fd.size, 1, fp);
		GSfreeze(FREEZE_LOAD, &fd);
		delete [] fd.data;

		fread(regs, 0x2000, 1, fp);

		long start = ftell(fp);

		GSvsync(1);

		struct Packet {uint8 type, param; uint32 size, addr; vector<uint8> buff;};

		list<Packet*> packets;
		vector<uint8> buff;
		int type;

		while((type = fgetc(fp)) != EOF)
		{
			Packet* p = new Packet();

			p->type = (uint8)type;

			switch(type)
			{
			case 0:
				
				p->param = (uint8)fgetc(fp);

				fread(&p->size, 4, 1, fp);

				switch(p->param)
				{
				case 0:
					p->buff.resize(0x4000);
					p->addr = 0x4000 - p->size;
					fread(&p->buff[p->addr], p->size, 1, fp);
					break;
				case 1:
				case 2:
				case 3:
					p->buff.resize(p->size);
					fread(&p->buff[0], p->size, 1, fp);
					break;
				}

				break;

			case 1:

				p->param = (uint8)fgetc(fp);

				break;

			case 2:

				fread(&p->size, 4, 1, fp);

				break;

			case 3:

				p->buff.resize(0x2000);

				fread(&p->buff[0], 0x2000, 1, fp);

				break;
			}

			packets.push_back(p);
		}

		Sleep(100);

		while(IsWindowVisible(hWnd))
		{
			for(list<Packet*>::iterator i = packets.begin(); i != packets.end(); i++)
			{
				Packet* p = *i;

				switch(p->type)
				{
				case 0:

					switch(p->param)
					{
					case 0: GSgifTransfer1(&p->buff[0], p->addr); break;
					case 1: GSgifTransfer2(&p->buff[0], p->size / 16); break;
					case 2: GSgifTransfer3(&p->buff[0], p->size / 16); break;
					case 3: GSgifTransfer(&p->buff[0], p->size / 16); break;
					}

					break;

				case 1:

					GSvsync(p->param);

					break;

				case 2:

					if(buff.size() < p->size) buff.resize(p->size);

					GSreadFIFO2(&buff[0], p->size / 16);

					break;

				case 3:

					memcpy(regs, &p->buff[0], 0x2000);

					break;
				}
			}
		}

		for(list<Packet*>::iterator i = packets.begin(); i != packets.end(); i++)
		{
			delete *i;
		}

		packets.clear();

		Sleep(100);


		/*
		vector<uint8> buff;
		bool exit = false;

		int round = 0;

		while(!exit)
		{
			uint32 index;
			uint32 size;
			uint32 addr;

			int pos;

			switch(fgetc(fp))
			{
			case EOF:
				fseek(fp, start, 0);
				exit = !IsWindowVisible(hWnd);
				//exit = ++round == 60;
				break;

			case 0:
				index = fgetc(fp);
				fread(&size, 4, 1, fp);

				switch(index)
				{
				case 0:
					if(buff.size() < 0x4000) buff.resize(0x4000);
					addr = 0x4000 - size;
					fread(&buff[addr], size, 1, fp);
					GSgifTransfer1(&buff[0], addr);
					break;

				case 1:
					if(buff.size() < size) buff.resize(size);
					fread(&buff[0], size, 1, fp);
					GSgifTransfer2(&buff[0], size / 16);
					break;

				case 2:
					if(buff.size() < size) buff.resize(size);
					fread(&buff[0], size, 1, fp);
					GSgifTransfer3(&buff[0], size / 16);
					break;

				case 3:
					if(buff.size() < size) buff.resize(size);
					fread(&buff[0], size, 1, fp);
					GSgifTransfer(&buff[0], size / 16);
					break;
				}

				break;

			case 1:
				GSvsync(fgetc(fp));
				exit = !IsWindowVisible(hWnd);
				break;

			case 2:
				fread(&size, 4, 1, fp);
				if(buff.size() < size) buff.resize(size);
				GSreadFIFO2(&buff[0], size / 16);
				break;

			case 3:
				fread(regs, 0x2000, 1, fp);
				break;
			}
		}
		*/

		GSclose();
		GSshutdown();

		fclose(fp);
	}
}
示例#4
0
static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
{
	// I really don't know the impact on windows! It could work
#ifdef __linux__
	if (theApp.GetConfig("enable_nvidia_multi_thread", 1)) {
		setenv("__GL_THREADED_OPTIMIZATIONS", "1", 0);
	}
#endif

	GSDevice* dev = NULL;

	if(renderer == -1)
	{
		renderer = theApp.GetConfig("renderer", 0);
	}

	if(threads == -1)
	{
		threads = theApp.GetConfig("extrathreads", 0);
	}

	GSWnd* wnd[2];

	try
	{
		if(s_renderer != renderer)
		{
			// Emulator has made a render change request, which requires a completely
			// new s_gs -- if the emu doesn't save/restore the GS state across this
			// GSopen call then they'll get corrupted graphics, but that's not my problem.

			delete s_gs;

			s_gs = NULL;
		}

		switch(renderer)
		{
		default:
#ifdef _WINDOWS
		case 0: case 1: case 2: case 14:
			dev = new GSDevice9(); 
			break;
		case 3: case 4: case 5: case 15:
			dev = new GSDevice11(); 
			break;
#endif
		case 9: case 10: case 11: case 16:
			dev = new GSDeviceNull(); 
			break;
		case 12: case 13: case 17:
			dev = new GSDeviceOGL(); 
			break;
		}

		if(dev == NULL)
		{
			return -1;
		}

		if(s_gs == NULL)
		{
			switch(renderer)
			{
			default:
#ifdef _WINDOWS
			case 0:
				s_gs = (GSRenderer*)new GSRendererDX9();
				break;
			case 3: 
				s_gs = (GSRenderer*)new GSRendererDX11(); 
				break;
#endif
			case 12: 
				s_gs = (GSRenderer*)new GSRendererOGL(); 
				break;
			case 1: case 4: case 10: case 13:
				s_gs = new GSRendererSW(threads);
				break;
			case 2: case 5: case 11:
				s_gs = new GSRendererNull();
				break;
			case 14: case 15: case 16: case 17:
#ifdef ENABLE_OPENCL
				s_gs = new GSRendererCL();
#else
				printf("GSdx error: opencl is disabled\n");
#endif
				break;
			}
			if (s_gs == NULL)
				return -1;

			s_renderer = renderer;
		}

		if (s_gs->m_wnd == NULL)
		{
#ifdef _WINDOWS
			switch(renderer)
			{
			case 12: case 13: case 17:
				s_gs->m_wnd = new GSWndWGL();
				break;
			default:
				s_gs->m_wnd = new GSWndDX();
				break;
			}
#else
			wnd[0] = new GSWndOGL();
#ifdef EGL_SUPPORTED
			wnd[1] = new GSWndEGL();
#else
			wnd[1] = NULL;
#endif
#endif
		}
	}
	catch(std::exception& ex)
	{
		// Allowing std exceptions to escape the scope of the plugin callstack could
		// be problematic, because of differing typeids between DLL and EXE compilations.
		// ('new' could throw std::alloc)

		printf("GSdx error: Exception caught in GSopen: %s", ex.what());

		return -1;
	}

	s_gs->SetRegsMem(s_basemem);
	s_gs->SetIrqCallback(s_irq);
	s_gs->SetVSync(s_vsync);
	s_gs->SetFrameLimit(s_framelimit);

	if(*dsp == NULL)
	{
		// old-style API expects us to create and manage our own window:

		int w = theApp.GetConfig("ModeWidth", 0);
		int h = theApp.GetConfig("ModeHeight", 0);

#ifdef __linux__
		for(uint32 i = 0; i < 2; i++) {
			try
			{
				if (wnd[i] == NULL) continue;

				wnd[i]->Create(title, w, h);
				s_gs->m_wnd = wnd[i];

				if (i == 0) delete wnd[1];

				break;
			}
			catch (GSDXRecoverableError)
			{
				wnd[i]->Detach();
				delete wnd[i];
			}
		}
		if (s_gs->m_wnd == NULL)
		{
			GSclose();

			return -1;
		}
#endif
#ifdef _WINDOWS
		if(!s_gs->CreateWnd(title, w, h))
		{
			GSclose();

			return -1;
		}
#endif

		s_gs->m_wnd->Show();

		*dsp = s_gs->m_wnd->GetDisplay();
	}
	else
	{
		s_gs->SetMultithreaded(true);

#ifdef __linux__
		if (s_gs->m_wnd) {
			// A window was already attached to s_gs so we also
			// need to restore the window state (Attach)
			s_gs->m_wnd->Attach((void*)((uptr*)(dsp)+1), false);
		} else {
			// No window found, try to attach a GLX win and retry 
			// with EGL win if failed.
			for(uint32 i = 0; i < 2; i++) {
				try
				{
					if (wnd[i] == NULL) continue;

					wnd[i]->Attach((void*)((uptr*)(dsp)+1), false);
					s_gs->m_wnd = wnd[i];

					if (i == 0) delete wnd[1];

					break;
				}
				catch (GSDXRecoverableError)
				{
					wnd[i]->Detach();
					delete wnd[i];
				}
			}
		}
#endif
#ifdef _WINDOWS
		try
		{
			s_gs->m_wnd->Attach(*dsp, false);
		}
		catch (GSDXRecoverableError)
		{
			s_gs->m_wnd->Detach();
			delete s_gs->m_wnd;
			s_gs->m_wnd = NULL;
		}
#endif
		if (s_gs->m_wnd == NULL)
		{
			return -1;
		}
	}

	if(!s_gs->CreateDevice(dev))
	{
		// This probably means the user has DX11 configured with a video card that is only DX9
		// compliant.  Cound mean drivr issues of some sort also, but to be sure, that's the most
		// common cause of device creation errors. :)  --air

		GSclose();

		return -1;
	}
	
	return 0;
}
示例#5
0
文件: GS.cpp 项目: Leo626/pcsx2
// Note
EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
{
	GLLoader::in_replayer = true;

	GSRendererType m_renderer;
	// Allow to easyly switch between SW/HW renderer -> this effectively removes the ability to select the renderer by function args
	m_renderer = static_cast<GSRendererType>(theApp.GetConfigI("Renderer"));
	// alternatively:
	// m_renderer = static_cast<GSRendererType>(renderer);

	if (m_renderer != GSRendererType::OGL_HW && m_renderer != GSRendererType::OGL_SW)
	{
		fprintf(stderr, "wrong renderer selected %d\n", static_cast<int>(m_renderer));
		return;
	}

	struct Packet {uint8 type, param; uint32 size, addr; vector<uint8> buff;};

	list<Packet*> packets;
	vector<uint8> buff;
	uint8 regs[0x2000];

	GSinit();

	GSsetBaseMem(regs);

	s_vsync = theApp.GetConfigB("vsync");

	void* hWnd = NULL;

	int err = _GSopen((void**)&hWnd, "", m_renderer);
	if (err != 0) {
		fprintf(stderr, "Error failed to GSopen\n");
		return;
	}
	if (s_gs->m_wnd == NULL) return;

	{ // Read .gs content
		std::string f(lpszCmdLine);
#ifdef LZMA_SUPPORTED
		GSDumpFile* file = (f.size() >= 4) && (f.compare(f.size()-3, 3, ".xz") == 0)
			? (GSDumpFile*) new GSDumpLzma(lpszCmdLine)
			: (GSDumpFile*) new GSDumpRaw(lpszCmdLine);
#else
		GSDumpFile* file = new GSDumpRaw(lpszCmdLine);
#endif

		uint32 crc;
		file->Read(&crc, 4);
		GSsetGameCRC(crc, 0);

		GSFreezeData fd;
		file->Read(&fd.size, 4);
		fd.data = new uint8[fd.size];
		file->Read(fd.data, fd.size);

		GSfreeze(FREEZE_LOAD, &fd);
		delete [] fd.data;

		file->Read(regs, 0x2000);

		GSvsync(1);


		while(!file->IsEof())
		{
			uint8 type;
			file->Read(&type, 1);

			Packet* p = new Packet();

			p->type = type;

			switch(type)
			{
			case 0:
				file->Read(&p->param, 1);
				file->Read(&p->size, 4);

				switch(p->param)
				{
				case 0:
					p->buff.resize(0x4000);
					p->addr = 0x4000 - p->size;
					file->Read(&p->buff[p->addr], p->size);
					break;
				case 1:
				case 2:
				case 3:
					p->buff.resize(p->size);
					file->Read(&p->buff[0], p->size);
					break;
				}

				break;

			case 1:
				file->Read(&p->param, 1);

				break;

			case 2:
				file->Read(&p->size, 4);

				break;

			case 3:
				p->buff.resize(0x2000);

				file->Read(&p->buff[0], 0x2000);

				break;
			}

			packets.push_back(p);
		}

		delete file;
	}

	sleep(1);

	//while(IsWindowVisible(hWnd))
	//FIXME map?
	int finished = theApp.GetConfigI("linux_replay");
	if (theApp.GetConfigI("dump")) {
		fprintf(stderr, "Dump is enabled. Replay will be disabled\n");
		finished = 1;
	}
	unsigned long frame_number = 0;
	while(finished > 0)
	{
		for(auto i = packets.begin(); i != packets.end(); i++)
		{
			Packet* p = *i;

			switch(p->type)
			{
				case 0:

					switch(p->param)
					{
						case 0: GSgifTransfer1(&p->buff[0], p->addr); break;
						case 1: GSgifTransfer2(&p->buff[0], p->size / 16); break;
						case 2: GSgifTransfer3(&p->buff[0], p->size / 16); break;
						case 3: GSgifTransfer(&p->buff[0], p->size / 16); break;
					}

					break;

				case 1:

					GSvsync(p->param);
					frame_number++;

					break;

				case 2:

					if(buff.size() < p->size) buff.resize(p->size);

					GSreadFIFO2(&buff[0], p->size / 16);

					break;

				case 3:

					memcpy(regs, &p->buff[0], 0x2000);

					break;
			}
		}

		if (finished >= 200) {
			; // Nop for Nvidia Profiler
		} else if (finished > 90) {
			sleep(1);
		} else {
			finished--;
		}
	}

#ifdef ENABLE_OGL_DEBUG_MEM_BW
	unsigned long total_frame_nb = std::max(1ul, frame_number) << 10;
	fprintf(stderr, "memory bandwith. T: %f KB/f. V: %f KB/f. U: %f KB/f\n",
			(float)g_real_texture_upload_byte/(float)total_frame_nb,
			(float)g_vertex_upload_byte/(float)total_frame_nb,
			(float)g_uniform_upload_byte/(float)total_frame_nb
		   );
#endif

	for(auto i = packets.begin(); i != packets.end(); i++)
	{
		delete *i;
	}

	packets.clear();

	sleep(1);

	GSclose();
	GSshutdown();
}
示例#6
0
文件: GS.cpp 项目: Blackbird88/pcsx2
// Note
EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
{
	GLLoader::in_replayer = true;

// lpszCmdLine:
//   First parameter is the renderer.
//   Second parameter is the gs file to load and run.

//EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
#if 0
	int renderer = -1;

	{
		char* start = lpszCmdLine;
		char* end = NULL;
		long n = strtol(lpszCmdLine, &end, 10);
		if(end > start) {renderer = n; lpszCmdLine = end;}
	}

	while(*lpszCmdLine == ' ') lpszCmdLine++;

	::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS);
#endif
	// Allow to easyly switch between SW/HW renderer
	renderer = theApp.GetConfig("renderer", 12);
	if (renderer != 12 && renderer != 13)
	{
		fprintf(stderr, "wrong renderer selected %d\n", renderer);
		return;
	}

	vector<float> stats;
	stats.clear();

	if(FILE* fp = fopen(lpszCmdLine, "rb"))
	{
		//Console console("GSdx", true);

		GSinit();

		uint8 regs[0x2000];
		GSsetBaseMem(regs);

		s_vsync = !!theApp.GetConfig("vsync", 0);

		void* hWnd = NULL;

		int err = _GSopen((void**)&hWnd, "", renderer);
		if (err != 0) {
			fprintf(stderr, "Error failed to GSopen\n");
			return;
		}
		if (s_gs->m_wnd == NULL) return;

		uint32 crc;
		fread(&crc, 4, 1, fp);
		GSsetGameCRC(crc, 0);

		GSFreezeData fd;
		fread(&fd.size, 4, 1, fp);
		fd.data = new uint8[fd.size];
		fread(fd.data, fd.size, 1, fp);
		GSfreeze(FREEZE_LOAD, &fd);
		delete [] fd.data;

		fread(regs, 0x2000, 1, fp);

		GSvsync(1);

		struct Packet {uint8 type, param; uint32 size, addr; vector<uint8> buff;};

		list<Packet*> packets;
		vector<uint8> buff;
		int type;

		while((type = fgetc(fp)) != EOF)
		{
			Packet* p = new Packet();

			p->type = (uint8)type;

			switch(type)
			{
			case 0:

				p->param = (uint8)fgetc(fp);

				fread(&p->size, 4, 1, fp);

				switch(p->param)
				{
				case 0:
					p->buff.resize(0x4000);
					p->addr = 0x4000 - p->size;
					fread(&p->buff[p->addr], p->size, 1, fp);
					break;
				case 1:
				case 2:
				case 3:
					p->buff.resize(p->size);
					fread(&p->buff[0], p->size, 1, fp);
					break;
				}

				break;

			case 1:

				p->param = (uint8)fgetc(fp);

				break;

			case 2:

				fread(&p->size, 4, 1, fp);

				break;

			case 3:

				p->buff.resize(0x2000);

				fread(&p->buff[0], 0x2000, 1, fp);

				break;
			}

			packets.push_back(p);
		}

		sleep(1);

		//while(IsWindowVisible(hWnd))
		//FIXME map?
		int finished = theApp.GetConfig("linux_replay", 1);
		unsigned long frame_number = 0;
		while(finished > 0)
		{
			frame_number = 0;
			unsigned long start = timeGetTime();
			for(auto i = packets.begin(); i != packets.end(); i++)
			{
				Packet* p = *i;

				switch(p->type)
				{
				case 0:

					switch(p->param)
					{
					case 0: GSgifTransfer1(&p->buff[0], p->addr); break;
					case 1: GSgifTransfer2(&p->buff[0], p->size / 16); break;
					case 2: GSgifTransfer3(&p->buff[0], p->size / 16); break;
					case 3: GSgifTransfer(&p->buff[0], p->size / 16); break;
					}

					break;

				case 1:

					GSvsync(p->param);
					frame_number++;

					break;

				case 2:

					if(buff.size() < p->size) buff.resize(p->size);

					GSreadFIFO2(&buff[0], p->size / 16);

					break;

				case 3:

					memcpy(regs, &p->buff[0], 0x2000);

					break;
				}
			}
			unsigned long end = timeGetTime();
			fprintf(stderr, "The %ld frames of the scene was render on %ldms\n", frame_number, end - start);
			fprintf(stderr, "A means of %fms by frame\n", (float)(end - start)/(float)frame_number);

			stats.push_back((float)(end - start));


			sleep(1);
			finished--;
		}

		if (theApp.GetConfig("linux_replay", 1) > 1) {
			// Print some nice stats
			// Skip first frame (shader compilation populate the result)
			// it divides by 10 the standard deviation...
			float n = (float)theApp.GetConfig("linux_replay", 1) - 1.0f;
			float mean = 0;
			float sd = 0;
			for (auto i = stats.begin()+1; i != stats.end(); i++) {
				mean += *i;
			}
			mean = mean/n;
			for (auto i = stats.begin()+1; i != stats.end(); i++) {
				sd += pow((*i)-mean, 2);
			}
			sd = sqrt(sd/n);

			fprintf(stderr, "\n\nMean: %fms\n", mean);
			fprintf(stderr, "Standard deviation: %fms\n", sd);
			fprintf(stderr, "Mean by frame: %fms (%ffps)\n", mean/(float)frame_number, 1000.0f*frame_number/mean);
			fprintf(stderr, "Standard deviatin by frame: %fms\n", sd/(float)frame_number);
		}
#ifdef ENABLE_OGL_DEBUG_MEM_BW
		fprintf(stderr, "memory bandwith. T: %f. V: %f\n", (float)g_texture_upload_byte/(float)frame_number/1024, (float)g_vertex_upload_byte/(float)frame_number/1024);
#endif

		for(auto i = packets.begin(); i != packets.end(); i++)
		{
			delete *i;
		}

		packets.clear();

		sleep(1);

		GSclose();
		GSshutdown();

		fclose(fp);
	} else {
		fprintf(stderr, "failed to open %s\n", lpszCmdLine);
	}
}
示例#7
0
文件: GS.cpp 项目: Alchemistxxd/pcsx2
static int _GSopen(void** dsp, const char* title, GSRendererType renderer, int threads = -1)
{
	GSDevice* dev = NULL;
	bool old_api = *dsp == NULL;

	// Fresh start up or config file changed
	if(renderer == GSRendererType::Undefined)
	{
		renderer = static_cast<GSRendererType>(theApp.GetConfigI("Renderer"));
#ifdef _WIN32
		if (renderer == GSRendererType::Default)
			renderer = GSUtil::GetBestRenderer();
#endif
	}

	if(threads == -1)
	{
		threads = theApp.GetConfigI("extrathreads");
	}

	try
	{
		if (theApp.GetCurrentRendererType() != renderer)
		{
			// Emulator has made a render change request, which requires a completely
			// new s_gs -- if the emu doesn't save/restore the GS state across this
			// GSopen call then they'll get corrupted graphics, but that's not my problem.

			delete s_gs;

			s_gs = NULL;

			theApp.SetCurrentRendererType(renderer);
		}

		std::shared_ptr<GSWnd> window;
		{
			// Select the window first to detect the GL requirement
			std::vector<std::shared_ptr<GSWnd>> wnds;
			switch (renderer)
			{
				case GSRendererType::OGL_HW:
				case GSRendererType::OGL_SW:
				case GSRendererType::OGL_OpenCL:
#if defined(EGL_SUPPORTED) && defined(__unix__)
					// Note: EGL code use GLX otherwise maybe it could be also compatible with Windows
					// Yes OpenGL code isn't complicated enough !
					switch (GSWndEGL::SelectPlatform()) {
#if GS_EGL_X11
						case EGL_PLATFORM_X11_KHR:
							wnds.push_back(std::make_shared<GSWndEGL_X11>());
							break;
#endif
#if GS_EGL_WL
						case EGL_PLATFORM_WAYLAND_KHR:
							wnds.push_back(std::make_shared<GSWndEGL_WL>());
							break;
#endif
						default:
							break;
					}
#endif
#if defined(__unix__)
					wnds.push_back(std::make_shared<GSWndOGL>());
#else
					wnds.push_back(std::make_shared<GSWndWGL>());
#endif
					break;
				default:
#ifdef _WIN32
					wnds.push_back(std::make_shared<GSWndDX>());
#endif
					break;
			}

			int w = theApp.GetConfigI("ModeWidth");
			int h = theApp.GetConfigI("ModeHeight");
#if defined(__unix__)
			void *win_handle = (void*)((uptr*)(dsp)+1);
#else
			void *win_handle = *dsp;
#endif

			for(auto& wnd : wnds)
			{
				try
				{
					if (old_api)
					{
						// old-style API expects us to create and manage our own window:
						wnd->Create(title, w, h);

						wnd->Show();

						*dsp = wnd->GetDisplay();
					}
					else
					{
						wnd->Attach(win_handle, false);
					}

					window = wnd; // Previous code will throw if window isn't supported

					break;
				}
				catch (GSDXRecoverableError)
				{
					wnd->Detach();
				}
			}

			if(!window)
			{
				GSclose();

				return -1;
			}
		}

		const char* renderer_fullname = "";
		const char* renderer_mode = "";

		switch (renderer)
		{
		case GSRendererType::DX9_SW:
		case GSRendererType::DX1011_SW:
		case GSRendererType::OGL_SW:
			renderer_mode = "(Software renderer)";
			break;
		case GSRendererType::Null:
			renderer_mode = "(Null renderer)";
			break;
		case GSRendererType::DX9_OpenCL:
		case GSRendererType::DX1011_OpenCL:
		case GSRendererType::OGL_OpenCL:
			renderer_mode = "(OpenCL)";
			break;
		default:
			renderer_mode = "(Hardware renderer)";
			break;
		}

		switch (renderer)
		{
		default:
#ifdef _WIN32
		case GSRendererType::DX9_HW:
		case GSRendererType::DX9_SW:
		case GSRendererType::DX9_OpenCL:
			dev = new GSDevice9();
			s_renderer_name = " D3D9";
			renderer_fullname = "Direct3D 9";
			break;
		case GSRendererType::DX1011_HW:
		case GSRendererType::DX1011_SW:
		case GSRendererType::DX1011_OpenCL:
			dev = new GSDevice11();
			s_renderer_name = " D3D11";
			renderer_fullname = "Direct3D 11";
			break;
#endif
		case GSRendererType::Null:
			dev = new GSDeviceNull();
			s_renderer_name = " Null";
			renderer_fullname = "Null";
			break;
		case GSRendererType::OGL_HW:
		case GSRendererType::OGL_SW:
		case GSRendererType::OGL_OpenCL:
			dev = new GSDeviceOGL();
			s_renderer_name = " OGL";
			renderer_fullname = "OpenGL";
			break;
		}

		printf("Current Renderer: %s %s\n", renderer_fullname, renderer_mode);

		if (dev == NULL)
		{
			return -1;
		}

		if (s_gs == NULL)
		{
			switch (renderer)
			{
			default:
#ifdef _WIN32
			case GSRendererType::DX9_HW:
				s_gs = (GSRenderer*)new GSRendererDX9();
				s_renderer_type = " HW";
				break;
			case GSRendererType::DX1011_HW:
				s_gs = (GSRenderer*)new GSRendererDX11();
				s_renderer_type = " HW";
				break;
#endif
			case GSRendererType::OGL_HW:
				s_gs = (GSRenderer*)new GSRendererOGL();
				s_renderer_type = " HW";
				break;
			case GSRendererType::DX9_SW:
			case GSRendererType::DX1011_SW:
			case GSRendererType::OGL_SW:
				s_gs = new GSRendererSW(threads);
				s_renderer_type = " SW";
				break;
			case GSRendererType::Null:
				s_gs = new GSRendererNull();
				s_renderer_type = "";
				break;
			case GSRendererType::DX9_OpenCL:
			case GSRendererType::DX1011_OpenCL:
			case GSRendererType::OGL_OpenCL:
#ifdef ENABLE_OPENCL
				s_gs = new GSRendererCL();
				s_renderer_type = " OCL";
#else
				printf("GSdx error: OpenCL is disabled\n");
#endif
				break;
			}
			if (s_gs == NULL)
				return -1;
		}

		s_gs->m_wnd = window;
	}
	catch (std::exception& ex)
	{
		// Allowing std exceptions to escape the scope of the plugin callstack could
		// be problematic, because of differing typeids between DLL and EXE compilations.
		// ('new' could throw std::alloc)

		printf("GSdx error: Exception caught in GSopen: %s", ex.what());

		return -1;
	}

	s_gs->SetRegsMem(s_basemem);
	s_gs->SetIrqCallback(s_irq);
	s_gs->SetVSync(s_vsync);
	s_gs->SetFrameLimit(s_framelimit);

	if(!old_api)
		s_gs->SetMultithreaded(true);

	if(!s_gs->CreateDevice(dev))
	{
		// This probably means the user has DX11 configured with a video card that is only DX9
		// compliant.  Cound mean drivr issues of some sort also, but to be sure, that's the most
		// common cause of device creation errors. :)  --air

		GSclose();

		return -1;
	}

	if (renderer == GSRendererType::OGL_HW && theApp.GetConfigI("debug_glsl_shader") == 2) {
		printf("GSdx: test OpenGL shader. Please wait...\n\n");
		static_cast<GSDeviceOGL*>(s_gs->m_dev)->SelfShaderTest();
		printf("\nGSdx: test OpenGL shader done. It will now exit\n");
		return -1;
	}
	
	return 0;
}