#include "Mix/Private/Graphics/DX11/TextureTargetL.h"
#include "Mix/Private/Graphics/DX11/Device.h"

namespace Mix{ namespace Graphics{ namespace DX11{

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Graphics::DX11::TextureTargetL
////////////////////////////////////////////////////////////////////////////////////////////////////

TextureTargetL* TextureTargetL::CreateInstance(	Mix::Graphics::DX11::Device* pDevice,
												UInt32 width, UInt32 height, Mix::Graphics::FORMAT format,
												ID3D11Texture2D* pTexture, ID3D11Texture2D* pReadingTexture, ID3D11RenderTargetView* pRTView, ID3D11ShaderResourceView* pSRView )
{
	return MIX_LIB_NEW_T( Mix::Memory::SECTION_GRAPHICS, TextureTargetL, pDevice, width, height, format, pTexture, pReadingTexture, pRTView, pSRView );
}

TextureTargetL::TextureTargetL(	Mix::Graphics::DX11::Device* pDevice,
								UInt32 width, UInt32 height, Mix::Graphics::FORMAT format,
								ID3D11Texture2D* pTexture, ID3D11Texture2D* pReadingTexture, ID3D11RenderTargetView* pRTView, ID3D11ShaderResourceView* pSRView ) :
DeviceObject( pDevice ),
m_pDevice( NULL ),
m_Width( width ),
m_Height( height ),
m_Format( format ),
m_pTexture( NULL ),
m_pReadingTexture( NULL ),
m_pRTView( NULL ),
m_pSRView( NULL )
{
	MIX_ASSERT( pDevice != NULL );
	MIX_ASSERT( pTexture != NULL );
	MIX_ASSERT( pReadingTexture != NULL );
	MIX_ASSERT( pRTView != NULL );
	MIX_ASSERT( pSRView != NULL );

	MIX_ADD_REF( pDevice );
	m_pDevice = pDevice;

	m_pTexture = pTexture;
	m_pReadingTexture = pReadingTexture;
	m_pRTView = pRTView;
	m_pSRView = pSRView;
}

TextureTargetL::~TextureTargetL( void )
{
	MIX_RELEASE( m_pSRView );
	MIX_RELEASE( m_pRTView );
	MIX_RELEASE( m_pReadingTexture );
	MIX_RELEASE( m_pTexture );
	MIX_RELEASE( m_pDevice );
}

ID3D11RenderTargetView* TextureTargetL::GetRTView( void )
{
	return m_pRTView;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Graphics::DX11::Texture
////////////////////////////////////////////////////////////////////////////////////////////////////

ID3D11Resource* TextureTargetL::GetInterface( void )
{
	return m_pTexture;
}

ID3D11ShaderResourceView* TextureTargetL::GetSRView( void )
{
	return m_pSRView;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Graphics::ITexture
////////////////////////////////////////////////////////////////////////////////////////////////////

Mix::Graphics::ITexture::DIMENSION_TYPE TextureTargetL::GetDimensionType( void ) const
{
	return ITexture::DIMENSION_PLANE;
}

Mix::Graphics::ITexture::BIND_TYPE TextureTargetL::GetBindType( void ) const
{
	return ITexture::BIND_TARGET;
}

UInt32 TextureTargetL::GetAccessFlags( void ) const
{
	return ITexture::ACCESS_CPU_READ | ITexture::ACCESS_GPU_WRITE;
}

UInt32 TextureTargetL::GetWidth( void ) const
{
	return m_Width;
}

UInt32 TextureTargetL::GetHeight( void ) const
{
	return m_Height;
}

Mix::Graphics::FORMAT TextureTargetL::GetFormat( void ) const
{
	return m_Format;
}

const wchar_t* TextureTargetL::GetFilePath( void ) const
{
	return Mix::STR_NULL;
}

Boolean TextureTargetL::Lock( Mix::Graphics::ITexture::LOCK& lock )
{
	D3D11_MAPPED_SUBRESOURCE mapped;
	HRESULT hRet;

	hRet = m_pDevice->CopyAndMap( m_pTexture, m_pReadingTexture, mapped );
	if( hRet != S_OK )
	{
		MIX_LOG_ERROR( L"ターゲットテクスチャのロックに失敗 : CopyAndMap %s : Result[%s]",
			Mix::STR_RETERROR, m_pDevice->GetD3DResultText( hRet ) );

		return False;
	}

	lock.pitch = mapped.RowPitch;
	lock.bits = mapped.pData;

	return True;
}

void TextureTargetL::Unlock( void )
{
	m_pDevice->Unmap( m_pReadingTexture );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Graphics::IDeviceObject
////////////////////////////////////////////////////////////////////////////////////////////////////

Mix::Graphics::IDeviceObject::TYPE TextureTargetL::GetType( void ) const
{
	return Mix::Graphics::IDeviceObject::TEXTURE;
}

}}}
