//
// Asura_PS3_FrameBuffer.h
//
// Created by KJFL - 06 December 2005
// Modified by Catalin Arsenescu - 27 March 2007
//
// Copyright (C) 2005 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif

#ifndef __ASURA_PS3_FRAMEBUFFER_H__
#define __ASURA_PS3_FRAMEBUFFER_H__

#include "Asura_PS3_Graphics.h"
#include "Asura_PS3_DeferredRendering.h"
class Asura_PS3_Texture;

enum ASURA_PS3_FRAMEBUFFER_FORMAT
{
	// RGBA as 16bit half-floats (64bit buffer)
	ASURA_PS3_FRAMEBUFFER_RGBA16F,
	// RGBA as 32bit floats (128bit buffer)
	ASURA_PS3_FRAMEBUFFER_RGBA32F,
	// Single 32bit float
	ASURA_PS3_FRAMEBUFFER_32F,
	ASURA_PS3_FRAMEBUFFER_RGBA
};

#define ASURA_RENDER_TARGET_CURRENT_FRONT_BUFFER 0

class Asura_PS3_FrameBuffer
{
	friend class Asura_PS3_DeferredRendering;

public:
	Asura_PS3_FrameBuffer( bool bWaitForIdleState, u_int uWidth, u_int uHeight, unsigned char ucNumberOfRenderTargets, enum ASURA_PS3_FRAMEBUFFER_FORMAT eFormat, bool bHasDepthBuffer, bool dUseDoubleBuffer, char* szName, char cDisplayID, bool bTiled = true, void** ppxDepthBuffer = NULL, bool bUseZCullMemory = false, u_int uAllocWidth = 0, u_int uAllocHeight = 0, CellGcmEnum eLocation = CELL_GCM_LOCATION_LOCAL );
	~Asura_PS3_FrameBuffer();

	void Bind( bool bSetViewport = true );
	void Flip( void );
#ifdef ASURA_ASSERT
	void AssertFlip( void );
#endif
	CellGcmSurface*	GetSurface( void );

	void BindAsSingleRT( bool bSetViewport = true ); //Bind Target 0 as single Render Target
	void BindAsZPassOnly( bool bSetViewport = true );
	void RestoreBind( void ); //Call this function if you need to restore the render target after a call to BindAsSingleRT
	bool IsBindAsSingleRT( void ) { return m_bIsInSingleRT; }

	void ResolveBackBuffer( Asura_PS3_Texture* pxResolveTexture, int iWidth = -1, int iHeight = -1 );
	void ResolveBackBufferNonBlock( Asura_PS3_Texture* pxResolveTexture, int iWidth = -1, int iHeight = -1 );
	void ResolveToRenderTarget( Asura_PS3_FrameBuffer* pxFrameBuffer );
	void ResolveToTexture( Asura_PS3_Texture* pxResolveTexture, bool bUseGammaCorrection = false );
	void ResolveToCubemapTexture( Asura_PS3_Texture* pxResolveTexture, int iFace ); // 0 = +x; 1 = -x; 2 = +y; 3 = -y; 4 = +z; 5 = -z;

	Asura_PS3_Texture*	GetRTAsTexture( u_int uRenderTarget ); // Get a render target as a texture
																// If you call this function with 0 as parameter and is double buffering frame buffer the current rendering frame buffer is returned.
	Asura_PS3_Texture*	GetZBufferAsTexture( void );

	u_int	CalcColourPitch( u_int uWidth, u_int uBytesPerPixel );

private:

	void*						m_apxBufferAddress[ 5 ]; // maximum 4 RT and one Depth Buffer
	void*						m_apxWasteBufferAddress[ 5 ];
	unsigned char				m_ucNumberOfRenderTargets;
	unsigned char				m_ucCurrentSurface;
	char						m_cDisplayID;
	bool						m_bHasDepthBuffer;
	bool						m_bIsInSingleRT;
	bool						m_bDoubleBuffer;
	enum ASURA_PS3_FRAMEBUFFER_FORMAT m_eFormat;
	CellGcmEnum					m_eLocation;

	CellGcmSurface				m_xRenderSurface[ 2 ]; // front and back buffer
	CellGcmSurface				m_axSingleRT[ 3 ];	//front buffer (0), back buffer (1), z buffer (2)

	Asura_PS3_Texture*			m_pxTextures[ 5 ];// maximum 4 render targets + one depth buffer
};

#endif//__ASURA_PS3_FRAMEBUFFER_H__
