diff options
| author | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 | 
|---|---|---|
| committer | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 | 
| commit | 15740faf9fe9fe4be08965098bbf2947e096aeeb (patch) | |
| tree | a730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/GfxDevice/GfxDevice.h | |
Diffstat (limited to 'Runtime/GfxDevice/GfxDevice.h')
| -rw-r--r-- | Runtime/GfxDevice/GfxDevice.h | 813 | 
1 files changed, 813 insertions, 0 deletions
| diff --git a/Runtime/GfxDevice/GfxDevice.h b/Runtime/GfxDevice/GfxDevice.h new file mode 100644 index 0000000..07d3906 --- /dev/null +++ b/Runtime/GfxDevice/GfxDevice.h @@ -0,0 +1,813 @@ +#pragma once + +#include "Configuration/UnityConfigure.h" +#include "GfxDeviceConfigure.h" +#include "GfxDeviceTypes.h" +#include "GfxDeviceObjects.h" +#include "GfxDeviceStats.h" +#include "Runtime/Math/Matrix4x4.h" +#include "Runtime/Math/Color.h" +#include "Runtime/Shaders/GraphicsCaps.h" +#include "Runtime/Shaders/MaterialProperties.h" +#include "Runtime/Threads/Thread.h" +#include "BuiltinShaderParams.h" +#include "Runtime/Modules/ExportModules.h" + +#if UNITY_EDITOR && UNITY_WIN +#include "GfxDeviceWindow.h" +#endif + +#if ENABLE_TEXTUREID_MAP +	#include "TextureIdMap.h" +#endif + + +// On some platforms we choose renderer at runtime; on others there's always a single +// renderer. On those that have only one, GFX_DEVICE_VIRTUAL is defined to zero, and +// the actual implementation is named GfxDevice, and uses no virtual functions. + +#if UNITY_PS3 +//#	define CELL_GCM_DEBUG +#	include <cell/gcm.h> +#endif + +#if UNITY_WIN || UNITY_OSX || UNITY_LINUX || UNITY_PS3 || UNITY_IPHONE || UNITY_ANDROID || UNITY_PEPPER || UNITY_XENON || UNITY_BB10 || UNITY_WEBGL || UNITY_TIZEN +#define GFX_DEVICE_VIRTUAL 1 +#else +#define GFX_DEVICE_VIRTUAL 0 +#endif + +#if (UNITY_OSX && WEBPLUG) || UNITY_LINUX && !UNITY_PEPPER +#define GFX_USES_VIEWPORT_OFFSET 1 +#else +#define GFX_USES_VIEWPORT_OFFSET 0 +#endif + + + +#if GFX_DEVICE_VIRTUAL + +#define GFX_API virtual +#define GFX_PURE = 0 +#define GFX_GL_IMPL GfxDeviceGL + +#else + +#define GFX_API +#define GFX_PURE +#define GFX_GL_IMPL GfxDevice +struct GfxDeviceImpl; + +#endif + +#define GFX_DEVICE_VERIFY_ENABLE (!UNITY_RELEASE) + +class VBO; +class RawVBO; +class VBOList; +class DynamicVBO; +class RenderTexture; +class ImageReference; +class Matrix4x4f; +class GpuProgram; +class GpuProgramParameters; +class GfxTimerQuery; +class GfxDisplayList; +class MaterialPropertyBlock; +class ShaderErrors; +class ChannelAssigns; +class CreateGpuProgramOutput; +struct SkinMeshInfo; +struct MemExportInfo; +struct VertexBufferData; +struct IndexBufferData; +struct PropertyNamesSet; +#if ENABLE_SPRITES +struct SpriteRenderData; +#endif +struct BoneInfluence; +namespace ShaderLab { +	class IntShader; +	struct ParserShader; +	struct TextureBinding; +	class PropertySheet; +	class SubProgram; +} +namespace xenon { +	class IVideoPlayer; +} + +class GPUSkinningInfo; + +class GfxDevice { +public: + +	enum PresentMode +	{ +		kPresentBeforeUpdate, +		kPresentAfterDraw +	}; + +	enum SurfaceFlags +	{ +		kSurfaceDefault = 0, + +		// Bits 0 and 1 are used to control render target restores. There flags are mutually exclusive. +		kSurfaceNeverRestore  = (1<<0), // Xbox 360: SetRenderTarget will never restore contents to EDRAM. +		kSurfaceAlwaysRestore = (1<<1), // Xbox 360: SetRenderTarget will always restore contents to EDRAM. +		kSurfaceRestoreMask   = kSurfaceNeverRestore | kSurfaceAlwaysRestore, +		// Xbox 360: SetRenderTarget by default will only restore contents to EDRAM if render target was previously used that frame. + +		// next flag (1<<2) +	}; + +	enum ReloadResourcesFlags { +		kReleaseRenderTextures = (1<<0), +		kReloadShaders = (1<<1), +		kReloadTextures = (1<<2), +	}; + +	enum RenderTargetFlags { +		kFlagDontRestoreColor = (1<<0),	// Xbox 360 specific: do not restore old contents to EDRAM +		kFlagDontRestoreDepth = (1<<1),	// Xbox 360 specific: do not restore old contents to EDRAM +		kFlagDontRestore      = kFlagDontRestoreColor | kFlagDontRestoreDepth, +		kFlagForceResolve     = (1<<3), // Xbox 360 specific: force a resolve to system RAM +	}; + +	enum ImmediateShapeType { +		kShapeCube = 0,			// Quads +		kShapeDodecahedron		// Triangles +	}; + +	enum GfxProfileControl { +		kGfxProfBeginFrame = 0, +		kGfxProfEndFrame, +		kGfxProfDisableSampling, +		kGfxProfSetActive, +	}; + +	GfxDevice(); +	GFX_API ~GfxDevice(); + +	GFX_API void	InvalidateState() GFX_PURE; +	#if GFX_DEVICE_VERIFY_ENABLE +	GFX_API void	VerifyState() GFX_PURE; +	#endif + +	GfxDeviceRenderer GetRenderer() const { return m_Renderer; } +	// OpenGL: texture V coordinate is 0 at the bottom; 1 at the top +	// otherwise: texture V coordinate is 0 at the top; 1 at the bottom +	bool UsesOpenGLTextureCoords() const { return m_UsesOpenGLTextureCoords; } +	// Should half-texel offset be applied for pixel-correct rendering (true on D3D9)? +	bool UsesHalfTexelOffset() const { return m_UsesHalfTexelOffset; } + +	GFX_API void SetMaxBufferedFrames (int bufferSize) { m_MaxBufferedFrames = bufferSize; } +	int GetMaxBufferedFrames () const { return m_MaxBufferedFrames; } + +	const GfxDeviceStats& GetFrameStats() const { return m_Stats; } +	GfxDeviceStats& GetFrameStats() { return m_Stats; } + +	RenderTexture* GetActiveRenderTexture() const +	{ +#if !UNITY_EDITOR // TODO: this needs fixing in the editor +		ASSERT_RUNNING_ON_MAIN_THREAD; +#endif +		return m_ActiveRenderTexture; +	} +	void SetActiveRenderTexture(RenderTexture* rt) +	{ +#if !UNITY_EDITOR // TODO: this needs fixing in the editor +		ASSERT_RUNNING_ON_MAIN_THREAD; +#endif +		m_ActiveRenderTexture = rt; +	} + +	const BuiltinShaderParamValues& GetBuiltinParamValues() const { return m_BuiltinParamValues; } +	BuiltinShaderParamValues& GetBuiltinParamValues() { return m_BuiltinParamValues; } +	const GfxFogParams& GetFogParams() const { return m_FogParams; } + +	static inline ColorRGBA32 ConvertToDeviceVertexColor(const ColorRGBA32& color) +	{ +		#if GFX_OPENGLESxx_ONLY || UNITY_PS3 || UNITY_WII +			// Optimization: we know that we never have to swizzle vertex color here +			DebugAssert(gGraphicsCaps.needsToSwizzleVertexColors == false); +			return color; +		#elif UNITY_XENON +			// Optimization: we know that we always have to swizzle vertex color on Xbox360 platform +			DebugAssert(gGraphicsCaps.needsToSwizzleVertexColors == true); +			return color.SwizzleToARGB(); +		#else +			return gGraphicsCaps.needsToSwizzleVertexColors ? color.SwizzleToBGRA() : color; +		#endif +	}; + +	int			GetTotalVBOCount() const; +	int			GetTotalVBOBytes() const; + +	void		RecreateAllVBOs(); + +	#if GFX_SUPPORTS_D3D9 +		void		ResetDynamicVBs(); +	#endif +	#if GFX_SUPPORTS_OPENGLES20 +		void		MarkAllVBOsLost(); +	#endif + + +	GFX_API void	Clear (UInt32 clearFlags, const float color[4], float depth, int stencil) GFX_PURE; +	GFX_API void	SetInvertProjectionMatrix( bool enable ) GFX_PURE; +	GFX_API bool	GetInvertProjectionMatrix() const GFX_PURE; +	#if GFX_USES_VIEWPORT_OFFSET +	GFX_API void	SetViewportOffset( float x, float y ) GFX_PURE; +	GFX_API void	GetViewportOffset( float &x, float &y ) const GFX_PURE; +	#endif + +	GFX_API DeviceBlendState* CreateBlendState(const GfxBlendState& state) GFX_PURE; +	GFX_API DeviceDepthState* CreateDepthState(const GfxDepthState& state) GFX_PURE; +	GFX_API DeviceStencilState* CreateStencilState(const GfxStencilState& state) GFX_PURE; +	GFX_API DeviceRasterState* CreateRasterState(const GfxRasterState& state) GFX_PURE; + +	GFX_API void RecordSetBlendState(const DeviceBlendState* state, const ShaderLab::FloatVal& alphaRef, const ShaderLab::PropertySheet* props ); +	GFX_API void SetBlendState(const DeviceBlendState* state, float alphaRef) GFX_PURE; +	GFX_API void SetRasterState(const DeviceRasterState* state) GFX_PURE; +	GFX_API void SetDepthState(const DeviceDepthState* state) GFX_PURE; +	GFX_API void SetStencilState(const DeviceStencilState* state, int stencilRef) GFX_PURE; +	GFX_API void SetSRGBWrite (const bool) GFX_PURE; +	GFX_API bool GetSRGBWrite () GFX_PURE; + +	GFX_API void SetUserBackfaceMode(bool enable) GFX_PURE; +	GFX_API void SetWireframe(bool wire) GFX_PURE; +	GFX_API bool GetWireframe() const GFX_PURE; + +	GFX_API void	SetWorldMatrixAndType( const float matrix[16], TransformType type ); +	GFX_API void	SetWorldMatrix( const float matrix[16] ) GFX_PURE; +	GFX_API void	SetViewMatrix( const float matrix[16] ) GFX_PURE; +	GFX_API void	SetProjectionMatrix (const Matrix4x4f& matrix) GFX_PURE; + +	GFX_API void	GetMatrix( float outMatrix[16] ) const GFX_PURE; + + +	GFX_API	const float* GetWorldMatrix() const GFX_PURE; +	GFX_API	const float* GetViewMatrix() const GFX_PURE; +	GFX_API	const float* GetProjectionMatrix() const GFX_PURE; // get projection matrix as passed from Unity (OpenGL projection conventions) +	GFX_API const float* GetDeviceProjectionMatrix() const GFX_PURE; // get projection matrix that will be actually used + +	GFX_API void	SetInverseScale (float invScale); + +	GFX_API void	SetNormalizationBackface( NormalizationMode mode, bool backface ) GFX_PURE; + +	GFX_API void	SetFFLighting( bool on, bool separateSpecular, ColorMaterialMode colorMaterial ) GFX_PURE; +	GFX_API void	RecordSetMaterial( const ShaderLab::VectorVal& ambient, const ShaderLab::VectorVal& diffuse, const ShaderLab::VectorVal& specular, const ShaderLab::VectorVal& emissive, const ShaderLab::FloatVal& shininess, const ShaderLab::PropertySheet* props ); +	GFX_API void	SetMaterial( const float ambient[4], const float diffuse[4], const float specular[4], const float emissive[4], const float shininess ) GFX_PURE; +	GFX_API void	RecordSetColor( const ShaderLab::VectorVal& color, const ShaderLab::PropertySheet* props ); +	GFX_API void	SetColor( const float color[4] ) GFX_PURE; +	GFX_API void	SetViewport( int x, int y, int width, int height ) GFX_PURE; +	GFX_API void	GetViewport( int* values ) const GFX_PURE; + +	GFX_API void	SetScissorRect( int x, int y, int width, int height ) GFX_PURE; +	GFX_API void	DisableScissor() GFX_PURE; +	GFX_API bool	IsScissorEnabled() const GFX_PURE; +	GFX_API void	GetScissorRect( int values[4] ) const GFX_PURE; + +	GFX_API TextureCombinersHandle CreateTextureCombiners( int count, const ShaderLab::TextureBinding* texEnvs, const ShaderLab::PropertySheet* props, bool hasVertexColorOrLighting, bool usesAddSpecular ) GFX_PURE; +	GFX_API void	DeleteTextureCombiners( TextureCombinersHandle& textureCombiners ) GFX_PURE; +	GFX_API void	SetTextureCombiners( TextureCombinersHandle textureCombiners, const ShaderLab::PropertySheet* props ) GFX_PURE; + +	GFX_API void	SetTexture (ShaderType shaderType, int unit, int samplerUnit, TextureID texture, TextureDimension dim, float bias) GFX_PURE; +	GFX_API void	SetTextureParams( TextureID texture, TextureDimension texDim, TextureFilterMode filter, TextureWrapMode wrap, int anisoLevel, bool hasMipMap, TextureColorSpace colorSpace ) GFX_PURE; +	GFX_API void	SetTextureTransform( int unit, TextureDimension dim, TexGenMode texGen, bool identity, const float matrix[16]) GFX_PURE; +	GFX_API void	SetTextureName( TextureID texture, char const* name ) GFX_PURE; + +	GFX_API void	SetMaterialProperties(const MaterialPropertyBlock& block); + +	GFX_API GpuProgram* CreateGpuProgram( const std::string& source, CreateGpuProgramOutput& output ); +	GFX_API void	SetShadersMainThread( ShaderLab::SubProgram* programs[kShaderTypeCount], const ShaderLab::PropertySheet* props ) GFX_PURE; + +	GFX_API bool	IsShaderActive( ShaderType type ) const GFX_PURE; +	GFX_API void	DestroySubProgram( ShaderLab::SubProgram* subprogram ) GFX_PURE; +	GFX_API void	SetConstantBufferInfo (int /*id*/, int /*size*/) { } + +	GFX_API void	DisableLights( int startLight ) GFX_PURE; +	GFX_API void	SetLight( int light, const GfxVertexLight& data) GFX_PURE; +	GFX_API void	SetAmbient( const float ambient[4] ) GFX_PURE; + +	GFX_API void	RecordEnableFog( FogMode fogMode, const ShaderLab::FloatVal& fogStart, const ShaderLab::FloatVal& fogEnd, const ShaderLab::FloatVal& fogDensity, const ShaderLab::VectorVal& fogColor, const ShaderLab::PropertySheet* props ); +	GFX_API void	EnableFog( const GfxFogParams& fog ) GFX_PURE; +	GFX_API void	DisableFog() GFX_PURE; + +	GFX_API VBO*	CreateVBO() GFX_PURE; +	GFX_API void	DeleteVBO( VBO* vbo ) GFX_PURE; +	GFX_API DynamicVBO&	GetDynamicVBO() GFX_PURE; + +	GFX_API void	BeginSkinning( int maxSkinCount ); +	GFX_API bool	SkinMesh( const SkinMeshInfo& skin, VBO* vbo ); +	GFX_API void	EndSkinning(); + +#if GFX_ENABLE_DRAW_CALL_BATCHING +	static	int		GetMaxStaticBatchIndices(); +	GFX_API	void	BeginStaticBatching(const ChannelAssigns& channels, GfxPrimitiveType topology); +	GFX_API	void	StaticBatchMesh( UInt32 firstVertex, UInt32 vertexCount, const IndexBufferData& indices, UInt32 firstIndexByte, UInt32 indexCount ); +	GFX_API	void	EndStaticBatching( VBO& vbo, const Matrix4x4f& matrix, TransformType transformType, int sourceChannels ); + +	GFX_API	void	BeginDynamicBatching( const ChannelAssigns& shaderChannels, UInt32 availableChannels, size_t maxVertices, size_t maxIndices, GfxPrimitiveType topology); +	GFX_API	void	DynamicBatchMesh( const Matrix4x4f& matrix, const VertexBufferData& vertices, UInt32 firstVertex, UInt32 vertexCount, const IndexBufferData& indices, UInt32 firstIndexByte, UInt32 indexCount ); +	GFX_API	void	EndDynamicBatching( TransformType transformType ); +#if ENABLE_SPRITES +	GFX_API	void    DynamicBatchSprite(const Matrix4x4f* matrix, const SpriteRenderData* rd, ColorRGBA32 color); +#endif +#endif + +	GFX_API	void	AddBatchingStats( int batchedTris, int batchedVerts, int batchedCalls ); + +	/** +	* CreateGPUSkinningInfo - Create a GPU-assisted skinning object. +	* +	* GPU-assisted skinning is limited to platforms that support GPU +	* writing the skinned output mesh into a VBO (StreamOut, MemExport, Transform Feedback). +	* +	* The returned object should be used against a single Skinned Mesh instance, and deleted once no longer needed. +	* +	* @return GFX_API GPUSkinningInfo* New GPU skinning object, or NULL if GPU skinning is not supported on this GfxDevice. +	*/ +	GFX_API GPUSkinningInfo* CreateGPUSkinningInfo() GFX_PURE; + +	/** +	* DeleteGPUSkinningInfo - Release a GPUSkinningInfo object. +	* +	* @param info GPUSkinningInfo object to delete +	*/ +	GFX_API void DeleteGPUSkinningInfo(GPUSkinningInfo *info) GFX_PURE; + +	/** +	* SkinOnGPU - Perform GPU-assisted skinning into the destination VBO. +	* +	* @param info GPUSkinningInfo object filled with valid data and set up using UpdateSkinData and UpdateSkinBones +	* @param lastThisFrame True if this is the last GPU-skinned mesh in this frame, false otherwise. +	*/ +	GFX_API void	SkinOnGPU( GPUSkinningInfo* info, bool lastThisFrame ) GFX_PURE; + +	/** +	* UpdateSkinSourceData - Pass the Vertex and skin data to the GPU. +	* +	* Assumes channel map, vertex count and stride has been previously set. +	* If dirty is true, the vertex or skin data has changed since the last call, and the implementation should refresh the content. +	* Otherwise, the implementation should just check that it has set up its internal buffers correctly and return. +	* +	* @param info GPUSkinningInfo object, expected to be properly set up with calls to setVertexCount, setChannelMap and setStride +	* @param vertData Vertex data, array size defined by previous calls to setVertexCount(), setChannelMap() and setStride +	* @param skinData Bone influence data, array size defined by setVertexCount +	* @param dirty Dirty flag, see above +	*/ +	GFX_API void UpdateSkinSourceData(GPUSkinningInfo *info, const void *vertData, const BoneInfluence *skinData, bool dirty) GFX_PURE; + +	/** +	* UpdateSkinBonePoses - Update bone pose matrices for a GPU-assisted skin. +	* +	* Note that the array is not guaranteed to stay alive after the call, so unless +	* the data can be uploaded immediately, a local copy is required. +	* +	* @param boneCount Number of bones +	* @param poses Array of bone matrices +	*/ +	GFX_API void UpdateSkinBonePoses(GPUSkinningInfo *info, const int boneCount, const Matrix4x4f* poses) GFX_PURE; + + +#if UNITY_XENON +	GFX_API RawVBO*	CreateRawVBO( UInt32 size, UInt32 flags ) GFX_PURE; +	GFX_API void	DeleteRawVBO( RawVBO* vbo ) GFX_PURE; +	GFX_API void    EnablePersistDisplayOnQuit( bool enabled ) GFX_PURE; + +	GFX_API void    RegisterTexture2D( TextureID tid, IDirect3DBaseTexture9* texture ) GFX_PURE; +	GFX_API void    PatchTexture2D( TextureID tid, IDirect3DBaseTexture9* texture ) GFX_PURE; +	GFX_API void    DeleteTextureEntryOnly( TextureID textureID ) GFX_PURE; +	GFX_API void    UnbindAndDelayReleaseTexture( IDirect3DBaseTexture9* texture ) GFX_PURE; +	GFX_API void    SetTextureWrapModes( TextureID textureID, TextureWrapMode wrapU, TextureWrapMode wrapV, TextureWrapMode wrapW ) GFX_PURE; + +	GFX_API void    OnLastFrameCallback() GFX_PURE; + +	GFX_API xenon::IVideoPlayer* CreateVideoPlayer( bool fullscreen ) GFX_PURE; +	GFX_API void                 DeleteVideoPlayer( xenon::IVideoPlayer* player ) GFX_PURE; +	GFX_API void SetNullPixelShader() GFX_PURE; +	GFX_API void SetHiZEnable( const HiZstate hiz_enable ) GFX_PURE; +	GFX_API void SetHiStencilState( const bool hiStencilEnable, const bool hiStencilWriteEnable, const int hiStencilRef, const CompareFunction cmpFunc ) GFX_PURE; +	GFX_API void HiStencilFlush( const HiSflush flushtype ) GFX_PURE; +#endif + +	GFX_API RenderSurfaceHandle CreateRenderColorSurface (TextureID textureID, int width, int height, int samples, int depth, TextureDimension dim, RenderTextureFormat format, UInt32 createFlags) GFX_PURE; +	GFX_API RenderSurfaceHandle CreateRenderDepthSurface (TextureID textureID, int width, int height, int samples, TextureDimension dim, DepthBufferFormat depthFormat, UInt32 createFlags) GFX_PURE; +	GFX_API void DestroyRenderSurface (RenderSurfaceHandle& rs) GFX_PURE; +	GFX_API void SetRenderTargets (int count, RenderSurfaceHandle* colorHandles, RenderSurfaceHandle depthHandle, int mipLevel = 0, CubemapFace face = kCubeFaceUnknown) GFX_PURE; +	GFX_API void SetRenderTargets (int count, RenderSurfaceHandle* colorHandles, RenderSurfaceHandle depthHandle, int mipLevel, CubemapFace face, UInt32 flags) +#if !UNITY_XENON +	{ SetRenderTargets(count, colorHandles, depthHandle, mipLevel, face); } +#else +	GFX_PURE +#endif +	; + +	GFX_API void ResolveColorSurface (RenderSurfaceHandle srcHandle, RenderSurfaceHandle dstHandle) GFX_PURE; + +	GFX_API void DiscardContents (RenderSurfaceHandle& rs) GFX_PURE; +	// Do not produce a warning for next unresolve of current RT; it is expected and there's nothing we can do about it +	GFX_API void IgnoreNextUnresolveOnCurrentRenderTarget() { } +	GFX_API void IgnoreNextUnresolveOnRS(RenderSurfaceHandle rs) { } + +	GFX_API void ResolveDepthIntoTexture (RenderSurfaceHandle /*colorHandle*/, RenderSurfaceHandle /*depthHandle*/) { } + +	GFX_API RenderSurfaceHandle GetActiveRenderColorSurface (int index) GFX_PURE; +	GFX_API RenderSurfaceHandle GetActiveRenderDepthSurface () GFX_PURE; + +	// TODO: we might need to extend it in the future, e.g. for multi-display +	GFX_API RenderSurfaceHandle GetBackBufferColorSurface () 	{ return m_BackBufferColor; } +	GFX_API RenderSurfaceHandle GetBackBufferDepthSurface () 	{ return m_BackBufferDepth; } + +	GFX_API void SetBackBufferColorSurface(RenderSurfaceBase* color)	{ m_BackBufferColor=RenderSurfaceHandle(color); } +	GFX_API void SetBackBufferDepthSurface(RenderSurfaceBase* depth)	{ m_BackBufferDepth=RenderSurfaceHandle(depth); } + +	GFX_API bool IsRenderTargetConfigValid(UInt32 width, UInt32 height, RenderTextureFormat /*colorFormat*/, DepthBufferFormat /*depthFormat*/) +#if !UNITY_XENON +	{ return width <= gGraphicsCaps.maxRenderTextureSize && height <= gGraphicsCaps.maxRenderTextureSize; } +#else +	GFX_PURE +#endif +	; + +	GFX_API void SetSurfaceFlags(RenderSurfaceHandle surf, UInt32 flags, UInt32 keepFlags = 0) GFX_PURE; + +	GFX_API TextureID	CreateTextureID(); +	GFX_API void		FreeTextureID( TextureID texture ); + +#if ENABLE_TEXTUREID_MAP +	GFX_API intptr_t	CreateExternalTextureFromNative(intptr_t nativeTex) 				{ return nativeTex; } +	GFX_API void		UpdateExternalTextureFromNative(TextureID tex, intptr_t nativeTex)	{ TextureIdMap::UpdateTexture(tex, nativeTex); } +#endif + +	enum kUploadTextureFlags +	{ +		kUploadTextureDefault = 0, +		kUploadTextureDontUseSubImage = 1<<0, // texture might not be created yet, or is being resized +		kUploadTextureOSDrawingCompatible = 1<<1, // create an OS-drawing compatible one (e.g. for GDI on Windows) +		// NOTE: Richard S added these on another Xbox360 branch, uncomment/merge when that branch comes back +		//kUploadTextureTiled = 1<<2, +		//kUploadTextureMemoryReady = 1<<3, +	}; + +	GFX_API void UploadTexture2D( TextureID texture, TextureDimension dimension, UInt8* srcData, int srcSize, int width, int height, TextureFormat format, int mipCount, UInt32 uploadFlags, int skipMipLevels, TextureUsageMode usageMode,  TextureColorSpace colorSpace ) GFX_PURE; +	GFX_API void UploadTextureSubData2D( TextureID texture, UInt8* srcData, int srcSize, int mipLevel, int x, int y, int width, int height, TextureFormat format, TextureColorSpace colorSpace ) GFX_PURE; +	GFX_API void UploadTextureCube( TextureID texture, UInt8* srcData, int srcSize, int faceDataSize, int size, TextureFormat format, int mipCount, UInt32 uploadFlags, TextureColorSpace colorSpace ) GFX_PURE; +	GFX_API void UploadTexture3D( TextureID texture, UInt8* srcData, int srcSize, int width, int height, int depth, TextureFormat format, int mipCount, UInt32 uploadFlags ) GFX_PURE; +	GFX_API void DeleteTexture( TextureID texture ) GFX_PURE; + +	GFX_API PresentMode	GetPresentMode() GFX_PURE; + +	GFX_API void	BeginFrame() GFX_PURE; +	GFX_API void	EndFrame() GFX_PURE; +	inline bool		IsInsideFrame() const { return m_InsideFrame; } +	inline void		SetInsideFrame(bool v) { m_InsideFrame = v; } +	GFX_API void	PresentFrame() GFX_PURE; +	// Check if device is in valid state. E.g. lost device on D3D9; in this case all rendering +	// should be skipped. +	GFX_API bool	IsValidState() GFX_PURE; +	GFX_API bool	HandleInvalidState() { return true; } +	GFX_API void	ResetDynamicResources() {} +	GFX_API bool	IsReadyToBeginFrame() { return true; } + +	// Fully finish any queued-up rendering (including on the GPU) +	GFX_API void	FinishRendering() GFX_PURE; +	// Insert CPU fence into command queue (if threaded) +	GFX_API UInt32	InsertCPUFence() { return 0; } +	// Get next CPU fence that will be inserted +	GFX_API UInt32	GetNextCPUFence() { return 0; } +	// Finish any threaded commands before CPU fence +	GFX_API void	WaitOnCPUFence(UInt32 /*fence*/) {} + +	// Are we recording graphics commands? +	inline bool		IsRecording() const { return m_IsRecording; } + +	// Does this device derive from GfxThreadableDevice? +	inline bool		IsThreadable() const { return m_IsThreadable; } + +	// Acquire thread ownership on the calling thread. Worker releases ownership. +	GFX_API void	AcquireThreadOwnership() {} +	// Release thread ownership on the calling thread. Worker acquires ownership. +	GFX_API void	ReleaseThreadOwnership() {} + +	// Immediate mode rendering +	GFX_API void	ImmediateShape( float x, float y, float z, float scale, ImmediateShapeType shape ); +	GFX_API void	ImmediateVertex( float x, float y, float z ) GFX_PURE; +	GFX_API void	ImmediateNormal( float x, float y, float z ) GFX_PURE; +	GFX_API void	ImmediateColor( float r, float g, float b, float a ) GFX_PURE; +	GFX_API void	ImmediateTexCoordAll( float x, float y, float z ) GFX_PURE; +	GFX_API void	ImmediateTexCoord( int unit, float x, float y, float z ) GFX_PURE; +	GFX_API void	ImmediateBegin( GfxPrimitiveType type ) GFX_PURE; +	GFX_API	void	ImmediateEnd() GFX_PURE; + +	// Recording display lists +#if GFX_SUPPORTS_DISPLAY_LISTS +	GFX_API bool	BeginRecording() { return false; } +	GFX_API bool	EndRecording( GfxDisplayList** outDisplayList ) { return false; } +#endif + +	// Capturing screen shots / blits +	GFX_API bool	CaptureScreenshot( int left, int bottom, int width, int height, UInt8* rgba32 ) GFX_PURE; +	GFX_API bool	ReadbackImage( ImageReference& image, int left, int bottom, int width, int height, int destX, int destY ) GFX_PURE; +	GFX_API void	GrabIntoRenderTexture (RenderSurfaceHandle rs, RenderSurfaceHandle rd, int x, int y, int width, int height) GFX_PURE; + +	// Any housekeeping around draw calls +	GFX_API void	BeforeDrawCall( bool immediateMode ) GFX_PURE; +	GFX_API void	AfterDrawCall() {}; + +	GFX_API bool	IsPositionRequiredForTexGen (int texStageIndex) const GFX_PURE; +	GFX_API bool	IsNormalRequiredForTexGen (int texStageIndex) const GFX_PURE; +	GFX_API bool	IsPositionRequiredForTexGen() const GFX_PURE; +	GFX_API bool	IsNormalRequiredForTexGen() const GFX_PURE; + +	GFX_API void	SetActiveContext (void* /*ctx*/) {}; + +	GFX_API void	ResetFrameStats(); +	GFX_API void	BeginFrameStats(); +	GFX_API void	EndFrameStats(); +	GFX_API void	SaveDrawStats(); +	GFX_API void	RestoreDrawStats(); +	GFX_API void	SynchronizeStats(); + +	#if ENABLE_PROFILER +	GFX_API void	BeginProfileEvent (const char* /*name*/) {} +	GFX_API void	EndProfileEvent () {} +	GFX_API void	ProfileControl (GfxProfileControl /*ctrl*/, unsigned /*param*/) {} + +	GFX_API GfxTimerQuery*		CreateTimerQuery() GFX_PURE; +	GFX_API void				DeleteTimerQuery(GfxTimerQuery* query) GFX_PURE; +	GFX_API void				BeginTimerQueries() GFX_PURE; +	GFX_API void				EndTimerQueries() GFX_PURE; +	GFX_API bool				TimerQueriesIsActive() { return false; } +	#endif + +	// Editor-only stuff +	#if UNITY_EDITOR +	GFX_API void	SetColorBytes (const UInt8 color[4]); +	GFX_API void				SetAntiAliasFlag( bool aa ) GFX_PURE; +	GFX_API void				DrawUserPrimitives( GfxPrimitiveType type, int vertexCount, UInt32 vertexChannels, const void* data, int stride ) GFX_PURE; +	GFX_API int					GetCurrentTargetAA() const GFX_PURE; + +	#if UNITY_WIN +		//ToDo: This is windows specific code, we should replace HWND window with something more abstract +		GFX_API GfxDeviceWindow*	CreateGfxWindow( HWND window, int width, int height, DepthBufferFormat depthFormat, int antiAlias ) GFX_PURE; + +	#endif +	#endif + +	#if UNITY_WIN +		GFX_API int	GetCurrentTargetWidth() const { return 0; } +		GFX_API int	GetCurrentTargetHeight() const { return 0; } +		GFX_API void SetCurrentTargetSize(int /*width*/, int /*height*/) { } +		GFX_API void SetCurrentWindowSize(int /*width*/, int /*height*/) { } +	#endif + +	static void CommonReloadResources( UInt32 flags ); + +	#if GFX_SUPPORTS_OPENGL +	GFX_API void UnbindObjects () {} +	#endif + +	#if GFX_OPENGLESxx_ONLY || GFX_SUPPORTS_MOLEHILL +	GFX_API void ReloadResources() GFX_PURE; +	#endif + +	#if !GFX_DEVICE_VIRTUAL +	GfxDeviceImpl*	GetImpl() { return impl; } +	#endif + +#if GFX_DEVICE_VIRTUAL +	GFX_API RenderTextureFormat	GetDefaultRTFormat() const	{ return kRTFormatARGB32; } +#else +	GFX_API RenderTextureFormat	GetDefaultRTFormat() const; +#endif + +#if GFX_DEVICE_VIRTUAL +	GFX_API RenderTextureFormat GetDefaultHDRRTFormat() const	{ return kRTFormatARGBHalf; } +#else +	GFX_API RenderTextureFormat	GetDefaultHDRRTFormat() const; +#endif + +	GFX_API void* GetNativeGfxDevice() { return NULL; } +	GFX_API void* GetNativeTexturePointer(TextureID /*id*/) { return NULL; } +	GFX_API UInt32 GetNativeTextureID(TextureID id); +	GFX_API void InsertCustomMarker (int marker); + +	GFX_API ComputeBufferID CreateComputeBufferID(); +	GFX_API void FreeComputeBufferID(ComputeBufferID id); + +	GFX_API void SetComputeBufferData (ComputeBufferID /*bufferHandle*/, const void* /*data*/, size_t /*size*/) { } +	GFX_API void GetComputeBufferData (ComputeBufferID /*bufferHandle*/, void* /*dest*/, size_t /*destSize*/) { } +	GFX_API void CopyComputeBufferCount (ComputeBufferID /*srcBuffer*/, ComputeBufferID /*dstBuffer*/, UInt32 /*dstOffset*/) { } + +	GFX_API void SetRandomWriteTargetTexture (int /*index*/, TextureID /*tid*/) { } +	GFX_API void SetRandomWriteTargetBuffer (int /*index*/, ComputeBufferID /*bufferHandle*/) { } +	GFX_API void ClearRandomWriteTargets () { } + +	GFX_API ComputeProgramHandle CreateComputeProgram (const UInt8* /*code*/, size_t /*codeSize*/) { ComputeProgramHandle cp; return cp; } +	GFX_API void DestroyComputeProgram (ComputeProgramHandle& /*cpHandle*/) { } +	GFX_API void CreateComputeConstantBuffers (unsigned /*count*/, const UInt32* /*sizes*/, ConstantBufferHandle* /*outCBs*/) { } +	GFX_API void DestroyComputeConstantBuffers (unsigned /*count*/, ConstantBufferHandle* /*cbs*/) { } +	GFX_API void CreateComputeBuffer (ComputeBufferID /*id*/, size_t /*count*/, size_t /*stride*/, UInt32 /*flags*/) { } +	GFX_API void DestroyComputeBuffer (ComputeBufferID /*handle*/) { } +	GFX_API void UpdateComputeConstantBuffers (unsigned /*count*/, ConstantBufferHandle* /*cbs*/, UInt32 /*cbDirty*/, size_t /*dataSize*/, const UInt8* /*data*/, const UInt32* /*cbSizes*/, const UInt32* /*cbOffsets*/, const int* /*bindPoints*/) { } +	GFX_API void UpdateComputeResources ( +		unsigned /*texCount*/, const TextureID* /*textures*/, const int* /*texBindPoints*/, +		unsigned /*samplerCount*/, const unsigned* /*samplers*/, +		unsigned /*inBufferCount*/, const ComputeBufferID* /*inBuffers*/, const int* /*inBufferBindPoints*/, +		unsigned /*outBufferCount*/, const ComputeBufferID* /*outBuffers*/, const TextureID* /*outTextures*/, const UInt32* /*outBufferBindPoints*/) { } +	GFX_API void DispatchComputeProgram (ComputeProgramHandle /*cpHandle*/, unsigned /*threadsX*/, unsigned /*threadsY*/, unsigned /*threadsZ*/) { } + +	GFX_API void DrawNullGeometry (GfxPrimitiveType /*topology*/, int /*vertexCount*/, int /*instanceCount*/) { }; +	GFX_API void DrawNullGeometryIndirect (GfxPrimitiveType /*topology*/, ComputeBufferID /*bufferHandle*/, UInt32 /*bufferOffset*/) { }; +	DepthBufferFormat GetFramebufferDepthFormat() const { return m_FramebufferDepthFormat; } +	void SetFramebufferDepthFormat(DepthBufferFormat depthFormat) { m_FramebufferDepthFormat = depthFormat; } + +protected: +	void SetupVertexLightParams(int light, const GfxVertexLight& data); + +private: + +	#if !GFX_DEVICE_VIRTUAL +	GfxDeviceImpl*	impl; +	#endif + +protected: +	void OnCreate(); +	void OnDelete(); +	void OnCreateVBO(VBO* vbo); +	void OnDeleteVBO(VBO* vbo); + +	// Mutable state +	BuiltinShaderParamValues	m_BuiltinParamValues; +	GfxFogParams		m_FogParams; +	GfxDeviceStats		m_Stats; +	GfxDeviceStats		m_SavedStats; +	bool				m_InsideFrame; +	bool				m_IsRecording; +	bool				m_IsThreadable; +	RenderTexture*		m_ActiveRenderTexture; +	const BuiltinShaderParamIndices*	m_BuiltinParamIndices[kShaderTypeCount]; +	BuiltinShaderParamIndices	m_NullParamIndices; +	MaterialPropertyBlock	m_MaterialProperties; + +	// Immutable data +	GfxDeviceRenderer	m_Renderer; +	bool				m_UsesOpenGLTextureCoords; +	bool				m_UsesHalfTexelOffset; +	int					m_MaxBufferedFrames; +	DepthBufferFormat	m_FramebufferDepthFormat; + + +	RenderSurfaceHandle	m_BackBufferColor; +	RenderSurfaceHandle	m_BackBufferDepth; + + +private: + +	VBOList*			m_VBOList; +	static volatile int	ms_TextureIDGenerator; +	static volatile int	ms_ComputeBufferIDGenerator; + +	typedef std::map<TextureID, size_t> TextureIDToSizeMap; +	TextureIDToSizeMap m_TextureSizes; +}; + +class GfxThreadableDevice : public GfxDevice +{ +public: +	//! Called by the worker thread on thread startup +	GFX_API void	OnDeviceCreated (bool /*callingFromRenderThread*/) { } + +	//! IsCombineModeSupported() exists because we want CreateTextureCombiners() failure to happen +	//! on the main thread, not the render thread where we can't do anything about it. +	//! When it returns true then creating combiners *should* succeed +	GFX_API bool	IsCombineModeSupported( unsigned int combiner ) GFX_PURE; + +	GFX_API void	SetTextureCombinersThreadable( TextureCombinersHandle textureCombiners, const TexEnvData* texEnvData, const Vector4f* texColors ) GFX_PURE; +	GFX_API void	SetShadersMainThread (ShaderLab::SubProgram* programs[kShaderTypeCount], const ShaderLab::PropertySheet* props); +	GFX_API void	SetShadersThreadable (GpuProgram* programs[kShaderTypeCount], const GpuProgramParameters* params[kShaderTypeCount], UInt8 const * const paramsBuffer[kShaderTypeCount]) { }; + +	//! CreateShaderParameters() exists because the main thread needs to know which parameters a shader takes, and on +	//! GL-like platforms it can vary with different fog modes because we recompile shaders when the mode was changed. +	GFX_API void	CreateShaderParameters( ShaderLab::SubProgram* /*program*/, FogMode /*fogMode*/ ) { } +}; + +bool				IsGfxDevice(); +EXPORT_COREMODULE GfxDevice& GetGfxDevice(); +GfxDevice&			GetUncheckedGfxDevice(); +void				SetGfxDevice(GfxDevice* device); +void				DestroyGfxDevice(); + +GfxDevice&			GetRealGfxDevice(); +bool				IsRealGfxDeviceThreadOwner(); +#if ENABLE_MULTITHREADED_CODE +void				SetRealGfxDevice(GfxDevice* device); +void				SetRealGfxDeviceThreadOwnership(); +void				DestroyRealGfxDevice(); +void				SetGfxThreadingMode(GfxThreadingMode mode); +GfxThreadingMode	GetGfxThreadingMode(); +#endif + +class AutoGfxDeviceAcquireThreadOwnership +{ +public: +	AutoGfxDeviceAcquireThreadOwnership(); +	~AutoGfxDeviceAcquireThreadOwnership(); + +private: +	bool m_WasOwner; +}; + +class AutoGfxDeviceBeginEndFrame +{ +public: +	AutoGfxDeviceBeginEndFrame(); +	~AutoGfxDeviceBeginEndFrame(); + +	void End(); +	bool GetSuccess() const { return m_Success; } + +private: +	bool m_Success; +	bool m_NeedsEndFrame; +}; + +void CalculateDeviceProjectionMatrix (Matrix4x4f& m, bool usesOpenGLTextureCoords, bool invertY); + +inline AutoGfxDeviceAcquireThreadOwnership::AutoGfxDeviceAcquireThreadOwnership() +{ +	m_WasOwner = IsRealGfxDeviceThreadOwner(); +	if (!m_WasOwner) +		GetGfxDevice().AcquireThreadOwnership(); +} + +inline AutoGfxDeviceAcquireThreadOwnership::~AutoGfxDeviceAcquireThreadOwnership() +{ +	if (!m_WasOwner) +		GetGfxDevice().ReleaseThreadOwnership(); +} + +inline AutoGfxDeviceBeginEndFrame::AutoGfxDeviceBeginEndFrame() : +m_Success(true), m_NeedsEndFrame(false) +{ +	GfxDevice& device = GetGfxDevice(); +	if (!device.IsInsideFrame()) +	{ +		device.BeginFrame(); +		m_Success = device.IsValidState(); +		m_NeedsEndFrame = true; +	} +} + +inline AutoGfxDeviceBeginEndFrame::~AutoGfxDeviceBeginEndFrame() +{ +	End(); +} + +inline void AutoGfxDeviceBeginEndFrame::End() +{ +	if (m_NeedsEndFrame) +		GetGfxDevice().EndFrame(); +	m_NeedsEndFrame = false; +} + + +inline DepthBufferFormat DepthBufferFormatFromBits(int bits) +{ +	if( bits <= 0 ) +		return kDepthFormatNone; +	else if( bits <= 16 ) +		return kDepthFormat16; +	else +		return kDepthFormat24; +} + +#if UNITY_EDITOR +extern VertexComponent kSuitableVertexComponentForChannel[]; +#endif + + +class SetAndRestoreWireframeMode { +public: +	SetAndRestoreWireframeMode() { +		GfxDevice& device = GetGfxDevice(); +		m_SavedWireframe = device.GetWireframe(); +	} +	SetAndRestoreWireframeMode(bool wireframe) { +		GfxDevice& device = GetGfxDevice(); +		m_SavedWireframe = device.GetWireframe(); +		device.SetWireframe(wireframe); +	} +	~SetAndRestoreWireframeMode() { +		GfxDevice& device = GetGfxDevice(); +		device.SetWireframe(m_SavedWireframe); +	} +private: +	bool m_SavedWireframe; +}; + +void ApplyTexEnvData (unsigned int texUnit, unsigned int samplerUnit, const TexEnvData& data); + | 
