Add back the D3D9 code from before the April 2014 code dump.

Bug 22533227

Change-Id: Ib669fcd6a644c79b3a9e8f5dcf7da278d75cefef
Reviewed-on: https://swiftshader-review.googlesource.com/3730
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/D3D9/Direct3DQuery9.cpp b/src/D3D9/Direct3DQuery9.cpp
new file mode 100644
index 0000000..c0f4323
--- /dev/null
+++ b/src/D3D9/Direct3DQuery9.cpp
@@ -0,0 +1,243 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DQuery9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Timer.hpp"
+#include "Renderer.hpp"
+#include "Debug.hpp"
+
+#include <assert.h>
+
+namespace D3D9
+{
+	Direct3DQuery9::Direct3DQuery9(Direct3DDevice9 *device, D3DQUERYTYPE type) : device(device), type(type)
+	{
+		if(type == D3DQUERYTYPE_OCCLUSION)
+		{
+			query = new sw::Query();
+		}
+		else
+		{
+			query = 0;
+		}
+	}
+
+	Direct3DQuery9::~Direct3DQuery9()
+	{
+		if(query)
+		{
+			device->removeQuery(query);
+
+			delete query;
+		}
+	}
+
+	long Direct3DQuery9::QueryInterface(const IID &iid, void **object)
+	{
+		CriticalSection cs(device);
+
+		TRACE("");
+
+		if(iid == IID_IDirect3DQuery9 ||
+		   iid == IID_IUnknown)
+		{
+			AddRef();
+			*object = this;
+
+			return S_OK;
+		}
+
+		*object = 0;
+
+		return NOINTERFACE(iid);
+	}
+
+	unsigned long Direct3DQuery9::AddRef()
+	{
+		TRACE("");
+
+		return Unknown::AddRef();
+	}
+	
+	unsigned long Direct3DQuery9::Release()
+	{
+		TRACE("");
+
+		return Unknown::Release();
+	}
+
+	long __stdcall Direct3DQuery9::GetDevice(IDirect3DDevice9 **device)
+	{
+		CriticalSection cs(this->device);
+
+		TRACE("");
+
+		if(!device)
+		{
+			return INVALIDCALL();
+		}
+
+		this->device->AddRef();
+		*device = this->device;
+
+		return D3D_OK;
+	}
+
+	D3DQUERYTYPE Direct3DQuery9::GetType()
+	{
+		CriticalSection cs(device);
+
+		return type;
+	}
+
+	unsigned long Direct3DQuery9::GetDataSize()
+	{
+		CriticalSection cs(device);
+
+		TRACE("");
+
+		switch(type)
+		{
+		case D3DQUERYTYPE_VCACHE:				return sizeof(D3DDEVINFO_VCACHE);
+		case D3DQUERYTYPE_RESOURCEMANAGER:		return sizeof(D3DDEVINFO_RESOURCEMANAGER);
+		case D3DQUERYTYPE_VERTEXSTATS:			return sizeof(D3DDEVINFO_D3DVERTEXSTATS);
+		case D3DQUERYTYPE_EVENT:				return sizeof(BOOL);
+		case D3DQUERYTYPE_OCCLUSION:			return sizeof(DWORD);
+		case D3DQUERYTYPE_TIMESTAMP:			return sizeof(UINT64);
+		case D3DQUERYTYPE_TIMESTAMPDISJOINT:	return sizeof(BOOL);
+		case D3DQUERYTYPE_TIMESTAMPFREQ:		return sizeof(UINT64);
+		case D3DQUERYTYPE_PIPELINETIMINGS:		return sizeof(D3DDEVINFO_D3D9PIPELINETIMINGS);
+		case D3DQUERYTYPE_INTERFACETIMINGS:		return sizeof(D3DDEVINFO_D3D9INTERFACETIMINGS);
+		case D3DQUERYTYPE_VERTEXTIMINGS:		return sizeof(D3DDEVINFO_D3D9STAGETIMINGS);
+		case D3DQUERYTYPE_PIXELTIMINGS:			return sizeof(D3DDEVINFO_D3D9PIPELINETIMINGS);
+		case D3DQUERYTYPE_BANDWIDTHTIMINGS:		return sizeof(D3DDEVINFO_D3D9BANDWIDTHTIMINGS);
+		case D3DQUERYTYPE_CACHEUTILIZATION:		return sizeof(D3DDEVINFO_D3D9CACHEUTILIZATION);
+		default:
+			ASSERT(false);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DQuery9::Issue(unsigned long flags)
+	{
+		CriticalSection cs(device);
+
+		TRACE("");
+
+		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END)
+		{
+			return INVALIDCALL();
+		}
+
+		switch(type)
+		{
+		case D3DQUERYTYPE_VCACHE:				if(flags != D3DISSUE_END) return INVALIDCALL(); break;
+		case D3DQUERYTYPE_RESOURCEMANAGER:		if(flags != D3DISSUE_END) return INVALIDCALL(); break;
+		case D3DQUERYTYPE_VERTEXSTATS:			if(flags != D3DISSUE_END) return INVALIDCALL(); break;
+		case D3DQUERYTYPE_EVENT:
+			if(flags == D3DISSUE_END)
+			{
+			//	device->renderer->synchronize();   // FIXME
+			}
+			else return INVALIDCALL();
+			break;
+		case D3DQUERYTYPE_OCCLUSION:
+			if(flags == D3DISSUE_BEGIN)
+			{
+				query->begin();
+				device->addQuery(query);
+				device->setOcclusionEnabled(true);
+			}
+			else   // flags == D3DISSUE_END
+			{
+				query->end();
+				device->removeQuery(query);
+				device->setOcclusionEnabled(false);
+			}
+			break;
+		case D3DQUERYTYPE_TIMESTAMP:			if(flags != D3DISSUE_END) return INVALIDCALL(); break;
+		case D3DQUERYTYPE_TIMESTAMPDISJOINT:	if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+		case D3DQUERYTYPE_TIMESTAMPFREQ:		if(flags != D3DISSUE_END) return INVALIDCALL(); break;
+		case D3DQUERYTYPE_PIPELINETIMINGS:		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+		case D3DQUERYTYPE_INTERFACETIMINGS:		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+		case D3DQUERYTYPE_VERTEXTIMINGS:		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+		case D3DQUERYTYPE_PIXELTIMINGS:			if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+		case D3DQUERYTYPE_BANDWIDTHTIMINGS:		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+		case D3DQUERYTYPE_CACHEUTILIZATION:		if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+		default:
+			ASSERT(false);
+		}
+
+		return D3D_OK;
+	}
+
+	long Direct3DQuery9::GetData(void *data, unsigned long size, unsigned long flags)
+	{
+		CriticalSection cs(device);
+
+		TRACE("void *data = %p, unsigned long size = %d, unsigned long flags = %d", data, size, flags);
+
+		if(query && query->building)
+		{
+			return INVALIDCALL();
+		}
+
+		bool signaled = !query || query->reference == 0; 
+
+		if(size && signaled)
+		{
+			if(!data)
+			{
+				return INVALIDCALL();
+			}
+
+			// FIXME: Check size
+
+			switch(type)
+			{
+			case D3DQUERYTYPE_VCACHE:
+				{
+					D3DDEVINFO_VCACHE vcache;
+
+					vcache.Pattern = 'CACH';
+					vcache.OptMethod = 1;   // Vertex-cache based optimization
+					vcache.CacheSize = 16;
+					vcache.MagicNumber = 8;
+
+					*(D3DDEVINFO_VCACHE*)data = vcache;
+				}
+				break;
+			case D3DQUERYTYPE_RESOURCEMANAGER:		UNIMPLEMENTED(); break;
+			case D3DQUERYTYPE_VERTEXSTATS:			UNIMPLEMENTED(); break;
+			case D3DQUERYTYPE_EVENT:				*(BOOL*)data = TRUE; break;                       // FIXME
+			case D3DQUERYTYPE_OCCLUSION:
+				*(DWORD*)data = query->data;
+				break;
+			case D3DQUERYTYPE_TIMESTAMP:			*(UINT64*)data = sw::Timer::counter(); break;     // FIXME: Verify behaviour
+			case D3DQUERYTYPE_TIMESTAMPDISJOINT:	*(BOOL*)data = FALSE; break;                      // FIXME: Verify behaviour
+			case D3DQUERYTYPE_TIMESTAMPFREQ:		*(UINT64*)data = sw::Timer::frequency(); break;   // FIXME: Verify behaviour
+			case D3DQUERYTYPE_PIPELINETIMINGS:		UNIMPLEMENTED(); break;
+			case D3DQUERYTYPE_INTERFACETIMINGS:		UNIMPLEMENTED(); break;
+			case D3DQUERYTYPE_VERTEXTIMINGS:		UNIMPLEMENTED(); break;
+			case D3DQUERYTYPE_PIXELTIMINGS:			UNIMPLEMENTED(); break;
+			case D3DQUERYTYPE_BANDWIDTHTIMINGS:		UNIMPLEMENTED(); break;
+			case D3DQUERYTYPE_CACHEUTILIZATION:		UNIMPLEMENTED(); break;
+			default:
+				ASSERT(false);
+			}
+		}
+
+		return signaled ? S_OK : S_FALSE;
+	}
+}